1. 程式人生 > >簡單opencv人臉檢測程式碼:LBP/Haar特徵

簡單opencv人臉檢測程式碼:LBP/Haar特徵

前言

目前網路上有太多opencv人臉檢測程式碼,但大部分都是用老的1.0介面,程式碼存在太多冗餘(各種記憶體分配...看著太不舒服了,話說還有人用1.x版本的opencv嗎- -),而實際上用2.0以上版本實現人臉檢測功能是可以比較簡潔的。(官方也早有相關示例)

人臉檢測程式碼

haar與lbp的訓練結果已有現成的,在opencv安裝目錄的data資料夾中。(把這兩個檔案複製到工程目錄下) lbp比haar快非常多,識別率沒去仔細評估過。 廢話不多扯,上程式碼。(備註:這是個基於對話方塊的工程,就長這樣)
#define HAAR_CASCADE_FRONT_FACE_PATH "haarcascade_frontalface_default.xml"//front face  haar特徵方法  
#define LBP_CASCADE_FRONT_FACE_PATH "lbpcascade_frontalface.xml"//front face  LBP特徵方法  
bool CfaceDlg::DetectFace( Mat& src,vector<Rect>& faceRect)
{
	static cv::CascadeClassifier face_Classifier;
	static cv::Mat src_gray;

	cv::cvtColor( src, src_gray, CV_BGR2GRAY );//灰度化
	cv::equalizeHist( src_gray, src_gray );//直方圖均衡,增加對比度以提高識別率

	//load
	if (face_Classifier.empty())//check if load
	{
		if(false == face_Classifier.load(LBP_CASCADE_FRONT_FACE_PATH))
			return false;
	}

	faceRect.clear();
	//detect
	face_Classifier.detectMultiScale( src_gray, faceRect, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, cv::Size(30, 30) );

	if(faceRect.size() == 0)
		return false;

	return true;
}

圖片與視訊載入程式碼

遇到非常多新手,讀個圖片/視訊都要折騰半天,這裡直接貼上吧。
加兩個button,圖片button程式碼:

void CfaceDlg::OnBnClickedButtonPic()
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,_T("All Files(*.*)|*.*|Image File(*.jpg)|*.jpg||"),NULL);
	if(IDOK == dlg.DoModal())
	{
		USES_CONVERSION;
		string pic_path = W2A((LPCTSTR)dlg.GetPathName());

		Mat src = imread(pic_path);
		if(src.empty()) return;
		vector<Rect> faceRect;
		namedWindow("face",1);

		if(DetectFace(src,faceRect))//進行人臉識別
		{
			for (size_t faceIdx = 0;faceIdx < faceRect.size();faceIdx++)//畫人臉
			{
				cv::rectangle(src,faceRect[faceIdx],cv::Scalar(10,220,240));
			}
		}
		imshow("face", src);
		waitKey();
	}
}

視訊button程式碼:
void CfaceDlg::OnBnClickedButtonCamera()
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	VideoCapture cap(0); // open the default camera
	if(!cap.isOpened())  // check if we succeeded
		return ;

	Mat src;
	namedWindow("face",1);
	for(;;)
	{
		vector<Rect> faceRect;
		cap >> src; // get a new frame from camera
		if(DetectFace(src,faceRect))
		{
			for (size_t faceIdx = 0;faceIdx < faceRect.size();faceIdx++)
			{
				cv::rectangle(src,faceRect[faceIdx],cv::Scalar(10,220,240));
			}
		}
		imshow("face", src);
		if(waitKey(30) >= 0) break;
	}
	// the camera will be deinitialized automatically in VideoCapture destructor
	cv::destroyWindow("face");
	return ;
}