OpenCV Face Detection

Feb 5, 2009 | Tags: OpenCV | del.icio.us del.icio.us | digg Digg

OpenCV has an example of Face Detection, located in the samples directory of OpenCV distribution. It uses a type of face detector called a Haar Cascade classifier. Basically it performs a simple operation. Given an image, the face detector examine each image location and classifies it as "face" or "not face".

However, I found that the example is hard to understand. So I simplify the code and add some comments for us to better understand it. I also modify the code to take the input from webcam rather than static images.

The code below displays video from webcam, detect faces and draw a surrounding box for each face found.

Listing 1: OpenCV Face Detection

  1. /**
  2.  * Display video from webcam and detect faces
  3.  */
  4. #include <stdio.h>
  5. #include "cv.h"
  6. #include "highgui.h"
  7.  
  8. CvHaarClassifierCascade *cascade;
  9. CvMemStorage            *storage;
  10.  
  11. void detectFaces( IplImage *img );
  12.  
  13. int main( int argc, char** argv )
  14. {
  15.     CvCapture *capture;
  16.     IplImage  *frame;
  17.     int       key;
  18.     char      *filename = "haarcascade_frontalface_alt.xml";
  19.  
  20.     /* load the classifier
  21.        note that I put the file in the same directory with
  22.        this code */
  23.     cascade = ( CvHaarClassifierCascade* )cvLoad( filename, 0, 0, 0 );
  24.  
  25.     /* setup memory buffer; needed by the face detector */
  26.     storage = cvCreateMemStorage( 0 );
  27.  
  28.     /* initialize camera */
  29.     capture = cvCaptureFromCAM( 0 );
  30.  
  31.     /* always check */
  32.     assert( cascade && storage && capture );
  33.  
  34.     /* create a window */
  35.     cvNamedWindow( "video", 1 );
  36.  
  37.     while( key != 'q' ) {
  38.         /* get a frame */
  39.         frame = cvQueryFrame( capture );
  40.  
  41.         /* always check */
  42.         if( !frame ) break;
  43.  
  44.         /* 'fix' frame */
  45.         cvFlip( frame, frame, -1 );
  46.         frame->origin = 0;
  47.  
  48.         /* detect faces and display video */
  49.         detectFaces( frame );
  50.  
  51.         /* quit if user press 'q' */
  52.         key = cvWaitKey( 10 );
  53.     }
  54.  
  55.     /* free memory */
  56.     cvReleaseCapture( &capture );
  57.     cvDestroyWindow( "video" );
  58.     cvReleaseHaarClassifierCascade( &cascade );
  59.     cvReleaseMemStorage( &storage );
  60.  
  61.     return 0;
  62. }
  63.  
  64. void detectFaces( IplImage *img )
  65. {
  66.     int i;
  67.  
  68.     /* detect faces */
  69.     CvSeq *faces = cvHaarDetectObjects(
  70.             img,
  71.             cascade,
  72.             storage,
  73.             1.1,
  74.             3,
  75.             0 /*CV_HAAR_DO_CANNY_PRUNNING*/,
  76.             cvSize( 40, 40 ) );
  77.  
  78.     /* for each face found, draw a red box */
  79.     for( i = 0 ; i < ( faces ? faces->total : 0 ) ; i++ ) {
  80.         CvRect *r = ( CvRect* )cvGetSeqElem( faces, i );
  81.         cvRectangle( img,
  82.                      cvPoint( r->x, r->y ),
  83.                      cvPoint( r->x + r->width, r->y + r->height ),
  84.                      CV_RGB( 255, 0, 0 ), 1, 8, 0 );
  85.     }
  86.  
  87.     /* display video */
  88.     cvShowImage( "video", img );
  89. }
  90.  

Related Articles

Recommended Book

The Downloads

44 Comments

Jin Le on Feb 23, 2009:

Hi Nash.

I am a beginner at openCV and i really like to try out your face dectection application... but the thing is that i having problems getting the application up and running..
when i try to compile it, there are no errors of any kind... but a cmd promt says (assertion failed) pointing on this line of code "assert( cascade && storage && capture );" i am using VS 2008 c++

please give me a pointer..
i am looking forward for your reply ...
best regards

Jin le

Nash on Feb 24, 2009:

Hi,
It looks like the program cannot find any webcam attached to your computer, since it takes the input from webcam. To take the input from static images, replace main() with this:

