/* $ sudo yum install opencv-devel Compile with: $ gcc -o facedetect-example facedetect-example.c -I /usr/include/opencv -lopencv_core -lopencv_imgproc -lopencv_video -lopencv_highgui -lopencv_objdetect Now try and check all the example cascade in /usr/share/OpenCV/haarcascades/: $ ./facedetect-example --cascade=/usr/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml */ // OpenCV Sample Application: facedetect.c // Include header files #include "cv.h" #include "highgui.h" #include #include #include #include #include #include #include #include #include // Create memory for calculations static CvMemStorage* storage = 0; // Create a new Haar classifier static CvHaarClassifierCascade* cascade = 0; // Function prototype for detecting and drawing an object from an image void detect_and_draw( IplImage* image ); // Create a string that contains the cascade name const char* cascade_name = "haarcascade_frontalface_alt.xml"; /* "haarcascade_profileface.xml";*/ // Main function, defines the entry point for the program. int main( int argc, char** argv ) { // Structure for getting video from camera or avi CvCapture* capture = 0; // Images to capture the frame from video or camera or from file IplImage *frame, *frame_copy = 0; // Used for calculations int optlen = strlen("--cascade="); // Input file name for avi or image file. const char* input_name; // Check for the correct usage of the command line if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 ) { cascade_name = argv[1] + optlen; input_name = argc > 2 ? argv[2] : 0; } else { fprintf( stderr, "Usage: facedetect --cascade=\"\" [filename|camera_index]\n" ); return -1; /*input_name = argc > 1 ? argv[1] : 0;*/ } // Load the HaarClassifierCascade cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); // Check whether the cascade has loaded successfully. Else report and error and quit if( !cascade ) { fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); return -1; } // Allocate the memory storage storage = cvCreateMemStorage(0); // Find whether to detect the object from file or from camera. if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') ) capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' ); else capture = cvCaptureFromAVI( input_name ); // Create a new named window with title: result cvNamedWindow( "result", 1 ); // Find if the capture is loaded successfully or not. // If loaded succesfully, then: if( capture ) { // Capture from the camera. for(;;) { // Capture the frame and load it in IplImage if( !cvGrabFrame( capture )) break; frame = cvRetrieveFrame( capture, 0 ); // If the frame does not exist, quit the loop if( !frame ) break; // Allocate framecopy as the same size of the frame if( !frame_copy ) frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels ); // Check the origin of image. If top left, copy the image frame to frame_copy. if( frame->origin == IPL_ORIGIN_TL ) cvCopy( frame, frame_copy, 0 ); // Else flip and copy the image else cvFlip( frame, frame_copy, 0 ); // Call the function to detect and draw the face detect_and_draw( frame_copy ); // Wait for a while before proceeding to the next frame if( cvWaitKey( 10 ) >= 0 ) break; } // Release the images, and capture memory cvReleaseImage( &frame_copy ); cvReleaseCapture( &capture ); } // If the capture is not loaded succesfully, then: else { // Assume the image to be lena.jpg, or the input_name specified const char* filename = input_name ? input_name : (char*)"lena.jpg"; // Load the image from that filename IplImage* image = cvLoadImage( filename, 1 ); // If Image is loaded succesfully, then: if( image ) { // Detect and draw the face detect_and_draw( image ); // Wait for user input cvWaitKey(0); // Release the image memory cvReleaseImage( &image ); } else { /* assume it is a text file containing the list of the image filenames to be processed - one per line */ FILE* f = fopen( filename, "rt" ); if( f ) { char buf[1000+1]; // Get the line from the file while( fgets( buf, 1000, f ) ) { // Remove the spaces if any, and clean up the name int len = (int)strlen(buf); while( len > 0 && isspace(buf[len-1]) ) len--; buf[len] = '\0'; // Load the image from the filename present in the buffer image = cvLoadImage( buf, 1 ); // If the image was loaded succesfully, then: if( image ) { // Detect and draw the face from the image detect_and_draw( image ); // Wait for the user input, and release the memory cvWaitKey(0); cvReleaseImage( &image ); } } // Close the file fclose(f); } } } // Destroy the window previously created with filename: "result" cvDestroyWindow("result"); // return 0 to indicate successfull execution of the program return 0; } // Function to detect and draw any faces that is present in an image void detect_and_draw( IplImage* img ) { int scale = 1; // Create a new image based on the input image IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 ); // Create two points to represent the face locations CvPoint pt1, pt2; int i; // Clear the memory storage which was used before cvClearMemStorage( storage ); // Find whether the cascade is loaded, to find the faces. If yes, then: if( cascade ) { // There can be more than one face in an image. So create a growable sequence of faces. // Detect the objects and store them in the sequence CvSeq* faces = cvHaarDetectObjects( img, cascade, storage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40), cvSize(40, 40) ); // Loop the number of faces found. for( i = 0; i < (faces ? faces->total : 0); i++ ) { // Create a new rectangle for drawing the face CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); // Find the dimensions of the face,and scale it if necessary pt1.x = r->x*scale; pt2.x = (r->x+r->width)*scale; pt1.y = r->y*scale; pt2.y = (r->y+r->height)*scale; // Draw the rectangle in the input image cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 ); } } // Show the image in the window named "result" cvShowImage( "result", img ); // Release the temp image created. cvReleaseImage( &temp ); }