Motion detection using a webcam, Python, OpenCV and Differential Images
This tutotial will show how simple it is to implement motion detection using Differential Images. As an example we capture the input of a webcam and visualize the motions in it. I recorded a short video of what we want to achieve:
Windows (bad webcam): Click here.
Linux (better webcam): Click here.
You need Python 2.7 and OpenCV 2.3 or higher. And of course you need a webcam. 🙂
You can download precompiled OpenCV-bindings for windows here.
Capturing and showing webcam-input
First we want to capture the webcam stream. This is pretty simple as OpenCV offers this feature already:
import cv2 cam = cv2.VideoCapture(0) s, img = cam.read() winName = "Movement Indicator" cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE) while s: cv2.imshow( winName,img ) s, img = cam.read() key = cv2.waitKey(10)<br> if key == 27:<br> cv2.destroyWindow(winName) break print "Goodbye"
This script will create a window showing your actual webcam input. You can close the window using "ESCAPE". What we do in detail is binding the first capturing device to a VideoCapture-Object and read it image by image with cam.read(). With imshow() we show the previously read image in the Window we created using namedWindow(). waitKey() waits 10ms for a user-input. If the pressed key is "ESCAPE" we destroy the window and break the while-loop.
Differential Images are the result of the subtraction of two images:
So as you can see a differential image shows the difference between two images. With those images you can make movement visible.
In our script we use a differential image calculated from three consecutive images , and . The advantage of this is that the uninteresting background is removed from the result:
OpenCV offers the possibility to subtract two images from each other using absdiff(). Also logical operations on two images is already implemented. We use the method bitwise_and() to achieve the final differential image. In python it looks like this:
def diffImg(t0, t1, t2): d1 = cv2.absdiff(t2, t1) d2 = cv2.absdiff(t1, t0) return cv2.bitwise_and(d1, d2)<br><br>
The last thing we have to do is bringing the differential image function into our previous script. Before the loop starts we read the first three images t_minus, t and t_plus and convert them into greyscale images as we dont need color information. With those images it is possible to start calculating differential images. After showing the differential image, we just have to get rid of the oldest image and read the next one. The final script looks like this:
import cv2 def diffImg(t0, t1, t2): d1 = cv2.absdiff(t2, t1) d2 = cv2.absdiff(t1, t0) return cv2.bitwise_and(d1, d2) cam = cv2.VideoCapture(0) winName = "Movement Indicator" cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE) # Read three images first: t_minus = cv2.cvtColor(cam.read(), cv2.COLOR_RGB2GRAY) t = cv2.cvtColor(cam.read(), cv2.COLOR_RGB2GRAY) t_plus = cv2.cvtColor(cam.read(), cv2.COLOR_RGB2GRAY) while True: cv2.imshow( winName, diffImg(t_minus, t, t_plus) ) # Read next image t_minus = t t = t_plus t_plus = cv2.cvtColor(cam.read(), cv2.COLOR_RGB2GRAY) key = cv2.waitKey(10) if key == 27: cv2.destroyWindow(winName) break print "Goodbye"
Thats it. It is a simple tutorial, but with the knowledge about differential images and how to read webcam streams, you can have pretty much fun (e.g. you can write simple tracking-algorithms now 🙂 ).
Download the result here: