├── README └── track.py /README: -------------------------------------------------------------------------------- 1 | This is a simple motion tracker application written in python. It uses OpenCV . If you are running on a Mac, you might want to reference this guide: http://sunny.in.th/2010/04/27/installing-opencv-21-on-snow-leopard.html. -------------------------------------------------------------------------------- /track.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Derived from http://sundararajana.blogspot.com/2007/05/motion-detection-using-opencv.html 4 | 5 | import cv 6 | 7 | class Target: 8 | def __init__(self): 9 | self.capture = cv.CaptureFromCAM(0) 10 | cv.NamedWindow("Target", 1) 11 | 12 | def run(self): 13 | # Capture first frame to get size 14 | frame = cv.QueryFrame(self.capture) 15 | frame_size = cv.GetSize(frame) 16 | grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1) 17 | moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3) 18 | difference = None 19 | 20 | while True: 21 | # Capture frame from webcam 22 | color_image = cv.QueryFrame(self.capture) 23 | 24 | # Smooth to get rid of false positives 25 | cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0) 26 | 27 | if not difference: 28 | # Initialize 29 | difference = cv.CloneImage(color_image) 30 | temp = cv.CloneImage(color_image) 31 | cv.ConvertScale(color_image, moving_average, 1.0, 0.0) 32 | else: 33 | cv.RunningAvg(color_image, moving_average, 0.020, None) 34 | 35 | # Convert the scale of the moving average. 36 | cv.ConvertScale(moving_average, temp, 1.0, 0.0) 37 | 38 | # Minus the current frame from the moving average. 39 | cv.AbsDiff(color_image, temp, difference) 40 | 41 | # Convert the image to grayscale. 42 | cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY) 43 | 44 | # Convert the image to black and white. 45 | cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY) 46 | 47 | # Dilate and erode to get object blobs 48 | cv.Dilate(grey_image, grey_image, None, 18) 49 | cv.Erode(grey_image, grey_image, None, 10) 50 | 51 | # Calculate movements 52 | storage = cv.CreateMemStorage(0) 53 | contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) 54 | points = [] 55 | 56 | while contour: 57 | # Draw rectangles 58 | bound_rect = cv.BoundingRect(list(contour)) 59 | contour = contour.h_next() 60 | 61 | pt1 = (bound_rect[0], bound_rect[1]) 62 | pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) 63 | points.append(pt1) 64 | points.append(pt2) 65 | cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1) 66 | 67 | num_points = len(points) 68 | if num_points: 69 | # Draw bullseye in midpoint of all movements 70 | x = y = 0 71 | for point in points: 72 | x += point[0] 73 | y += point[1] 74 | x /= num_points 75 | y /= num_points 76 | center_point = (x, y) 77 | cv.Circle(color_image, center_point, 40, cv.CV_RGB(255, 255, 255), 1) 78 | cv.Circle(color_image, center_point, 30, cv.CV_RGB(255, 100, 0), 1) 79 | cv.Circle(color_image, center_point, 20, cv.CV_RGB(255, 255, 255), 1) 80 | cv.Circle(color_image, center_point, 10, cv.CV_RGB(255, 100, 0), 5) 81 | 82 | # Display frame to user 83 | cv.ShowImage("Target", color_image) 84 | 85 | # Listen for ESC or ENTER key 86 | c = cv.WaitKey(7) % 0x100 87 | if c == 27 or c == 10: 88 | break 89 | 90 | if __name__=="__main__": 91 | t = Target() 92 | t.run() 93 | --------------------------------------------------------------------------------