-
Notifications
You must be signed in to change notification settings - Fork 0
/
laser_tracker.py
executable file
·204 lines (171 loc) · 6.76 KB
/
laser_tracker.py
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
194
195
196
197
198
199
200
201
202
203
#! /usr/bin/env python
##
## This program is a quick attempt to track the dot from a red laser pointer.
## Right now, the code performs steps 1-5 below, and shows the results in several windows.
##
## General Idea:
## 1. Grab the video frame.
## 2. Convert it to HSV
## 3. Split the frame into individual components (separate images for H, S, and V)
## 4. Apply a threshold to each compenent (hopefully keeping just the dot from the laser)
## 5. AND the 3 images (which "should" cut down on false positives)
## TODO:
## 6. Identify the "best" location for the identified laser. ie: x,y coordinates in the image.
## 7. Do something interesting with it...
## (draw a circle around it, control the mouse cursor, build a game, etc).
##
## Author: Brad Montgomery (www.bradmontgomery.net)
## Date: 2008-01-23
#############################################################################
import sys
from opencv import cv
from opencv import highgui
#############################################################################
# definition of some constants
cam_width = 320
cam_height = 240
#############################################################################
def averageWhitePoints(frame):
xtotal = 0.0
ytotal = 0.0
count = 0.0;
for x in range(cam_width):
for y in range(cam_height):
if(cv.cvGetReal2D(frame, y, x) > 200):
xtotal = xtotal + x
ytotal = ytotal + y
count += 1
#if(xtotal < 0):
# xtotal = 0
#if(xtotal >= cam_width):
# xtotal = cam_width-1
#if(ytotal < 0):
# ytotal = 0
#if(ytotal >= cam_height):
# ytotal = cam_height-1
if(count > 0):
return int(xtotal/count), int(ytotal/count)
return 0, 0
def create_and_position_window(name, xpos, ypos):
''' a function to created a named widow (from name),
and place it on the screen at (xpos, ypos) '''
highgui.cvNamedWindow(name, highgui.CV_WINDOW_AUTOSIZE) # create the window
highgui.cvResizeWindow(name, cam_width, cam_height) # resize it
highgui.cvMoveWindow(name, xpos, ypos) # move it to (xpos,ypos) on the screen
def setup_camera_capture(device_num=0):
''' perform camera setup for the device number (default device = 0) i
return a reference to the camera Capture
'''
try:
# try to get the device number from the command line
device = int(device_num)
except (IndexError, ValueError):
# no device number on the command line, assume we want the 1st device
device = 0
print 'Using Camera device %d'%device
# 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, cam_width)
highgui.cvSetCaptureProperty (capture,highgui.CV_CAP_PROP_FRAME_HEIGHT, cam_height)
# check that capture device is OK
if not capture:
print "Error opening capture device"
sys.exit (1)
return capture
# so, here is the main part of the program
def main():
# HSV color space Threshold values for a RED laser pointer
# hue
hmin = 5
hmax = 100 # hmax = 180
# saturation
smin = 50
smax = 100
# value
vmin = 200
vmax = 256
print "OpenCV version: %s (%d, %d, %d)" % (cv.CV_VERSION,
cv.CV_MAJOR_VERSION,
cv.CV_MINOR_VERSION,
cv.CV_SUBMINOR_VERSION)
# create windows
create_and_position_window('Thresholded_HSV_Image', 10, 10)
create_and_position_window('RGB_VideoFrame', 10+cam_width, 10)
create_and_position_window('Hue', 10, 10+cam_height)
create_and_position_window('Saturation', 210, 10+cam_height)
create_and_position_window('Value', 410, 10+cam_height)
create_and_position_window('LaserPointer', 0,0)
capture = setup_camera_capture()
# create images for the different channels
h_img = cv.cvCreateImage (cv.cvSize (cam_width,cam_height), 8, 1)
s_img = cv.cvCreateImage (cv.cvSize (cam_width,cam_height), 8, 1)
v_img = cv.cvCreateImage (cv.cvSize (cam_width,cam_height), 8, 1)
laser_img = cv.cvCreateImage (cv.cvSize (cam_width,cam_height), 8, 1)
cv.cvSetZero(h_img)
cv.cvSetZero(s_img)
cv.cvSetZero(v_img)
cv.cvSetZero(laser_img)
while True:
# 1. capture the current image
frame = highgui.cvQueryFrame (capture)
if frame is None:
# no image captured... end the processing
break
hsv_image = cv.cvCloneImage(frame) # temporary copy of the frame
cv.cvCvtColor(frame, hsv_image, cv.CV_BGR2HSV) # convert to HSV
# split the video frame into color channels
cv.cvSplit(hsv_image, h_img, s_img, v_img, None)
# Threshold ranges of HSV components.
cv.cvInRangeS(h_img, hmin, hmax, h_img)
cv.cvInRangeS(s_img, smin, smax, s_img)
cv.cvInRangeS(v_img, vmin, vmax, v_img)
# Perform an AND on HSV components to identify the laser!
cv.cvAnd(h_img, v_img, laser_img)
# This actually Worked OK for me without using Saturation.
#cv.cvAnd(laser_img, s_img,laser_img)
# Merge the HSV components back together.
cv.cvMerge(h_img, s_img, v_img, None, hsv_image)
xavg, yavg = averageWhitePoints(v_img)
print "(", xavg, ",", yavg, ")"
#-----------------------------------------------------
# NOTE: default color space in OpenCV is BGR!!
# we can now display the images
highgui.cvShowImage ('Thresholded_HSV_Image', hsv_image)
highgui.cvShowImage ('RGB_VideoFrame', frame)
highgui.cvShowImage ('Hue', h_img)
highgui.cvShowImage ('Saturation', s_img)
highgui.cvShowImage ('Value', v_img)
highgui.cvShowImage('LaserPointer', laser_img)
# handle events
k = highgui.cvWaitKey (10)
if k == '\x1b' or k == 'q':
# user has press the ESC key, so exit
print "hmin = ", hmin, " hmax = ", hmax, " vmin = ", vmin, " vmax = ", vmax
sys.exit()
if k == 'a':
hmin = hmin-1
if hmin < 0:
hmin = 0
if k == 's':
hmin = (hmin+1)
if k == 'd':
hmax = hmax-1
if hmax < 0:
hmax = 0
if k == 'f':
hmax = (hmax+1)
if k == 'z':
vmin = vmin-1
if vmin < 0:
vmin = 0
if k == 'x':
vmin = (vmin+1)
if k == 'c':
vmax = vmax-1
if vmax < 0:
vmax = 0
if k == 'v':
vmax = (vmax+1)
if __name__ == '__main__':
main()