File: cam-histo.py

package info (click to toggle)
opencv 2.1.0-3%2Bsqueeze1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 68,800 kB
  • ctags: 52,010
  • sloc: cpp: 554,793; xml: 475,942; ansic: 153,396; python: 18,622; sh: 428; makefile: 111
file content (193 lines) | stat: -rwxr-xr-x 6,128 bytes parent folder | download
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