2010-01-11

Python webcam fun - motion detection

 
 

Sent to you by l5g via Google Reader:

 
 


http://gumuz.looze.net/wordpress/index.php/archives/2005/06/06/python-webcam-fun-motion-detection/

Python webcam fun - motion detection

I own a webcam, but I'm not the video-chat-type-of-guy(honestly!). So this 5 Euro Logitech webcam was just collecting dust in a box of don't-throw-away-just-yet-stuff. When one of my friends IM'ed me with his webcam hooked up, I decided to plug mine in as well. All fun and games, but the driver software also contained software to create all kinds of animations, like time-lapse and stop-motion. It also provided a way of detecting motion and acting on it by either taking a few snapshots or recording a few seconds to an avi file.

This made me wonder how motion is actually detected, from a programmers point of view. If you ask yourself these questions you only need 2 tools: google and Python :) . I found out how to grab a webcam shot, detect motion and even using this technique to create an Playstation EyeToy-like user interface.

Accessing the camera

A good first step would be connecting to your camera and access the images it receives. Fortunately there is a Python VideoCapture module available. Unfortunately it's only available for Windows. I'm ignoring this fact, because I am working on a Windows box. There probably is a Linux equivalent out there, keep looking ;) .

Connecting to your camera and grabbing a frame with this module is as easy as:

PYTHON:
  1. from VideoCapture import Device
  2.  
  3. # get webcam device
  4. cam = Device()
  5.  
  6. # get image
  7. img = cam.getImage()

The nice thing is, that this image object is a PIL Image instance. PIL also happens to be useful, when trying to detect motion. What a coincidence!

Detecting motion

How do you detect motion? You have to realise that we are trying to detect motion and not track motion. This makes our lives much easier and us a step closer to our goal. As I'm not an expert in this field I tried the simplest thing that could possibly work(why not?) and it worked!

First you take 2 snapshots, which you want to compare in order to detect possible movement. You iterate through every pixel location and compare the pixels from image A to image B. Every pixel has 3 values: Red, Green and Blue(RGB!). They all have a value ranging from 0 to 255. Every pixel's R,G and B values are summed and compared to the sum of the values from the second image. If the pixels differs over a certain threshold, it's counted. If the number of different pixels exceed yet another threshold, motion is detected.

The following function compares 2 PIL Image instances, looking for motion:

PYTHON:
  1. def diff_image(img1, img2, pix_threshold=50, img_threshold=10):
  2.     """ Compare 2 images to detect possible motion """
  3.     if not img1 or not img2: return False
  4.     img1 = img1.getdata()
  5.     img2 = img2.getdata()
  6.     pixel_count = len(img1)
  7.     pixdiff = 0
  8.     for i in range(pixel_count):
  9.         if abs(sum(img1[i]) - sum(img2[i])) > pix_htreshold:
  10.             pixdiff += 1
  11.             diffperc = pixdiff / (pixel_count/100.0)
  12.             if diffperc > img_threshold:
  13.                 # motion detected
  14.                 return True

The getdata() function returns a list of R,G,B tuples. I think line 9 clearly shows the summing and comparing of the pixel values.

I've written a little script putting this into practise. Taking snap shots at a regular interval and saving the images to files when motion is detected. The interval is lowered on detection to avoid having lot's of images of the same motion.

Requires: VideoCapture, PIL
Source: webcam_motion.py source.

Even more fun

The Sony playstation 2 has this webcam game concept called EyeToy. You can hook up a playstation webcam, interact with the system and play games by making movements in front of the camera. It's great fun with a bunch of friends.

I figured this ought to work with motion detection as well, so I wanted to try it out. First thing was to do was showing the real-time video from the camera to the user. I quickly turned to the Pygame Python module. This module could quickly render the the frames on screen.

I wanted to show 2 outlined squares on the screen. one top left and 1 top right. My goal was to color fill the squares when movement was detected within the square. It worked like a charm. If you are not familiar with the EyeToy it may be a bit difficult to imagine the effect, but I hope the following screenshots will clarify it a bit.

The program in idle mode showing the 2 squares outlined:

Idle

If i now move my hand in the air, producing movement in the left square, you can see it light up:

Left square filled

And yes, the right button also works:

Right square filled

Now, connecting these detections to actual actions I leave as an exercise to you: the reader who read till the end of this post.

Requires: VideoCapture, PIL, PyGame
Source: webcam_eyetoy.py source.

This entry was posted on Monday, June 6th, 2005 at 11:57 pm and is filed under python, programming. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

 


 
 

Things you can do from here:

 
 

No comments:

Post a Comment