Created
January 15, 2011 00:04
-
-
Save xoebus/780546 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Run with: | |
// ./facedetect --cascade="/opt/local/share/opencv/haarcascades/haarcascade_frontalface_default.xml" 0 | |
// | |
// Remember to change the path of your xml file. | |
// | |
// OpenCV Sample Application: facedetect.c | |
// Include header files | |
#include "cv.h" | |
#include "highgui.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include <math.h> | |
#include <float.h> | |
#include <limits.h> | |
#include <time.h> | |
#include <ctype.h> | |
// 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=\"<cascade_path>\" [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. | |
capture = cvCaptureFromCAM( 0 ); | |
// 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(;;) | |
{ | |
frame = cvQueryFrame( capture ); | |
// 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) ); | |
// 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 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment