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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
#! /usr/bin/env python
print "OpenCV Python version of lkdemo"
import sys
# import the necessary things for OpenCV
from opencv import cv
from opencv import highgui
#############################################################################
# some "constants"
win_size = 10
MAX_COUNT = 500
#############################################################################
# some "global" variables
image = None
pt = None
add_remove_pt = False
flags = 0
night_mode = False
need_to_init = False
# the default parameters
quality = 0.01
min_distance = 10
#############################################################################
# the mouse callback
# the callback on the trackbar
def on_mouse (event, x, y, flags, param):
# we will use the global pt and add_remove_pt
global pt
global add_remove_pt
if image is None:
# not initialized, so skip
return
if event == highgui.CV_EVENT_LBUTTONDOWN:
# user has click, so memorize it
pt = cv.cvPoint (x, y)
add_remove_pt = True
#############################################################################
# so, here is the main part of the program
if __name__ == '__main__':
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)
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)
# display a small howto use it
print "Hot keys: \n" \
"\tESC - quit the program\n" \
"\tr - auto-initialize tracking\n" \
"\tc - delete all the points\n" \
"\tn - switch the \"night\" mode on/off\n" \
"To add/remove a feature point click it\n"
# first, create the necessary windows
highgui.cvNamedWindow ('LkDemo', highgui.CV_WINDOW_AUTOSIZE)
# register the mouse callback
highgui.cvSetMouseCallback ('LkDemo', on_mouse, None)
while 1:
# do forever
# 1. capture the current image
frame = highgui.cvQueryFrame (capture)
if frame is None:
# no image captured... end the processing
break
if image is None:
# create the images we need
image = cv.cvCreateImage (cv.cvGetSize (frame), 8, 3)
grey = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
prev_grey = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
pyramid = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
prev_pyramid = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
eig = cv.cvCreateImage (cv.cvGetSize (frame), cv.IPL_DEPTH_32F, 1)
temp = cv.cvCreateImage (cv.cvGetSize (frame), cv.IPL_DEPTH_32F, 1)
points = [[], []]
# copy the frame, so we can draw on it
cv.cvCopy (frame, image)
# create a grey version of the image
cv.cvCvtColor (image, grey, cv.CV_BGR2GRAY)
if night_mode:
# night mode: only display the points
cv.cvSetZero (image)
if need_to_init:
# we want to search all the good points
# create the wanted images
# search the good points
points [1] = cv.cvGoodFeaturesToTrack (
grey, eig, temp,
MAX_COUNT,
quality, min_distance, None, 3, 0, 0.04)
# refine the corner locations
cv.cvFindCornerSubPix (
grey,
points [1],
cv.cvSize (win_size, win_size), cv.cvSize (-1, -1),
cv.cvTermCriteria (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS,
20, 0.03))
elif len (points [0]) > 0:
# we have points, so display them
# calculate the optical flow
[points [1], status], something = cv.cvCalcOpticalFlowPyrLK (
prev_grey, grey, prev_pyramid, pyramid,
points [0], len (points [0]),
(win_size, win_size), 3,
len (points [0]),
None,
cv.cvTermCriteria (cv.CV_TERMCRIT_ITER|cv.CV_TERMCRIT_EPS,
20, 0.03),
flags)
# initializations
point_counter = -1
new_points = []
for the_point in points [1]:
# go trough all the points
# increment the counter
point_counter += 1
if add_remove_pt:
# we have a point to add, so see if it is close to
# another one. If yes, don't use it
dx = pt.x - the_point.x
dy = pt.y - the_point.y
if dx * dx + dy * dy <= 25:
# too close
add_remove_pt = 0
continue
if not status [point_counter]:
# we will disable this point
continue
# this point is a correct point
new_points.append (the_point)
# draw the current point
cv.cvCircle (image,
cv.cvPointFrom32f(the_point),
3, cv.cvScalar (0, 255, 0, 0),
-1, 8, 0)
# set back the points we keep
points [1] = new_points
if add_remove_pt:
# we want to add a point
points [1].append (cv.cvPointTo32f (pt))
# refine the corner locations
points [1][-1] = cv.cvFindCornerSubPix (
grey,
[points [1][-1]],
cv.cvSize (win_size, win_size), cv.cvSize (-1, -1),
cv.cvTermCriteria (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS,
20, 0.03))[0]
# we are no more in "add_remove_pt" mode
add_remove_pt = False
# swapping
prev_grey, grey = grey, prev_grey
prev_pyramid, pyramid = pyramid, prev_pyramid
points [0], points [1] = points [1], points [0]
need_to_init = False
# we can now display the image
highgui.cvShowImage ('LkDemo', image)
# handle events
c = highgui.cvWaitKey (10)
if c == '\x1b':
# user has press the ESC key, so exit
break
# processing depending on the character
if c in ['r', 'R']:
need_to_init = True
elif c in ['c', 'C']:
points = [[], []]
elif c in ['n', 'N']:
night_mode = not night_mode
|