![]() |
| 點圖可放大 |
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
看過文章之後歡迎留下您寶貴的意見喔!