int main( int argc, char** argv )
{
  CvCapture *capture;
  IplImage  *img;
  int       key;
  char      *filename = "haarcascade_frontalface_alt.xml";

  cascade = ( CvHaarClassifierCascade* )cvLoad( filename, 0, 0, 0 );
  storage = cvCreateMemStorage( 0 );
  img     = cvLoadImage( argv[1], 1 );

  assert( cascade && storage && img );

  cvNamedWindow( "video", 1 );
  detectFaces( img );
  cvWaitKey( 0 );
  cvDestroyWindow( "video" );
  cvReleaseImage( &img );
  cvReleaseHaarClassifierCascade( &cascade );
  cvReleaseMemStorage( &storage );

  return 0;
}
Run the program from your DOS box with command like: facedetect myphoto.jpg.

Also make sure that you have copied haarcascade_frontalface_alt.xml to the same directory with the code above.

ABHAY SHANKAR on Feb 27, 2009:

Hi Nash,
I am studying on the face detection algorithm (my research is on face recognition and comparison) using the haar like features by openCV. I wish to know the XML file used by the facedetect.c code.

My questions are:-

1. What are these threshold values n where are these values coming from?

2. Are the threshold value in the XML file directly compared with the haar features values calculated by the cvIntegeral?

3. What are "stage threshold" and "left value" and "right value"?

4. Can I use Phase Correlation technique for face recognition and comparison?

Nash on Feb 27, 2009:

Hi Abhay,
There is a good tutorial about finding faces with OpenCV that explains the parameters in cvHaarDetectObjects. Maybe we can find the answers there

atzu on Mar 3, 2009:

Hi Nash, great work.
I'd like to try your code but I have the same problem as the first comment. The line that says assertion failed "assert( cascade && storage && capture );" is getting the code crazy. I tried the script to see the video from my webcam and works fine so I can't understand why this doesn't... Any idea?

atzu on Mar 3, 2009:

Hi Nash, great work.
Works fine thanks. Just solved, was just the name of the haarcascade file name that was twice named as .xml... Didn't load properly, maybe the first comment is having the same problem because I downloaded from the wiki.

fuzy on Mar 19, 2009:

hi nash , really good work , but i have a problem with this code , when i compile it i find an error in a black prompt "assert( haarface , .... )" , i found that assert is working fine with img but with capture this error takes place , and i am sure my web cam is fine , i run it with your program "Display Video from Webcam" and it works fine , so can u help me plzzz , thx in advance

Kamardin on Apr 22, 2009:

Salam,

Congratz! Bro...
You have done a really good work to share with others. I do hope the good deed regain the good reciproration, dude!.

Eak on Apr 22, 2009:

If we will be used Kalman filter for tracking object then Haar detection. Will we be written code? Help me, please.

Aaron on May 14, 2009:

Hi, i have been trying your source code out, however there's a problem.

MFC Application will show
facetest3 MFC Application has encountered a problem and needs to close. We are sorry for the inconvenience.

I wish to ask why? did I miss out something?
I have already included library files, copied haarcascade_frontalface_alt.xml into same folder. You have any idea what when wrong? or is it my webcam cannot be detected with OPENCV?

Nash on May 15, 2009:

Hi,
I don't have VC++ so I'm afraid I cannot help. But I suggest you to use gcc compiler. We're using it and it works very well.

Jaideep on May 15, 2009:

Hi Nash,
I am working on the face detection algorithm (my research is on face recognition and comparison) by openCV.

I want to know that is there any limitation for comparison.

Is there any limitation for width and height?
Is there any limitation for size in KB?

Please reply.
Thanks in advance

Nash on May 15, 2009:

Hi,
You're doing face recognition. That's cool. Only one thing, I know nothing about it

felix on May 21, 2009:

This your "Display video from webcam and detect faces" code is a great welldone job. But I have the following problem with the codes:
1. It did not automatically take the picture of the face detected.
2. The dispalyed video output is upside down.
3. I need some codes to save picture taken by the codes.

Please Nash, i will really appreciate it further if you could help me out with the above issues.

Thanks a lot in advance.

Nash on May 22, 2009:

To fix the upside down frame, try to replace:

cvFlip(frame, frame, -1);

with this:

cvFlip(frame, frame, 0);

---

To save the detected faces into separate images, here's a quick and dirty code:

char *filename = "";
if (cvWaitKey(1) == 's') {
  for(i = 0 ; i < (faces ? faces->total : 0); i++) {
    sprintf(filename, "%d.jpg", (i+1));
    CvRect *r = (CvRect*)cvGetSeqElem(faces, i);
    cvSetImageROI(img, cvRect(r->x, r->y, r->width, r->height));
    cvSaveImage(filename, img);
    cvResetImageROI(img);
  }
}
The code above will save the detected faces to 1.jpg, 2.jpg, ..., n.jpg when you press the 's' button. Put the code at the end of detectFaces().

