使用HaarDetec进行简单的人脸识别(face detection)

红薯 发布于 2011/06/12 08:37
阅读 3K+
收藏 7

範例程式下載(使用BCB)

PS:內附分類器的xml文件

文章转自:http://blog.finalevil.com/2008/03/opencv04face-detectionhaardetectobjects.html

This is a demo of face detection by using OpenCV.The result is very bad.But if you know it only spent 10 minutes,then you would not think so.Will explain how to accomplish below.

我們先來看看這隻程式的效果如何?從下圖我們可以看到,效果很爛= ="
但是,如果你知道完成它只要10分鐘!!!那麼你就會驚艷使用OpenCV的便利,
立基於OpenCV的開發絕對會讓電腦視覺和影像處理,非常方便快速。
現在就和我一起加入,學習使用與擴充OpenCV,而非重造輪子!!7 
##ReadMore##

在這個範例裡面,我們使用Haar feature做為辨識特徵,使用Cascade Adaboost分類器
做為學習機制。這個範例是OpenCV安裝完以後附帶範例的簡化版本。

(1)載入分類器

String cascade_name = "C:\\Documents and Settings\\Administrator\\桌面\\FaceDetect\\other\\haarcascade_frontalface_alt2.xml"; 

CvHaarClassifierCascade* cascade
=  (CvHaarClassifierCascade*)cvLoad( cascade_name.c_str() );
OpenCV安裝完會附帶一些訓練好的Cascade分類器,這些分類器被儲存在 C:\Program Files\OpenCV\data\haarcascades資料夾裡面,其附檔名為.xml ,我們可以試用這些訓練好的分類器,解此熟悉OpenCV的使用。

CvHaarClassifierCascade
這就是用來表示分類器的資料結構。
因此,在上面我們建立了一個CvHaarClassifierCascade形別的指標。
cvLoad(char* filename)
載入指定路徑的分類器檔案。
c_str()
這是BCB Stirng Object的方法,可以將字串轉型為char*,這個型別正好是cvLoad需要的。



(2)偵測影像中的人臉 CvMemStorage* storage = cvCreateMemStorage(0);

CvSeq* faces = cvHaarDetectObjects( gray, cascade, storage, 1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/, cvSize(30, 30) );

CvMemStorage(size):
用來建立一個指定大小的記憶體區塊,若為0,則建立的記憶體區塊大小依照預設值為64k
CvSeq
此資料型別用來表示一連串的opencv物件序列,類似C++的Array或是Queue,從上面例子來看,偵測到的人臉,是一連串(偵測到的人臉不只一個)的opencv物件,會被存在CvSeq*型別的faces變數中。
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) );

詳細說明,你可以 參考這裡
以下簡單說明,
image:表示要偵測的圖片。
cascade:分類器變數,在第一個步驟所載入的分類器。
storage:偵測到的物件所儲存的記憶體區塊。
min_size:檢測視窗的最小尺寸。因為AdaBoost的演算法,分成搜索視窗和檢測視窗兩個部分,搜索視窗在整個圖片中移動,檢測視窗在搜索視窗中移動並計算特徵值。 當檢測視窗越小,則計算特徵值的單位就越小,需要的運算量就越高,但是結果不一定會更為精確。



(3)將偵測到的人臉位置,顯示在圖片上
    for(int i = 0; i < faces->total; i++ )
    {
        /* extract the rectanlges only */
        CvRect* face_rect = (CvRect*)cvGetSeqElem( faces, i );        
        cvRectangle( iplImg, cvPoint(face_rect->x,face_rect->y),
                     cvPoint((face_rect->x+face_rect->width),
                             (face_rect->y+face_rect->height)),
                     CV_RGB(255,0,0), 3 );
    }

由上面可以知道偵測到的人臉(物件)都被放置在faces變數中,
我們現在就使用 cvGetSeqElem這個函數把存在faces變數中的物件一個一個拿出來。
在將物件拿出來的同時,我們把物件轉型為 cvRect型別。
cvRect
此資料形態用來表示一個矩形,因此會有此舉行的 左上座標,和矩形的 長與寬

透過 cvRectangle我們可以在指定的圖片上用cvRect指定要繪製矩形大小與位置,而這些矩形就是我們偵測到的人臉位置。
加载中
返回顶部
顶部