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.

112 Comments

Add yours

  1. Thank you for posting it online. I find it useful.

  2. You're welcome! I'm glad you found it useful.

  3. Really-really helpful! Thank you so much for sharing this code

  4. hi. i have this
    Null pointer (Invalid classifier cascade)
    in function cvHaarDetectObjects,
    C:UserVPoperncvcvsrccvhaar.cpp(890)

  5. Are you sure you have the cascade file in the same directory?

  6. C:DevOpenCVdatahaarcascades

  7. I currently don't have a Linux machine for testing, but IIRC the line

    cascade = cv.LoadHaarClassifierCascade('haarcascade_frontalface_alt.xml', cv.Size(1,1))

    requires the cascade file to be in the same directory as the script.

    By the way, the script I presented in this blog post won't work on Windows. You should use the simple_winclient.py script for that (which can be found in the tarball available from my website).

  8. thank you very much Jo

  9. hi. i have this
    Null pointer (Invalid classifier cascade)
    in function cvHaarDetectObjects,
    C:UserVPoperncvcvsrccvhaar.cpp(890)

  10. Are you sure you have the cascade file in the same directory?

  11. C:DevOpenCVdatahaarcascades

  12. I currently don't have a Linux machine for testing, but IIRC the line

    cascade = cv.LoadHaarClassifierCascade('haarcascade_frontalface_alt.xml', cv.Size(1,1))

    requires the cascade file to be in the same directory as the script.

    By the way, the script I presented in this blog post won't work on Windows. You should use the simple_winclient.py script for that (which can be found in the tarball available from my website).

  13. thank you very much Jo

  14. Hey great post. I can't wait to get started hacking it to my needs. I made a script that tracts an IR LED and maps the mouse to the movements(http://hackaday.com/2010/02/25/python-ir-tracking-for-the-handicapped/).

    I used VideoCapture(http://videocapture.sourceforge.net/) for the webcam interface though. I'm going to try and map the mouse movements to this new face-recognition.

  15. After about a week of work, I couldn't get opencv to work. I used VideoCapture again, and fdlib.dll to detect the faces. http://www.kyb.mpg.de/bs/people/kienzle/facedem

  16. Me and my friend want to set up a funny type call of duty video type thing, but to do so we would need to. BlackStar69

  17. Me and my friend want to set up a funny type call of duty video type thing, but to do so we would need to. BlackStar69

  18. Hey,

    I just found your amazing code on the web. I'm trying to make a eye tracking device for a paralized girl. I tryed your code but got this error.
    Can you help me with this problem. I really don't know what to do.

    Traceback (most recent call last):
    File “D:My DocumentsMijn documentenTWGanotherdetection.py”, line 65, in <module>
    detect(frame)
    File “D:My DocumentsMijn documentenTWGanotherdetection.py”, line 22, in detect
    faces = cv.HaarDetectObjects(grayscale, cascade, storage, 1.2, 2, cv.HAAR_DO_CANNY_PRUNING, cv.Size(50, 50))
    WindowsError: exception: access violation reading 0x00000028

    Thx,

    Stefan (from the Netherlands)

  19. Hey,
    I found the solution already. Needed to put the
    'haarcascade_frontalface_default.xml' file in the same directory as your little programm. When I runned the code, it seems to work fine. I only noticed that the program is often detecting my chin and mouth.. and not the whole face. Is this because I'm to close to my cam or is there a other solution for.

    Thx,

    Stefan

    ps: I also needed to put “from opencv.highgui import *” above the code. Did yours work without?

  20. OpenCV has reasonably robust Python interface created with SWIG. This makes it easy to integrate with existing libraries like Pygame and olpcgames. As an example, OpenCV can be combined with Pygame to make a simple face tracking xeyes clone.
    Thanks.

  21. dont work for me

    from CVtypes import cv
    ImportError: No module named CVtypes

  22. i read this and detection is one component of … It is a simple python script that will connect to your webcam

  23. “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. ”

    This reminded me of this
    “If you have a problem – if no one else can help – and if you can find
    them – maybe you can hire: The A-Team.”

    I almost want somebody to geekerise the lyrics and make them about ctypes now.

  24. wow thats some crazy code

  25. I got lost half way through your code

  26. Mark S. is definitely on the right track. If you want to get a professional looking email address, Id recommend buying your name domain name, like or
    Gucci sweaters
    If its common it might be difficult to get, however, be creative and you can usually find something.

  27. Golden. Great, useful info.

  28. rickdouglas85

    August 2, 2010 — 01:00

    Absolutely incredible – technology is certainly an amazing thing!


    Rick, MJ Researcher

  29. Nice! I've got some motion detection going on over here if you're interested: http://appdelegateinc.com/blog/2010/08/02/motio

    Did you buy the book? I find the OpenCV documentation is very hard to follow.

  30. Muito obrigado pelos elogios…de coração.
    Se depender de mim, estarei sempre compartlhando minha paixão, que são os games!!
    Quanto a fase da aranha realmente eh dificil, mas é ali onde vc realmente fica “ninja” nas suas habilidades , e ai o resto do game fica muito mais atenuado, hehe como se fosse uma academia essa fase, rs.
    Abração amigo
    online jogos

  31. qual versao opencv se ta usand0?

  32. whtas opencv version?

  33. IIRC, I was still using version 1.0 or 1.1 back then.

  34. Some v4l2 incompatibility, get it working with exporting that :
    export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so

    https://bugs.launchpad.net/ubuntu/+source/opencv/+bug/321358

  35. cv.DestroyWindow(“camera”) should solve the problem with exiting the program.

  36. The young man who has not wept is a savage, and the old man who will not laugh is a fool
    Supra TK Society Women
    ed hardy dresses

  37. Youth is like spring, an overpraised season.
    Supra Skytop For Womens Sale
    Supra Skytop Black

  38. Hello,everyone,Attention please! If you’re looking for a new Tattoo T-shirt, check out the Don Ed Hardy from Street Fashion.

  39. THANK YOU! IT IS A GREAT HELP.

  40. Thank you so much. Since the formatting is lost, I created a gist for others to make it easy to copy. https://gist.github.com/1269098

Leave a Reply

Your email address will not be published. Required fields are marked *