點圖可放大 |
Paul Viola等人利用了三個演算法,來快速找到人臉。第一個是Integral Image,第二個是 AdaBoost,第三個是Cascade classifier。
Cascade Detection |
詳細步驟可以參考"Robust Real-Time Face Detection" 這篇paper,或者可以看下面我整理的幾份文章
1.robust-real-time-face-detection 介紹
載點
2.robust-real-time-face-detection 投影片
載點
如果還沒安裝OPENCV,可以參考這篇文章。
程式碼最重要的地方為這個函式cvHaarDetectObjects
cvHaarDetectObjects(const CvArr* image, CvHaarClassifierCascade* cascade,CvMemStorage* storage, double scale_factor=1.1,int min_neighbors=3, int flags=0,CvSize min_size=cvSize(0,0) );
參數說明大致上如下:
1.image: 要偵測的圖片。
2.cascade: 要使用的分類器。
3.storage: 偵測到的物件所儲存的記憶體區塊。
4.scale_factor: 搜索視窗成長比率。
5.min_neighbors: 最少鄰近偵測視窗。一個臉可能重複偵測好幾次,但我們只要取一次,如果設0的話,所有偵測的視窗都會畫出來。
6.flag: 演算法模式。
7.min_size: 檢測視窗的最小尺寸。因為AdaBoost的演算法,分成搜索視窗和檢測視窗兩個部分,搜索視窗在整個影像中移動,檢測視窗在搜索視窗中移動並計算特徵值。當檢測視窗越小,則計算特徵值的單位就越小,需要的運算量就越高,但是結果不一定會更為精確。
程式碼是使用haarcascade_frontalface_default.xml這個訓練好的分類器,其它效果比較好的還有haarcascade_frontalface_alt.xml。還有可以偵測眼睛、嘴巴、鼻子、上半身、下半身等等~(請參考:C:/OpenCV2.0/data/haarcascades 資料夾內)。
#include <cv.h> #include <cxcore.h> #include <highgui.h> #include <iostream> using namespace std; //人臉最小的範圍 int min_face_height = 50; int min_face_width = 50; int main( int argc , char ** argv ){ string image_name="lena.bmp"; // 讀取圖片 IplImage* image_detect=cvLoadImage(image_name.c_str(), 1); string cascade_name="C:/OpenCV2.0/data/haarcascades/haarcascade_frontalface_alt.xml"; //讀取cascade CvHaarClassifierCascade* classifier=(CvHaarClassifierCascade*)cvLoad(cascade_name.c_str(), 0, 0, 0); if(!classifier){ cerr<<"ERROR: Could not load classifier cascade."<<endl; system("pause"); return -1; } //配置記憶體 CvMemStorage* facesMemStorage=cvCreateMemStorage(0); IplImage* tempFrame=cvCreateImage(cvSize(image_detect->width, image_detect->height), IPL_DEPTH_8U, image_detect->nChannels); if(image_detect->origin==IPL_ORIGIN_TL){ cvCopy(image_detect, tempFrame, 0); } else{ cvFlip(image_detect, tempFrame, 0); } cvClearMemStorage(facesMemStorage); //偵測人臉 CvSeq* faces=cvHaarDetectObjects(tempFrame, classifier, facesMemStorage, 1.1, 3 , CV_HAAR_DO_CANNY_PRUNING, cvSize(min_face_width, min_face_height)); if(faces){ for(int i=0; i<faces->total; ++i){ //畫出偵測到的人臉框 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); } } //另存成02.bmp圖片 cvSaveImage("02.bmp", tempFrame); //視窗名稱 cvNamedWindow("Face Detection Result", 1); //展示圖片 cvShowImage("Face Detection Result", tempFrame); //讓視窗停住 cvWaitKey(0); cvDestroyWindow("Face Detection Result"); //釋放記憶體 cvReleaseMemStorage(&facesMemStorage); cvReleaseImage(&tempFrame); cvReleaseHaarClassifierCascade(&classifier); cvReleaseImage(&image_detect); system("pause"); return EXIT_SUCCESS; }專案下載:
載點1
除了上面程式碼可以參考之外
在OpenCV2.0\samples\c中 也有提供人臉辨識的範例與程式碼(facedetect)
沒有留言:
張貼留言
俗話說
凡走過必留下痕跡,凡住過必留下鄰居
凡爬過必留下樓梯,凡來過必留下IP
看過文章之後歡迎留下您寶貴的意見喔!