| |
|
Seeing With OpenCV, Part 2: Finding Faces in Images
|
|
by Robin Hewitt
|
|
This article originally appeared in
SERVO Magazine, February 2007.
Reprinted by permission of T & L Publications, Inc.
|
| |
Last month's article
in this series
introduced OpenCV, Intel's free, open-source computer vision library for C/C++ programmers. It covered the basics - downloading and installing OpenCV, reading and writing image files, capturing video, and working with the IplImage data structure.
This month, I'll show you how to use OpenCV to detect faces. I'll explain how the face-detection algorithm works, and give you tips for getting the most out of it.
Background and Preliminaries
OpenCV uses a type of face detector called a Haar Cascade classifier. The
sidebar,
"How Face Detection Works"
explains what this mouthful means.
Figure 1
shows an example of OpenCV's face detector in action.
Given an image, which can come from a file or from live video, the face detector examines each image location and classifies it as "Face" or "Not Face." Classification assumes a fixed scale for the face, say 50x50 pixels. Since faces in an image might be smaller or larger than this, the classifier runs over the image several times, to search for faces across a range of scales. This may seem an enormous amount of processing, but thanks to algorithmic tricks, explained in the sidebar, classification is very fast, even when it's applied at several scales.
|
|
|
|
|
Figure 1. Face detection with OpenCV, using default parameters. The input image is lena.jpg, in the samples/c directory
|
|
The classifier uses data stored in an XML file to decide how to classify each image location. The OpenCV download includes four flavors of XML data for frontal face detection, and one for profile faces. It also includes three non-face XML files - one for full body (pedestrian) detection, one for upper body, and one for lower body.
You'll need to tell the classifier where to find the data file you want it to use. The one I'll be using is called haarcascade_frontalface_default.xml.
In OpenCV version 1.0, it's located at
[OPENCV_ROOT]/data/haarcascades/haarcascade_frontalface_default.xml
where [OPENCV_ROOT] is the path to your OpenCV installation. For example, if you're on Windows XP, and you selected the default installation location, you'd use
[OPENCV_ROOT] = "C:/Program Files/OpenCV"
(If you're working with an older, 16-bit version of Windows, you'd use '\' as the directory separator, instead of '/'.)
It's a good idea to locate the XML file you want to use, and make sure your path to it is correct, before you code the rest of your face-detection program.
You'll also need an image to process. The image lena.jpg is a good one to test with. It's located in the OpenCV samples/c directory. If you copy it to your program's working directory, you'll easily be able to compare your program's output with the output from the code in
Figure 2.
Implementing Face Detection, Step by Step
Figure 2
shows the source code to load an image from file, detect faces in it, and display the image with detected faces outlined in green.
Figure 1
shows the display produced by this program when it's run from the command line, using DetectFacesFigure lena.jpg
|
|
Figure 2. Source code to detect faces in one image. Usage: DetectFaces <image file>
|
 |
|
(Click here to get as text.)
|
|
Initializing the detector
The variable CvHaarClassifierCascade * pCascade (Line 2) holds the data from the XML file you located earlier. To load the XML data into pCascade, you can use the cvLoad() function, as in Lines 11-13. cvLoad() is a general-purpose function for loading data from files. It takes up to three input parameters. For this example, you'll only need the first parameter. This is the path to an XML file containing a valid Haar Cascade. Here, I've loaded the default frontal face detector included with OpenCV. If you're coding in C, set the remaining parameters to 0. If you're coding in C++, you can simply omit the unused parameters from your function call.
Before detecting faces in images, you'll also need to instantiate a CvMemStorage object (pStorage, declared at Line 3). This is a memory buffer that expands automatically, as needed. The face detector will put the list of detected faces into this buffer. Since the buffer is expandable, you won't need to worry about overflowing it. All you'll have to do is create it (Line 10), then release it when you're finished (Line 54).
You'll often need to load data from files with OpenCV. Since it's easy to get a path wrong, it's a good idea to insert a quick check to make sure everything loaded and initialized properly. Lines 16-24 do a simple error check, print a diagnostic message, and exit if initialization fails.
Running the detector
Lines 27-32 in
Figure 2
call cvHaarDetectObjects() to run the face detector. This function takes up to seven parameters. The first three are the image pointer, XML data, and memory buffer. The remaining four parameters are set to their C++ defaults. These last four parameters are described below, in the section, "Parameters and Tuning."
Viewing the results
A quick way to check if your program works is to display the results in an OpenCV window. You can create a display window using the cvNamedWindow() function, as in Line 35. The first parameter is a string, with a window name. The second, CV_WINDOW_AUTOSIZE, is a flag that tells the window to automatically resize itself to fit the image you give it to display.
To pass an image for display, call cvShowImage() with the name you previously assigned the window, and the image you want it to display. The cvWaitKey() call at Line 48 pauses the application until you close the window. If the window fails to close by clicking its close icon, click inside the window's display area, then press a keyboard key. Also, make sure your program calls cvDestroyWindow() (Line 49) to close the window.
Face detections are stored as a list of CvRect struct pointers. Lines 38-44 access each detection rectangle and add its outline to the pInpImg variable, which holds the in-memory image loaded from file.
Releasing resources
Lines 52-54 release the resources used by the input image, the XML data, and the storage buffer. If you'll be detecting faces in multiple images, you don't need to release the XML data or the buffer until after you're done detecting faces.
|