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:
Pretty fun stuff!

24 responses so far ↓
1 Henrik // Mar 23, 2009 at 1:46 pm
Thx, was looking for this!
2 Dom // May 5, 2009 at 7:21 am
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
3 Dom // May 5, 2009 at 7:24 am
p.s. tested and working with the ISO standard CV http://en.wikipedia.org/wiki/Lenna test image
4 Anony M. // May 18, 2009 at 7:09 pm
Thank you very much indeed, sir.
5 ryanhaigh // Aug 22, 2009 at 5:30 am
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
6 marius // Jan 21, 2010 at 10:01 am
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?
7 Robert McGuire // Jan 21, 2010 at 1:21 pm
Marius – have you tried ryanhaigh’s suggestion of changing the “if faces:” line to “if faces.total > 0:”?
8 Alexander F. // Apr 27, 2010 at 12:49 am
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
9 Guenter Bachelier // May 16, 2010 at 12:32 pm
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
10 Alexander F // Jun 2, 2010 at 5:12 am
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.
11 facesaver.py locks your screen when you forget « wilkox // Aug 31, 2010 at 3:44 am
[...] to be added to the list. A large part of the code is stolen directly from Marty McGuire’s face_detect.py. This is the first thing I’ve ever written in python so feel free to suggest improvements. [...]
12 John // Dec 30, 2010 at 3:17 pm
Nice stuff! Exactly what I wanted. Thanks.
13 Rob G. Healey // Jan 5, 2011 at 10:28 pm
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…
14 wasuaje // Mar 15, 2011 at 4:07 pm
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?
15 wasuaje // Mar 15, 2011 at 4:19 pm
Sorry found the solution myself here
https://bugs.launchpad.net/opencv/+bug/698016
16 wasuaje // Mar 15, 2011 at 4:36 pm
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()
17 marius // Apr 3, 2011 at 8:41 am
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!
18 AnandOka // May 9, 2011 at 10:47 pm
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.
19 Face detection with Python « Python Adventures // May 10, 2011 at 11:35 pm
[...] I found an interesting post: Face Detection in Static Images with Python. You give an image as input and the program draws a rectangle around the face(s) on the [...]
20 matias // May 11, 2011 at 10:51 am
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
21 Leigh // May 11, 2011 at 1:06 pm
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()
22 Toby Skinner // Sep 12, 2011 at 8:42 am
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.
23 discontents - the real face of white australia // Sep 20, 2011 at 10:42 am
[...] didn’t take long to find a python script that used the OpenCV library to detect faces in photographs. I tried the script on a few of the NAA [...]
24 A Walk with Love and Data « Quædam cuiusdam // Oct 26, 2011 at 11:23 pm
[...] on their travel. The documents include photographs; Sherratt’s inspiration was to use open-source facial recognition software to crop the faces out of the scanned documents and present them as a waterfall, with more faces [...]
Leave a Comment