Felix Okoye on May 22, 2009:

Thanks a lot for the codes and your prompt response to my questions.

I was able to correct the upside down frame based on your kind clue but for the saving of the detected faces, i receive this error "Unhandled exception at 0x10228567 (msvcr80d.dll) in det.exe: 0xC0000005: Access violation writing location 0x00415643" immediately I press the letter "s"(det is my file's name).

I'm sorry to disturb you again, but your kind assistance will be more highly appreciated.

Many thanks in advance.

Nash on May 23, 2009:

It looks like VC++ doesn't like the sprintf() part. Maybe you have to format filename in VC++'s way. Since I don't have VC++, I cannot help you to figure it out.

Btw, when you have solved your problem, consider to put the solution in this forum.

Gabriel on Jun 24, 2009:

Hi, I discovered what is happening with the, "assert( cascade && storage && capture );" problem.

The problem is that the program doesn´t load the Harr cascade correctly. I discover it adding this to verify the output. It was giving always error.

capture = cvCaptureFromCAM( CV_CAP_ANY );
if( !capture ) {
    fprintf( stderr, "ERROR: capture is NULL n" );
    getchar();
    return -1;
}


The solution can be find it here:

http://www.openframeworks.cc/forum/viewtopic.php?f=10&t=1853

By the way, what a great blog!! Thanks man!!
Peace from Spain

Gabriel on Jun 24, 2009:

Hi there!

I just soved the problem!

The version I had was buggy, I just installed the opencv libraries from the repositories of Ubuntu 8.10 and it worked. The versión is 1.0.0.6-1

The problem was at this line

cascade = (CvHaarClassifierCascade*)cvLoad( "haarcascade_frontalface_alt.xml", 0, 0, 0 );

Thanks again and keep sharing so great tutorials, they are really helpful.

Tim on Jul 1, 2009:

@Nash

look at these two lines:

1. char *filename = "";
4. sprintf(filename, "%d.jpg", (i+1));

for me it seems, that's not a VC++ problem, it's a problem putting at least 6 bytes in a 1 byte buffer.

Nash on Jul 1, 2009:

Man, you're right! I forgot to initialize the variable. So here's the correct version:

char filename[6];
if (cvWaitKey(1) == 's') {
  for(i = 0 ; i < (faces ? faces->total : 0); i++) {
    sprintf(filename, "%d.jpg", (i+1));
    CvRect *r = (CvRect*)cvGetSeqElem(faces, i);
    cvSetImageROI(img, cvRect(r->x, r->y, r->width, r->height));
    cvSaveImage(filename, img);
    cvResetImageROI(img);
  }
}
It will save the subimage to 1.jpg, ..., n.jpg. Thanks.

felix on Jul 12, 2009:

Hi Nash,

i think the above codes still need some adjustments. It's able to store the first image but instead of storing subsequent images, it replaces the firstly stored one. Hence it could only store only one(1) image.

Can u try out something ?

TQ

abyadh on Jul 21, 2009:

Hi Nash,

I actually working on the same coding as yours, i tried to save every single image detected from the program. it works, but right now i'm not satisfied with the outcome since the filename is printed according to the value of k..here is the code

for( i = 0; i < (faces ? faces->total : 0); i++ )
{
   /* extract the rectanlges only */
   CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i);

   IplImage* clone = cvCreateImage (cvSize(img->width, img->height),
                                    IPL_DEPTH_8U, img->nChannels );
  
   cvCopy (img, clone, 0);
   cvNamedWindow ("ROI", CV_WINDOW_AUTOSIZE);
   cvSetImageROI ( clone, face_rect);
   face_rect = cvGetImageROI ( clone );
   cvShowImage ("ROI", clone);
   k = (int) cvGetTickCount();
   char *name=0;
   name=(char*) calloc(255, 1);
   sprintf(name, "Image %d.jpg", k);
   cvSaveImage(name, clone);
}

Nash on Jul 22, 2009:

Then give it a filename you like. What's the problem?

Luis on Aug 20, 2009:

can you tell me if there are a version of this library for c#?

Nash on Aug 20, 2009:

Here it is:

http://www.emgu.com

Jason on Aug 29, 2009:

Hey Nash
great tutorial..
i have compiled ur program . But i'm getting an error message when script prompt to show my webcam then a box show

Null pointer (Invalid classifier cascade)

Please help me out..

Nash on Aug 29, 2009:

The code above needs the haar classifier xml file. I didn't include it in the zip file, since you already have the file in your disk. If you installed OpenCV in:

