Social Icons

twitterfacebookgoogle plusrss feedemail

6/02/2013

[OpenCV] 人臉偵測 (Face Detection)

點圖可放大

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
看過文章之後歡迎留下您寶貴的意見喔!

 
 
无觅相关文章插件,迅速提升网站流量