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.

2 comments: