Creating With Code

A blog by Robert (Marty) McGuire

Face Detection in Static Images with Python

February 20th, 2009 · 26 Comments

One of the things I’ve been longing to do with my mobile photo-sharing site Camura is to offer image annotations, like objects and faces.  Over the last couple of years I have been increasingly frustrated by the appearance of face tagging on services like Facebook, and the recent addition of face recognition to iPhoto has brought this frustration to the surface once again.  I don’t even want to do something as complex as face recognition – I just want to find faces in an image.

Googling for things like “open source face detector” doesn’t come up with much.  The landscape seems to be comprised of mostly expensive for-pay libraries written for Windows, abandoned research projects, and lots of research papers full of equations — but no code that I could get to run.

To make a long post short, it turns out that Intel’s OpenCV computer vision library comes with a face detector example that should work out of the box.  Better yet, there are now some decent Python bindings for OpenCV that come pre-packaged with OpenCV for Ubuntu and Debian.  You can install them with:

$ sudo apt-get install python-opencv

Now, it seems that most OpenCV face detector examples are meant to be run “live”, usually taking the image from a webcam and highlighting faces with a red box in real-time.  However, I have a large database of static images that I want to consider individually, and I simply want to save the face coordinates for later use, rather than altering the picture.

So, with a bit more Googling, I found a Python script that I could chop up and use for this purpose, and here is what I came up with:

An example run of the script looks something like this:

$ python face_detect.py marty_mcguire.jpg
[(50,36) -> (115,101)]

You can overlay that rectangle on an output image with ImageMagick’s “convert”:

$ convert marty_mcguire.jpg -stroke red -fill none -draw "rectangle 50,36 115,101" output.jpg

And the output might look something like this:

My face, it has been detected.

Pretty fun stuff!

