1. 程式人生 > >opencv中haar特徵檢測人臉(適合小白)

opencv中haar特徵檢測人臉(適合小白)

本文的例程是我第一次用opencv自帶的利用haar特徵人臉識別的分類器檔案進行人臉檢測的收穫,注意,前提是已經有了分類器檔案xml,僅僅是利用它來進行檢測的過程。希望能幫到有需求的人~

步入正題吧,haar特徵識別人臉的原理情自行百度,這裡就不多說了。《學習opencv》一書中有一段利用haar特徵進行人臉檢測和標識的程式碼,我按照他的程式碼寫了程式,發現了一些小小的問題,列舉下來。先直接上我最後的程式碼吧。

//----------------HAAR特徵的人臉檢測-------------------
//使用opencv自帶的xml分類器檔案
//問題:1.分類器檔案的載入,使用的是opencvc的路徑下的data中的帶有GPU的資料夾下的分類器檔案,另外一個不能成功。
//2、巨集定義中的SCALE的值影響了縮放的比例,非常影響結果。
//----------------------cjs-----------------------------

#include<opencv.hpp>
#include<highgui.hpp>
//#include<core.hpp>
//#include<ml\ml.hpp>
//#include<opencv2\imgproc.hpp>

#define SCALE 1.01//巨集定義一個縮放的尺寸方便修改

void detect_and_draw(IplImage* img, double scale = SCALE)
{
	//定義顯示的框的顏色
	static CvScalar colors[] = { { 0,0,255 },{ 0,128,255 },{ 0,255,255 },{ 0,255,0 },
	{ 255,128,0 },{ 255,255,0 },{ 255,0,0 },{ 255,0,255 } };
	//載入分類器,按照自己的分類器路徑載入
	CvHaarClassifierCascade *cascade = (CvHaarClassifierCascade*)cvLoad(
		"D:\\opencv_2_4_13\\opencv\\sources\\data\\haarcascades_GPU\\haarcascade_frontalface_default.xml");
	//判斷是否載入分類器成功
	if (!cascade)
	{
		cvShowImage("error", img);
		cvWaitKey(100);//等100的原因是給足夠的時間來顯示圖片,不然可能顯示不成功

	}
	//建立儲存空間
	CvMemStorage* storage = cvCreateMemStorage(0);
	//建立灰度影象和縮小的影象
	IplImage* gray = cvCreateImage(cvSize(img->width, img->height), 8, 1);
	IplImage* small_img = cvCreateImage(cvSize(cvRound(img->width / scale), cvRound(img->height / scale)), 8, 1);
	cvCvtColor(img, gray, CV_BGR2GRAY);
	cvResize(gray, small_img, CV_INTER_LINEAR);
	//直方圖均衡化,消除圖片成像條件引起的問題
	cvEqualizeHist(small_img, small_img);
	//先清空儲存區域
	cvClearMemStorage(storage);
	//這就是重點啦,識別過程
	CvSeq* objects = cvHaarDetectObjects(small_img, cascade, storage, 1.1, 2, 0, cvSize(30, 30));
	//依次提取出結果並顯示
	for (int i = 0; i < (objects ? objects->total : 0); i++)
	{
		CvRect* r = (CvRect*)cvGetSeqElem(objects, i);
		cvRectangle(img, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), colors[i % 8]);
	}
	cvShowImage("result", img);
	//暫停,一直顯示結果
	cvWaitKey(0);
	cvReleaseImage(&gray);
	cvReleaseImage(&small_img);

}
void main()
{
	IplImage* img = cvLoadImage("people.jpg", 3);//這裡可以更改讀取的影象
	detect_and_draw(img,SCALE);
}


給兩張執行結果圖吧。

如圖,人臉還是檢測到了一些,但是有些地方有些錯誤識別,需要進一步研究咯,不過目的達到了,就是能使用分類器檔案來檢測出人臉了~

以下是幾個問題:

1:分類器檔案只能用data資料夾下的haarcascades_GPU資料夾下的檔案,而不能用haarcascades下面的檔案,至於為什麼,我也不能解釋,歡迎大家解答啦~

2:那個SCALE的值很會影響到識別的結果。這裡設定的是1.01,效果還可以,我之前按照書上的設定的是1.3,效果慘不忍睹。就是這樣咯~


以上就是我的一些小收穫啦,如果有錯誤希望大家指正,大家一起交流進步~~微笑