Fun with Python, OpenCV and face detection

I had some fun with Gary Bishop’s OpenCV Python wrapper this morning. I wanted to try out OpenCV for detecting faces using a web cam. This could be used for instance to see if someone is sitting behind his desk or not. I used Gary’s Python wrapper since I didn’t want to code in C++.

I didn’t know where to start, so I searched for existing OpenCV face detection examples. I found a blog post by Nirav Patel explaining how to use OpenCV’s official Python bindings to perform face detection. Nirav will be working on a webcam module for Pygame for the Google Summer of Code.

I managed to rewrite Nirav’s example to get it working with CVtypes:

Here’s the code. Although it’s just a quick and dirty hack, it might be useful to others. It requires CVtypes and OpenCV, and was tested on Ubuntu Hardy with a Logitech QuickCam Communicate Deluxe webcam. You will need Nirav’s Haar cascade file as well.

import sys
from CVtypes import cv
 
def detect(image):
    image_size = cv.GetSize(image)
 
    # create grayscale version
    grayscale = cv.CreateImage(image_size, 8, 1)
    cv.CvtColor(image, grayscale, cv.BGR2GRAY)
 
    # create storage
    storage = cv.CreateMemStorage(0)
    cv.ClearMemStorage(storage)
 
    # equalize histogram
    cv.EqualizeHist(grayscale, grayscale)
 
    # detect objects
    cascade = cv.LoadHaarClassifierCascade('haarcascade_frontalface_alt.xml', cv.Size(1,1))
    faces = cv.HaarDetectObjects(grayscale, cascade, storage, 1.2, 2, cv.HAAR_DO_CANNY_PRUNING, cv.Size(50, 50))
 
    if faces:
        print 'face detected!'
        for i in faces:
            cv.Rectangle(image, cv.Point( int(i.x), int(i.y)),
                         cv.Point(int(i.x + i.width), int(i.y + i.height)),
                         cv.RGB(0, 255, 0), 3, 8, 0)
 
if __name__ == "__main__":
    print "OpenCV version: %s (%d, %d, %d)" % (cv.VERSION,
                                               cv.MAJOR_VERSION,
                                               cv.MINOR_VERSION,
                                               cv.SUBMINOR_VERSION)
 
    print "Press ESC to exit ..."
 
    # create windows
    cv.NamedWindow('Camera', cv.WINDOW_AUTOSIZE)
 
    # create capture device
    device = 0 # assume we want first device
    capture = cv.CreateCameraCapture(0)
    cv.SetCaptureProperty(capture, cv.CAP_PROP_FRAME_WIDTH, 640)
    cv.SetCaptureProperty(capture, cv.CAP_PROP_FRAME_HEIGHT, 480)    
 
    # check if capture device is OK
    if not capture:
        print "Error opening capture device"
        sys.exit(1)
 
    while 1:
        # do forever
 
        # capture the current frame
        frame = cv.QueryFrame(capture)
        if frame is None:
            break
 
        # mirror
        cv.Flip(frame, None, 1)
 
        # face detection
        detect(frame)
 
        # display webcam image
        cv.ShowImage('Camera', frame)
 
        # handle events
        k = cv.WaitKey(10)
 
        if k == 0x1b: # ESC
            print 'ESC pressed. Exiting ...'
            break

A known problem is that pressing the escape key doesn’t quit the program. Might be something wrong in my use of the cv.WaitKey function. Meanwhile you can just use Ctrl+C. All in all, the face detection works pretty well. It doesn’t recognize multiple faces yet, but that might be due to the training data. It would be interesting to experiment with OpenCV’s support for eye tracking in the future.

Update: the script does recognize multiple faces in a frame. Yesterday when Alex stood at my desk, it recognized his face as well. I think it didn’t work before because I used cv.Size(100, 100) for the last parameter of cv.HaarDetectObjects instead of cv.Size(50, 50). This parameter indicates the minimum face size (in pixels). When people were standing around my desk, they were usually farther away from the camera. Their face was then probably smaller than 100×100 pixels.

Just a quick note on ctypes. I remember when I created PydgetRFID that I tried to use libphidgets’ SWIG-generated Python bindings, but couldn’t get them to work properly. I had read about ctypes, and decided to use it for creating my own wrapper around libphidgets. Within a few hours I had a working prototype. When you’re struggling with SWIG-generated Python bindings, or have some C library without bindings that you would like to use, give ctypes a try. Gary Bishop wrote about a couple of interesting ctypes tricks to make the process easier.

  • Pingback: Web cam + Face Detection + Real Time Notification = DIY Home Security | James Lin's Blog

  • http://www.facebook.com/people/Mithil-Bhoras/100003504931361 Mithil Bhoras

    tried the code from this
    blog. In the second line it’s given: “from CVtypes import cv”. I even
    downloaded CVtypes and pasted it in the same folder where the program
    is. Even when I type “from CVtypes import cv” in interpreter mode, it’s giving the same error. There is one thing about the “Wrappers” that I don’t seem to follow. Here is the error: “>>> from CVtypes import cv Traceback (most recent call last): File “”, line 1, in File “CVtypes.py”, line 38, in _cxDLL = cdll.LoadLibrary(‘libcxcore.so.1′) File “/usr/lib/python2.7/ctypes/__init__.py”, line 431, in LoadLibrary return self._dlltype(name) File “/usr/lib/python2.7/ctypes/__init__.py”, line 353, in __init__ self._handle = _dlopen(self._name, mode) OSError: libcxcore.so.1: cannot open shared object file: No such file or directory” Can’t make anything out of it even when I tried to…

  • http://blog.jozilla.net/ Jo Vermeulen

    That piece of code tries to load the OpenCV 1.0 library. This might not work with newer versions of OpenCV. 

  • ARK

    Hi, I have started a new blog on new opencv python module, cv2. This module is quite fast compared to old. visit : http://www.opencvpython.blogspot.com

  • Pingback: Getting Started with Opencv + Python + Face Recognition | ESSELS BVBA

  • http://www.facebook.com/reidel.martinraul Reidel Martin-Raul

    Hello i was wondering if you could help me out a bit with a problem… i would like to make a facial recognition software for my laptop and i dont really now were to start from please it would mean a lot to me u could send me a message on raolboss@yahoo.com

  • margarita

    how I do to take a snapshot with python and opencv?

  • Amol

    How to use it in C#

  • shrikant

    i need depth mapping code in python opencv………please help

  • Pingback: Python, opencv instalace a testování na ubuntu | blog

  • rajat saxena

    the cv.waitKey() function has a bug, to make it correct change it to cv.waitKey() % 0xFF

  • Kala Swaminathan

    from CVtypes import cv

    ImportError: No module named CVtypes

    pls help me..