Wednesday, February 10, 2010

A face full of celebration

As I mentioned earlier, I was able to get an openCV based python script that pulls images from a webcam and locates faces. Some of you may be wondering why I'd want to track faces? Well, I could make my rig constantly point a laser pointer at some one's face, but realistically speaking, this is merely an exercise in image processing with openCV.

Before I go any further, here's an example of a tracked face:

(Yes, this was actually identified as a face)

And here's the code to go with it:
#!/usr/bin/python

import sys, os, pygame
from pygame.locals import *
from opencv.cv import *
from opencv.highgui import *
from opencv.adaptors import Ipl2PIL #need python-numeric

fps = 30.0
pygame.init()
window = pygame.display.set_mode((640,480))
pygame.display.set_caption("Face track Demo")
screen = pygame.display.get_surface()
camera = cvCreateCameraCapture(0)

def get_image():
im = cvQueryFrame(camera)
#return Ipl2PIL(im)
return im

def detectFace(image):
grayscale = cvCreateImage(cvSize(640, 480), 8, 1)
cvCvtColor(image, grayscale, CV_BGR2GRAY)
storage = cvCreateMemStorage(0)
cvClearMemStorage(storage)
cvEqualizeHist(grayscale, grayscale)
cascade = cvLoadHaarClassifierCascade('haarcascade_frontalface_alt.xml', cvSize(1,1))
faces = cvHaarDetectObjects(grayscale, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(100,100))

if faces:
for i in faces:
cvRectangle(image, cvPoint( int(i.x), int(i.y)), cvPoint(int(i.x+i.width), int(i.y+i.height)), CV_RGB(0,255,0), 3, 8, 0)

def displayObject(image):
cvShowImage("face", image)
cvWaitKey()

def main(im):
events = pygame.event.get()
for event in events:
if event.type == KEYDOWN:
if event.key == K_q:
sys.exit(0)

if event.key == K_p:
cvSaveImage("face.jpg", im)
print "Snapshot saved"

im = get_image()
pygame.display.flip()
pygame.time.delay(int(1000 * 1.0/fps))

detectFace(im)
temp = Ipl2PIL(im)
screen.blit(pygame.image.frombuffer(temp.tostring(), temp.size, temp.mode), (0,0))
return im

if __name__ == "__main__":
im = get_image()
while(True):
im = main(im)
Sources:

I drew a lot of the code from both sources, but I wrote my own little GUI in pygame (hard, I know).

I did encounter a number of issues along the way, most prominently a lack of Windows compatibility. While the python bindings are available on Windows, some of the methods would simply not work and cause the python interpreter to crash. This only became an issue because I have to use Windows 7 for school and it was a little difficult to play around with this program during class because many classes require the use of Windows only software.

The next step is to try and coerce openCV into recognize other objects besides faces. Also, translating a recognized object in a picture to movement of the pan-tilt rig could prove difficult. Luckily, I already have a few ideas on how I can accomplish this.

Friday, February 5, 2010

Hardware issues and the beginning of vision processing

It's been a while since my last post, but I've made a fair amount of progress. I was testing the pan-tilt rig when I started to run into some issues with it. The power supply I was using could only supply a maximum of .5 amps and the two servos together were drawing substantially more then that. This was causing the voltage to dip and the servo motors to start acting sporadically. Luckily, a guy I work with was kind enough to give me an old computer power supply, which can provide more than enough current to power the two servos. Unfortunately, using the PSU limits me to running the servos at 12 volts, which isn't ideal because it will wear the servos out, but the servos are cheap and it's what I've got.

During my time troubleshooting the servos, I took the two of them apart to see if anything overt was wrong. Much to my dismay, I discovered that the servo controlling the tilt action is actually missing about 2 teeth on one of the gears. While the servo still works, there is a certain area in its rotation where it sputters and skips. I'm still going to use it, but the laser pointer won't be nearly as precise now.

I should be making another post soonish as I've made some headway with object tracking using python and openCV. More on that to come in the near future.