Update to 2.0.0 tree from current Fremantle build
[opencv] / samples / swig_python / cam-histo.py
1 #! /usr/bin/env python
2
3 import sys
4
5 # import the necessary things for OpenCV
6 from opencv import cv
7 from opencv import highgui
8
9 #############################################################################
10 # definition of some constants
11
12 # how many bins we want for the histogram, and their ranges
13 hdims = 16
14 hranges = [[0, 180]]
15
16 # ranges for the limitation of the histogram
17 vmin = 10
18 vmax = 256
19 smin = 30
20
21 # the range we want to monitor
22 hsv_min = cv.cvScalar (0, smin, vmin, 0)
23 hsv_max = cv.cvScalar (180, 256, vmax, 0)
24
25 #############################################################################
26 # some useful functions
27
28 def hsv2rgb (hue):
29     # convert the hue value to the corresponding rgb value
30
31     sector_data = [[0, 2, 1],
32                    [1, 2, 0],
33                    [1, 0, 2],
34                    [2, 0, 1],
35                    [2, 1, 0],
36                    [0, 1, 2]]
37     hue *= 0.1 / 3
38     sector = cv.cvFloor (hue)
39     p = cv.cvRound (255 * (hue - sector))
40     if sector & 1:
41         p ^= 255
42
43     rgb = {}
44     rgb [sector_data [sector][0]] = 255
45     rgb [sector_data [sector][1]] = 0
46     rgb [sector_data [sector][2]] = p
47
48     return cv.cvScalar (rgb [2], rgb [1], rgb [0], 0)
49
50 #############################################################################
51 # so, here is the main part of the program
52
53 if __name__ == '__main__':
54
55     # a small welcome
56     print "OpenCV Python wrapper test"
57     print "OpenCV version: %s (%d, %d, %d)" % (cv.CV_VERSION,
58                                                cv.CV_MAJOR_VERSION,
59                                                cv.CV_MINOR_VERSION,
60                                                cv.CV_SUBMINOR_VERSION)
61
62     # first, create the necessary windows
63     highgui.cvNamedWindow ('Camera', highgui.CV_WINDOW_AUTOSIZE)
64     highgui.cvNamedWindow ('Histogram', highgui.CV_WINDOW_AUTOSIZE)
65
66     # move the new window to a better place
67     highgui.cvMoveWindow ('Camera', 10, 40)
68     highgui.cvMoveWindow ('Histogram', 10, 270)
69
70     try:
71         # try to get the device number from the command line
72         device = int (sys.argv [1])
73
74         # got it ! so remove it from the arguments
75         del sys.argv [1]
76     except (IndexError, ValueError):
77         # no device number on the command line, assume we want the 1st device
78         device = 0
79
80     if len (sys.argv) == 1:
81         # no argument on the command line, try to use the camera
82         capture = highgui.cvCreateCameraCapture (device)
83
84         # set the wanted image size from the camera
85         highgui.cvSetCaptureProperty (capture,
86                                       highgui.CV_CAP_PROP_FRAME_WIDTH, 320)
87         highgui.cvSetCaptureProperty (capture,
88                                       highgui.CV_CAP_PROP_FRAME_HEIGHT, 240)
89     else:
90         # we have an argument on the command line,
91         # we can assume this is a file name, so open it
92         capture = highgui.cvCreateFileCapture (sys.argv [1])            
93
94     # check that capture device is OK
95     if not capture:
96         print "Error opening capture device"
97         sys.exit (1)
98         
99     # create an image to put in the histogram
100     histimg = cv.cvCreateImage (cv.cvSize (320,240), 8, 3)
101
102     # init the image of the histogram to black
103     cv.cvSetZero (histimg)
104
105     # capture the 1st frame to get some propertie on it
106     frame = highgui.cvQueryFrame (capture)
107
108     # get some properties of the frame
109     frame_size = cv.cvGetSize (frame)
110
111     # compute which selection of the frame we want to monitor
112     selection = cv.cvRect (0, 0, frame.width, frame.height)
113
114     # create some images usefull later
115     hue = cv.cvCreateImage (frame_size, 8, 1)
116     mask = cv.cvCreateImage (frame_size, 8, 1)
117     hsv = cv.cvCreateImage (frame_size, 8, 3 )
118
119     # create the histogram
120     hist = cv.cvCreateHist ([hdims], cv.CV_HIST_ARRAY, hranges, 1)
121
122     while 1:
123         # do forever
124
125         # 1. capture the current image
126         frame = highgui.cvQueryFrame (capture)
127         if frame is None:
128             # no image captured... end the processing
129             break
130
131         # mirror the captured image
132         cv.cvFlip (frame, None, 1)
133
134         # compute the hsv version of the image 
135         cv.cvCvtColor (frame, hsv, cv.CV_BGR2HSV)
136
137         # compute which pixels are in the wanted range
138         cv.cvInRangeS (hsv, hsv_min, hsv_max, mask)
139
140         # extract the hue from the hsv array
141         cv.cvSplit (hsv, hue, None, None, None)
142
143         # select the rectangle of interest in the hue/mask arrays
144         hue_roi = cv.cvGetSubRect (hue, selection)
145         mask_roi = cv.cvGetSubRect (mask, selection)
146
147         # it's time to compute the histogram
148         cv.cvCalcHist (hue_roi, hist, 0, mask_roi)
149
150         # extract the min and max value of the histogram
151         min_val, max_val, min_idx, max_idx = cv.cvGetMinMaxHistValue (hist)
152
153         # compute the scale factor
154         if max_val > 0:
155             scale = 255. / max_val
156         else:
157             scale = 0.
158
159         # scale the histograms
160         cv.cvConvertScale (hist.bins, hist.bins, scale, 0)
161
162         # clear the histogram image
163         cv.cvSetZero (histimg)
164
165         # compute the width for each bin do display
166         bin_w = histimg.width / hdims
167         
168         for  i in range (hdims):
169             # for all the bins
170
171             # get the value, and scale to the size of the hist image
172             val = cv.cvRound (cv.cvGetReal1D (hist.bins, i)
173                               * histimg.height / 255)
174
175             # compute the color
176             color = hsv2rgb (i * 180. / hdims)
177
178             # draw the rectangle in the wanted color
179             cv.cvRectangle (histimg,
180                             cv.cvPoint (i * bin_w, histimg.height),
181                             cv.cvPoint ((i + 1) * bin_w, histimg.height - val),
182                             color, -1, 8, 0)
183
184         # we can now display the images
185         highgui.cvShowImage ('Camera', frame)
186         highgui.cvShowImage ('Histogram', histimg)
187
188         # handle events
189         k = highgui.cvWaitKey (10)
190
191         if k == '\x1b':
192             # user has press the ESC key, so exit
193             break