Tags: · · · · · ·

  • http://henriklindgren.se Henrik

    Thx, was looking for this!

  • Dom

    Thanks for this example!

    FYI, /usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml is contained in libcv-dev so you actually need to install that too for the code to run

    i.e.,

    $ sudo apt-get install python-opencv libcv-dev

  • Dom

    p.s. tested and working with the ISO standard CV http://en.wikipedia.org/wiki/Lenna test image :-)

  • Anony M.

    Thank you very much indeed, sir.

  • http://www.ryanhaigh.net ryanhaigh

    Thanks for this information it was very useful to me. I did however have a problem when using this in a larger program and I thought others might find it useful. It seems that “if faces:” will still be true even if no faces are found in the image. Using “if faces.total > 0:” worked perfectly.

    Thanks Again,
    ryanhaigh

  • marius

    Hi, I get an error when running this script:

    $ ./face_detect.py lena.jpg
    terminate called after throwing an instance of ‘int’
    Aborted
    $ _

    The same happens when running this from the python shell. When copy-pasting single lines, the error appears at “faces = cvHaarDetectObjects(…)”. The shell is also killed. I don’t even have a guess on where to start looking here. Any ideas on what goes wrong?

  • http://creatingwithcode.com/ Robert McGuire

    Marius – have you tried ryanhaigh’s suggestion of changing the “if faces:” line to “if faces.total > 0:”?

  • Alexander F.

    Hi! Anyone an idea how this works on windows? i get the “ImportError: No module named opencv.cv” Error using python 26 and opencv 2.1. copying the files from “C:\OpenCV2.1\Python2.6\Lib\site-packages” to “C:\Python26\Lib\site-packages” as said everywhere on the internet doesn’t seem to work. best regards, alex

  • Guenter Bachelier

    I have just installed OpenCV 2.1 on Ubuntu with
    http://gijs.pythonic.nl/blog/2010/apr/7/opencv-21-ubuntu-packages/
    and tried this code but I get a
    ImportError: No module named opencv.cv

  • http://- Alexander F

    Hi! I have the thingy running on windows but maybe this can help you:
    • Add /bin to your PATH environment variable
    • Create an environment variable PYTHONPATH and set it to /Python2.6/Lib/site-packages

    adapt it to your versions/directories/operating systems needs.

  • Pingback: facesaver.py locks your screen when you forget « wilkox

  • John

    Nice stuff! Exactly what I wanted. Thanks.

  • Rob G. Healey

    This is an awesome piece of code and work! I am running Fedora Rawhide/ 15, and this runs perfectly!

    Thank you so much for creating this code, and example to use…

  • wasuaje

    Hi there, great code, but i can’t find /usr/share/opencv/haarcascades/haarcascade_frontal/face_default.xml on ubuntu 10.10 can you help me?

  • wasuaje

    Sorry found the solution myself here

    https://bugs.launchpad.net/opencv/+bug/698016

  • wasuaje

    Hello there, i prefer to do the image changes (draw the rectangles) right in python so i paste my code all python based:

    #!/usr/bin/python

    # face_detect.py

    # Face Detection using OpenCV. Based on sample code from:
    # http://python.pastebin.com/m76db1d6b

    # Usage: python face_detect.py

    import sys, os
    from opencv.cv import *
    from opencv.highgui import *
    import Image, ImageDraw

    def detectObjects(image):
    “”"Converts an image to grayscale and prints the locations of any
    faces found”"”
    grayscale = cvCreateImage(cvSize(image.width, image.height), 8, 1)
    cvCvtColor(image, grayscale, CV_BGR2GRAY)

    storage = cvCreateMemStorage(0)
    cvClearMemStorage(storage)
    cvEqualizeHist(grayscale, grayscale)
    cascade = cvLoadHaarClassifierCascade(‘/usr/share/doc/opencv-doc/examples/haarcascades/haarcascades/haarcascade_frontalface_alt.xml’,cvSize(1,1))
    faces = cvHaarDetectObjects(grayscale, cascade, storage, 1.2, 2,CV_HAAR_DO_CANNY_PRUNING, cvSize(50,50))

    if faces.total > 0:
    for f in faces:
    x1,y1,x2,y2=f.x,f.y,f.x+f.width,f.y+f.height
    print(“[(%d,%d) -> (%d,%d)]” % (x1,y1,x2,y2))
    print_rectangle(x1,y1,x2,y2) #call to a python pil

    def print_rectangle(x1,y1,x2,y2): #function to modify the img
    im = Image.open(sys.argv[1])
    draw = ImageDraw.Draw(im)
    draw.rectangle([x1,y1,x2,y2])
    im.save(sys.argv[1])

    def main():
    image = cvLoadImage(sys.argv[1]);
    detectObjects(image)

    if __name__ == “__main__”:
    main()

  • marius

    Hi Robert, very late reply… :) I was just playing with stuff again and found the exact same website as last year.

    I’m using Ubuntu 10.10 with everything installed from repository. Still get the same error, even with ryanhaigh’s change. The script never gets to that line, so that doesn’t surprise me.

    Cheers!

  • AnandOka

    Hi Marius,
    you need to make sure that in:
    cascade = cvLoadHaarClassifierCascade(
    ‘path/to/haarcascade_frontalface_default.xml’,
    cvSize(1,1))
    the path of the file is correct. Otherwise the returned value is a None which causes the abort.

    In my ubuntu 11.04, the file is in
    /usr/share/doc/opencv-doc/examples/haarcascades/haarcascades/haarcascade_frontalface_default.xml.gz
    I just copied it to my working directory and extracted it there.
    The code worked after that.

  • Pingback: Face detection with Python « Python Adventures

  • matias

    I’ve started this project about an year ago and uploaded to github when didn’t had time to work on it, I guess it might be interesting to somebody.

    It’s python, of course, and uses opencv too.

    https://github.com/omab/faces

  • Leigh

    1. install
    # apt-get install python-opencv libcv-dev opencv-doc

    2. extract
    # cd /usr/share/doc/opencv-doc/examples/haarcascades/haarcascades/
    # cp *.gz ..
    # gunzip *.gz

    3. Run (this changes your images and renames the old ones)

    #!/usr/bin/python

    # face_detect.py

    # Face Detection using OpenCV. Based on sample code from:
    # http://python.pastebin.com/m76db1d6b

    # Usage: python face_detect.py

    import sys,os
    from opencv.cv import *
    from opencv.highgui import *

    CLASSIFIER=’/usr/share/doc/opencv-doc/examples/haarcascades/haarcascade_frontalface_default.xml’

    def detectObjects(fn, image):
    “”"Converts an image to grayscale and prints the locations of any
    faces found”"”
    grayscale = cvCreateImage(cvSize(image.width, image.height), 8, 1)
    cvCvtColor(image, grayscale, CV_BGR2GRAY)

    storage = cvCreateMemStorage(0)
    cvClearMemStorage(storage)
    cvEqualizeHist(grayscale, grayscale)
    cascade = cvLoadHaarClassifierCascade(CLASSIFIER, cvSize(1,1))
    faces = cvHaarDetectObjects(grayscale, cascade, storage, 1.2, 2,
    CV_HAAR_DO_CANNY_PRUNING, cvSize(50,50))

    if faces:
    for f in faces:
    newfn = fn + “.output.jpg”
    os.system(“convert %s -stroke red -fill none -draw ‘rectangle %d,%d %d,%d’ %s” % (fn, f.x, f.y, f.x+f.width, f.y+f.height, newfn))
    os.system(“mv %s %s.orig” % (fn, fn))
    os.system(“mv %s %s” % (newfn, fn))

    def main():
    image = cvLoadImage(sys.argv[1]);
    detectObjects(sys.argv[1], image)

    if __name__ == “__main__”:
    main()

  • http://globaloptima.co.uk Toby Skinner

    If you are using Python(X,Y) with Open CV 2 then you’ll need to make a few tweaks. I couldn’t find the Haar classifier data in the standard install so I needed to download OpenCV, extract it and the data folder can be found in there (no need to actually build or install OpenCV).

    My version that works, I’m not a Python dev so I’m sure there are optimisations etc:

    import sys, os
    import cv2.cv as cv

    image = cv.LoadImage(sys.argv[1])

    grayscale = cv.CreateImage((image.width, image.height), 8, 1)
    cv.CvtColor(image, grayscale, cv.CV_BGR2GRAY)

    storage = cv.CreateMemStorage(0)
    cv.EqualizeHist(grayscale, grayscale)
    cascade = cv.Load(”)
    faces = cv.HaarDetectObjects(grayscale, cascade, storage, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING, (50,50))

    if faces:
    for f in faces:
    print(f)

    Note I’m not sure where the ClearMemStorage function has gone and whether del does the same thing or not, someone better at Python might be able to help.

    Also the data structures returned are slightly different, each ‘face’ is a tuple containing a rect and an int.

    Hope that helps someone.

  • Pingback: discontents - the real face of white australia

  • Pingback: A Walk with Love and Data « Quædam cuiusdam

  • emijrp

    I downloaded this file and replaced the path to this file in the code http://tutorial-haartraining.googlecode.com/svn/trunk/data/haarcascades/haarcascade_frontalface_default.xml Also, I installed opencv-doc. I voila, it works.

  • 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