C:/OpenCV

then the xml file is located at:

C:/OpenCV/data/haarcascades/haarcascade_frontalface_alt.xml

So all you have to do is copy the xml file to your working dir, and the code above should work just fine.

raj on Sep 12, 2009:

hey nash i'm doing hand recognition right now and for that i intend to use the haar classifier -but i am not sure about how to go about doing it as i'm still pretty new to opencv . If you could please explain to me how to train classifier and stuff like how to create .xml file and use it in the detction code i'l be very grateful .you dont have to give me the code just please explain me the steps involved and what to watch out for

also i have heard tht training a classifier takes about 3-5 days to train is this true?
thanks in adv

Nash on Sep 13, 2009:

Hi,

I've no experience on building classifiers, but here's the howto. It looks like it does take a lot of time to build one.

Note: if you've managed to build the classifier, consider to upload the xml file in this forum

Anju on Sep 14, 2009:

hi Nash,
Is it necessary to train the classifier for a generic object detection. My aim is to detect all the objects in a video. Is it possible to do the same without training the classifier? I mean is there any algorithm for this?

Nash on Sep 14, 2009:

Yes you can train classifiers for the objects. But why would you do that? you can track the objects using motion or color detection.

Anju on Sep 14, 2009:

Thanks a lot. Just wanted to confirm this.

Felipe on Oct 16, 2009:

Nash, good afternoon.

I found this very interesting topic and I wonder if there is such a library for Delphi 7.
Whether you have the package with the files .Pas and the dll to the examples cited above.
And also like to know what function that detects the characteristics of the face, because I saw some examples and the examples only detects the face and not his features.

Thank

Felipe Carnevali

Nash on Oct 17, 2009:

Hi,

I don't know if there is an OpenCV wrapper to Delphi. But IMHO, Delphi isn't suitable for computer vision tasks.

There are some papers out there that describe face features, but I haven't implement any yet.

watachi on Oct 30, 2009:

super thanks, the sample code from opencv was really complicated your is a bless,, opencv 2.0-visual 2008

Tony on Nov 18, 2009:

Thanks for uploading this tutorial. Was really a great help to me! Was just wondering, would it be possible to alter this code to take input from a video rather than webcam/static image. Im quite new to opencv, so your help will be much appreciated.

Thanks

Greg on Dec 17, 2009:

Nash,

Greate work!!

I'm learning OpenCV, and I was playing a video, and when I apply cvPyrDown to get a smood image, the video turned upside down, with your suggestion of the cvFlip(source, destination, 0); the problem was corrected and now everything looks perfect!!

Thanks alot!

Mohamed Alkaduhimi on Jan 28, 2010:

Nice example Nash, keep up the good work. What is wrong with some people here can't they write c code? They ask some very basic questions :S, my advice is to learn basic c and then study openCV.

Lideman on Feb 3, 2010:

Does anybody know how can i make a robot head that can follow the faces using Basic Stamp?
Thanks
best regards for all.

alex on Feb 14, 2010:

Try it at : http://www.progisma.com/face_detection/submit. If you need any help with face detection with OpenCV, contact me.

john on Feb 20, 2010:

Hi Nash...
My code on face detection works perfectly on VS 2008..
But i need to know how to make this code for multi threading... can you help me out

Dileep S.P on Mar 8, 2010:

Hi nash,

Im a newbie to openCV

I tried out your code but, There is a delay for the cam output, even though i changed the values for cvWaitKey there is too much delay, I am working with very limited hardware resources so is there a way to reduce the resolution of the img and still be able to detect faces, or some other approach to optimize the program ?

Nash on Mar 9, 2010:

Try to resize the frames taken from the camera:

capture = cvCaptureFromCAM(0);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 240);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 160);

Leave a comment

Name (required)
Email (will not be published) (required)
Website

Characters left = 1000

Tags

Recent Posts

  1. OpenCV Utility: Reading Image Pixels Value
  2. OpenCV Circular ROI
  3. OpenCV 2.0 Installation on Windows XP and Visual Studio 2008
  4. Runtime ROI Selection using Mouse
  5. Real Time Eye Tracking and Blink Detection
View Archives

About the Author

avatar Cool PHP programmer writing cool PHP scripts. Feel free to contact
Tel. +62 31 8662872
+62 856 338 6017
ICQ 489571630
Skype dede_bl4ckheart
Yahoo dede_bl4ckheart
Google nashruddin.amin

Recommended Sites:

Hacker's HTTP Client
HTML and CSS Tutorials
Stop Dreaming Start Action
Online Quran and Translation