// C++ includes. #include // OpenCV includes. #include #include void faceDetection(IplImage* frame, CvMemStorage* storage, CvHaarClassifierCascade* classifier) { // "Resets" the memory but does not deallocate it. cvClearMemStorage(storage); // Run the main object recognition function. The arguments are: // 1. the image to use // 2. the pre-trained Haar classifier cascade data // 3. memory storage for rectangles around recognized objects // 4. a scale factor "by which the search window is scaled between the // subsequent scans, for example, 1.1 means increasing window by 10%" // 5. the "minimum number (minus 1) of neighbor rectangles that makes up // an object. All the groups of a smaller number of rectangles than // min_neighbors-1 are rejected. If min_neighbors is 0, the function // does not any grouping at all and returns all the detected candidate // rectangles, which may be useful if the user wants to apply a // customized grouping procedure." // 6. flags which determine the mode of operation // 7. the minimum object size CvSeq* faces = cvHaarDetectObjects(frame, classifier, storage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40)); // If any faces were detected, draw rectangles around them. if (faces) { for(int i = 0; i < faces->total; ++i) { // Setup two points that define the extremes of the rectangle, // then draw it to the image.. CvPoint point1, point2; CvRect* rectangle = (CvRect*)cvGetSeqElem(faces, i); point1.x = rectangle->x; point2.x = (rectangle->x + rectangle->width); point1.y = rectangle->y; point2.y = (rectangle->y + rectangle->height); cvRectangle(frame, point1, point2, CV_RGB(255,0,0), 3, 8, 0); } } } int main(int argc, char* argv[]) { // Setup either a camera or input video to use for face detection. CvCapture* inputSource = cvCaptureFromCAM(0); //CvCapture* inputSource = cvCaptureFromAVI("input.avi"); // Load the pre-trained Haar classifier data. CvHaarClassifierCascade* classifier = (CvHaarClassifierCascade*)cvLoad( "data/haarcascades/haarcascade_frontalface_alt.xml", 0, 0, 0); // Quit the application if the input source or the classifier data // failed to load properly. if(!inputSource || !classifier) { std::cerr << "ERROR: Invalid input source and/or classifier data." << std::endl; return -1; } // Create a CvMemStorage object for use by the face detection function. CvMemStorage* facesMemStorage = cvCreateMemStorage(0); // Setup a window to display out results. cvNamedWindow("Result", 1); IplImage* tempFrame = NULL; // Begin looping over the input video/camera data. while(true) { IplImage* currentFrame = cvQueryFrame(inputSource); // If we run out of input data, break out of the loop. if(!currentFrame) { break; } // If this is the first iteration, allocate a temporary image to // use for face detection. if (!tempFrame) { tempFrame = cvCreateImage(cvSize(currentFrame->width, currentFrame->height), IPL_DEPTH_8U, currentFrame->nChannels); } // Copy the current frame into the temporary image. Also, make // sure the images have the same orientation. if(currentFrame->origin == IPL_ORIGIN_TL) { cvCopy(currentFrame, tempFrame, 0); } else { cvFlip(currentFrame, tempFrame, 0); } // Perform face detection on the temporary image, adding a rectangle // around the detected face. faceDetection(tempFrame, facesMemStorage, classifier); // Show the result in the window. cvShowImage("Result", tempFrame); // If a key is pressed, break out of the loop. if(cvWaitKey(10) >= 0) { break; } } // Clean up allocated OpenCV objects. cvDestroyWindow("Result"); cvReleaseCapture(&inputSource); cvReleaseMemStorage(&facesMemStorage); if (tempFrame) { cvReleaseImage(&tempFrame); } return 0; }