天天看點

OpenCV學習記錄(一):使用haar分類器進行人臉識别

OpenCV支援的目标檢測的方法是利用樣本的Haar特征進行的分類器訓練,得到的級聯boosted分類器(Cascade Classification)。OpenCV2之後的C++接口除了Haar特征以外也可以使用LBP特征。

介紹haar分類器理論知識:

1、http://www.cnblogs.com/ello/archive/2012/04/28/2475419.html(講的很詳細);

2、http://blog.csdn.net/zy1034092330/article/details/48850437(基礎理論)

實際使用中原理隻要大概懂就行了,如果想深究,可以讀讀兩個連結中的博文。

使用OpenCV中自帶的haar分類器識别人臉,其檔案在OpenCV安裝檔案夾如下路徑中:

OpenCV學習記錄(一):使用haar分類器進行人臉識别

将haarcascade_frontalface_alt.xml檔案複制到工程根目錄下即可。

代碼:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

//String my_face_cascade_name = "my_haarcasade_face.xml";
String face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
String window_name = "Capture - face detection";

void detectFace(Mat frame);

int main()
{
    VideoCapture capture;
    Mat frame;

    //檢測是否成功讀取人臉的haar分類器,就是那個xml檔案
    if (!face_cascade.load(my_face_cascade_name))
    {
        cout << "Error: cannot load face casade!!!" << endl;
        return -;
    }

    capture.open();//打開攝像頭
    //檢測攝像頭是否成功打開
    if (!capture.isOpened())
    {
        cout << "Error: cannot open the camera!!!" << endl;
        return -;
    }

        namedWindow(window_name);//建立視窗

    while (true)
    {
        capture >> frame;   //從攝像頭讀入一幀圖像

        detectFace(frame);//對那幀圖像進行處理,識别人臉

        //等待按鍵,若按下esc鍵,則退出循環
        int c = waitKey();
        if (c == )
            break;
    }


    return ;
}

//從輸入圖像中檢測人臉
void detectFace(Mat frame)
{
    Mat frame_gray;
    vector<Rect> face;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//轉成灰階圖像
    equalizeHist(frame_gray, frame_gray);//直方圖均衡化

    //按照文檔說明調用函數即可
    face_cascade.detectMultiScale(frame_gray, face, , , CASCADE_SCALE_IMAGE, Size(, ));

    //周遊所有人臉
    for (size_t i = ; i < face.size(); i++)
    {
        //根據傳回的Rect的x坐标、y坐标、寬width和高height算出中心位置
        Point center(face[i].x + face[i].width/, face[i].y + face[i].height/);
        //調用ellipse畫出橢圓型邊框,訓示人臉
        ellipse(frame, center, Size(face[i].width/, face[i].height/), , , , Scalar(, , ), , , );

    }

    //最後重新整理視窗,顯示圖像
    imshow(window_name, frame);
}
           

程式中已經有相關注釋,不做贅述。隻要環境配置正确,OpenCV2下運作應該不會有錯。

簡要總結一下CascadeClassifier::detectMultiScale函數的用法:

從文檔中摘出來的三種c++下的定義方式:

CascadeClassifier::detectMultiScale

Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.

C++: void CascadeClassifier::detectMultiScale(InputArray image, vector& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())

C++: void CascadeClassifier::detectMultiScale(InputArray image, vector& objects, vector& numDetections, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())

C++: void CascadeClassifier::detectMultiScale(InputArray image, std::vector& objects, std::vector& rejectLevels, std::vector& levelWeights, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size(), bool outputRejectLevels=false )

隻讨論下面這種形式:

C++: void CascadeClassifier::detectMultiScale(InputArray image,

vector& objects, double scaleFactor=1.1, int minNeighbors=3, int

flags=0, Size minSize=Size(), Size maxSize=Size())

參數說明:

1、InputArray image:

輸入圖像,填Mat類型的圖像即可。圖像通道數可以是任意的,但圖像深度應為CV_8U、CV_16U、CV_16S、CV_32F、CV_64F;

2、std::vector& objects:

為被檢測物體的矩形向量組,這裡就代表人臉所在範圍的矩形向量組;

3、double scaleFactor=1.1:

scaleFactor為圖像中的尺度參數,預設取值1.1;

4、int minNeighbors=3:

每一個級聯矩形應該保留的鄰近個數的最小值,預設為3;

5、int flags=0:

在老版本的OpenCV中,與cvHaarDetectObjects中的這個參數具有相同的含義,新版本中沒用,預設取0;

6、Size minSize=Size():

物體的最小大小,指定其大小的最小值,所有小于此的都被忽視掉;

7、Size maxSize=Size():

物體的最大大小,指定其大小的最大值,所有大于此的都被忽視掉;

繼續閱讀