| |
|
Seeing With OpenCV, Part 2: Finding Faces in Images
(Continued)
|
|
|
|
This article originally appeared in
SERVO Magazine, February 2007.
Reprinted by permission of T & L Publications, Inc.
|
| |
Parameters and Tuning
There are several parameters you can adjust to tune the face detector for your application.
Minimum Detection Scale
The seventh parameter in the call to cvHaarDetectObjects() is the size of the smallest face to search for. In C, you can select the default for this by setting the scale to 0x0, as in
Figure 2,
Line 32. (In C++, simply omit this parameter to use the default.) But what is the default? You can find out by opening the XML file you'll be using.
Look for the <size> tag. In the default frontal face detector, it's
<size> 24 24 </size>.
So, for this cascade, the default minimum scale is 24x24.
Depending on the resolution you're using, this default size may be a very small portion of your overall image. A face image this small may not be meaningful or useful, and detecting it takes up CPU cycles you could use for other purposes. For these reasons, and also to minimize the number of face detections your own code needs to process, it's best to set the minimum detection scale only as small as you truly need.
To set the minimum scale higher than the default value, set this parameter to the size you want. A good rule of thumb is to use some fraction of your input image's width or height as the minimum scale - for example, 1/4 of the image width. If you specify a minimum scale other than the default, be sure its aspect ratio (the ratio of width to height) is the same as the default's. In this case, aspect ratio is 1:1.
Minimum Neighbors Threshold
One of the things that happens "behind the scenes" when you call the face detector is that each positive face region actually generates many hits from the Haar detector.
Figure 3
shows OpenCV's internal rectangle list for the example image, lena.jpg. The face region itself generates the largest cluster of rectangles. These largely overlap. In addition, there's one small detection to the (viewer's) left, and two larger detections slightly above and left of the main face cluster.
Usually, isolated detections are false detections, so it makes sense to discard these. It also makes sense to somehow merge the multiple detections for each face region into a single detection. OpenCV does both these before returning its list of detected faces. The merge step first groups rectangles that contain a large amount of overlap, then finds the average rectangle for the group. It then replaces all rectangles in the group with the average rectangle.
Between isolated rectangles and large groupings, are smaller groupings that may be faces, or may be false detections. The minimum-neighbors threshold sets the cutoff level for discarding or keeping rectangle groups based on how many raw detections are in the group. The C++ default for this parameter is three, which means to merge groups of three or more and discard groups with fewer rectangles. If you find that your face detector is missing a lot of faces, you might try lowering this threshold to two or one.
If you set it to 0, OpenCV will return the complete list of raw detections from the Haar classifier. While you're tuning your face detector, it's helpful to do this just to see what's going on inside OpenCV. Viewing the raw detections will improve your intuition about the effects of changing other parameters, which will help you tune them.
|
|
Figure 3. OpenCV's internal detection rectangles. To see these, use min_neighbors = 0
|
Scale Increase Rate
The fourth input parameter to cvHaarDetectObjects() specifies how quickly OpenCV should increase the scale for face detections with each pass it makes over an image. Setting this higher makes the detector run faster (by running fewer passes), but if it's too high, you may jump too quickly between scales and miss faces. The default in OpenCV is 1.1, in other words, scale increases by a factor of 1.1 (10%) each pass.
Canny Pruning Flag
The sixth parameter to cvHaarDetectObjects() is a flag variable. There are currently only two options: 0 or CV_HAAR_DO_CANNY_PRUNING. If the Canny Pruning option is selected, the detector skips image regions that are unlikely to contain a face, reducing computational overhead and possibly eliminating some false detections. The regions to skip are identified by running an edge detector (the Canny edge detector) over the image before running the face detector.
Again, the choice of whether or not to set this flag is a tradeoff choice between speed and detecting more faces. Setting this flag speeds processing, but may cause you to miss some faces. In general, you can do well with it set, but if you're having difficulty detecting faces, clearing this flag may allow you to detect more reliably. Setting the minimum-neighbors threshold to 0 so you can view the raw detections will help you better gauge the effect of using Canny pruning.
The Haar Cascade
There are several frontal face detector cascades in OpenCV. The best choice for you will depend on your set up. It's easy to switch between them - just change the file name. Why not try each?
It's also possible to create your own, custom XML file using the HaarTraining application, in OpenCV's apps directory. Using that application is beyond the scope of this article. However, the instructions are in OpenCV's apps/haartraining/docs directory.
Next...
Now that you've found a face, you might want to follow it around.
In Part 3,
I'll show you how to use Camshift, OpenCV's face tracking method, to do that. Be seeing you!
|