- 首先定義一些Haar-Like Features。
- 再來,我們必須給定一些sample,例如: 假如我們要偵測的是人臉,那麼我們就要輸入一些人臉的sample。有了這些sample,我們將會利用AdaBoost learning algorithm來挑出某幾個代表性的Haar-Like Features,以這個例子來講,我們可以想成這些被挑選出來的feature就是代表人臉的feature。
- 每個被挑選出來的feature都代表一種classifier,許多種被挑選出來的feature因此構成了一連串的classifier,我們稱為strong classifier。而每個classifier皆用來判斷所輸入的圖片是否為人臉,並且回傳「是」或「否」,最後,通過所有classifier的圖片將被判定是一張人臉。
/* * Face Detection in Digital Photographs * * We leverage the AdaBoost learning-based face detection method with Haar-like features to detect faces in photos. * However, OpenCV supplies Haar Cascade classifier for object (face) detection. * * (C) Matt Swanson & TrekLee * http://seeyababy.blogspot.com/ * */ // Path setting for OpenCV Library #pragma comment(lib,"../OpenCV/lib/cv.lib") #pragma comment(lib,"../OpenCV/lib/cxcore.lib") #pragma comment(lib,"../OpenCV/lib/highgui.lib") // Path setting for OpenCV Header files #include "../OpenCV/include/cv.h" #include "../OpenCV/include/cxcore.h" #include "../OpenCV/include/highgui.h" #include <stdio.h> #include <iostream> using namespace std; // the minimum object size int min_face_height = 20; int min_face_width = 10; //Face Detection int runFaceDetection(IplImage* image_detect); void main() { IplImage* pImg = cvLoadImage( "image.jpg", 1); runFaceDetection(pImg); cvReleaseImage( &pImg ); } int runFaceDetection(IplImage* image_detect) { // Load the pre-trained Haar classifier data. CvHaarClassifierCascade* classifier = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml", 0, 0, 0); // Quit the application if the input source or the classifier data failed to load properly. if( !classifier) { cerr << "ERROR: Could not load classifier cascade." << endl; return -1; } // Create a CvMemStorage object for use by the face detection function. CvMemStorage* facesMemStorage = cvCreateMemStorage(0); IplImage* tempFrame = cvCreateImage(cvSize(image_detect->width, image_detect->height), IPL_DEPTH_8U, image_detect->nChannels); // Copy the current frame into the temporary image. Also, make // sure the images have the same orientation. if(image_detect->origin == IPL_ORIGIN_TL) { cvCopy(image_detect, tempFrame, 0); } else { cvFlip(image_detect, tempFrame, 0); } /* Perform face detection on the temporary image, adding a rectangle around the detected face. */ // "Resets" the memory but does not deallocate it. cvClearMemStorage(facesMemStorage); // 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 (if possible, increasing this will // really speed up the process) CvSeq* faces = cvHaarDetectObjects(tempFrame, classifier, facesMemStorage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(min_face_width, min_face_height)); // 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(tempFrame, point1, point2, CV_RGB(255,0,0), 3, 8, 0); } } // Show the result in the window. cvNamedWindow("Face Detection Result", 1); cvShowImage("Face Detection Result", tempFrame); cvWaitKey(0); cvDestroyWindow("Face Detection Result"); // Clean up allocated OpenCV objects. cvReleaseMemStorage(&facesMemStorage); cvReleaseImage(&tempFrame); cvReleaseHaarClassifierCascade( &classifier ); return 0; }
CvSeq* faces = cvHaarDetectObjects(tempFrame, classifier, facesMemStorage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(min_face_width, min_face_height));
我們發現誤判果然被解決了。