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安裝檔案夾如下路徑中:
将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():
物體的最大大小,指定其大小的最大值,所有大于此的都被忽視掉;