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