194 lines
6.0 KiB
Python
194 lines
6.0 KiB
Python
|
#! /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
|