1. 程式人生 > >【MFC基礎入門】OpenCV人臉檢測與馬賽克

【MFC基礎入門】OpenCV人臉檢測與馬賽克

這是OpenCV的程式碼,在這基礎上加了馬賽克。

void CFaceDetectionDlg::detect_and_draw( IplImage* img )  
{  
	//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}}  
	//};  //用不同顏色的圈圈區分不同的人

	double scale = 1.3;													//先縮小為small_img 後放大,為了便於處理也可以不用   
	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 );  
	int i;  

	cvCvtColor( img, gray, CV_BGR2GRAY );								//灰度圖
	cvResize( gray, small_img, CV_INTER_LINEAR );						//縮小
	cvEqualizeHist( small_img, small_img );								//經過上面兩步,gray指向的影象已經變為small_img
	cvClearMemStorage( storage );										//動態記憶體重置

	if( cascade )														//括號裡是分類器的指標,就是用這個東西來判斷是不是人臉的!!!
	{
		double t = (double)cvGetTickCount();							//開始計時
		CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
			1.1, 2, 0													/*CV_HAAR_DO_CANNY_PRUNING*/,
			cvSize(30, 30) );											//檢測的核心語句,注意cascade引數
		t = (double)cvGetTickCount() - t;								//計算時間間隔
		//cout<<"detection time = %gms\n"<<t/((double)cvGetTickFrequency()*1000.)<<endl;//打印出所用的時間
		for( i = 0; i < (faces ? faces->total : 0); i++ )				//總共有faces->total 個臉,把他們一個一個圈出來
		{
			CvRect* r = (CvRect*)cvGetSeqElem( faces, i );				//每個臉對應的連結串列節點
			CvPoint center;
			int radius;
			center.x = cvRound((r->x + r->width*0.5)*scale);			//圓心橫座標,注意scale,這裡放大
			center.y = cvRound((r->y + r->height*0.5)*scale);			//縱座標
			radius = cvRound((r->width + r->height)*0.25*scale);		//半徑
			//cvCircle( img, center, radius, colors[i%8], -1, 8, 0 );	//畫圓圈出目標頭像

			//馬賽克
			cvSetImageROI(img,cvRect(center.x-radius,center.y-radius,radius*2,radius*2));
			int W=8;
			int H=8;
			for(int mi=W;mi<img->roi->width;mi+=W)
				for(int mj=H;mj<img->roi->height;mj+=H)
				{
					CvScalar tmp=cvGet2D(img,mj-H/2,mi-W/2);
					for(int mx=mi-W;mx<=mi;mx++)
						for(int my=mj-H;my<=mj;my++)
							cvSet2D(img,my,mx,tmp);
				}
			cvResetImageROI(img);  
		}
	}

	cvReleaseImage( &gray );  
	cvReleaseImage( &small_img );  
}

本人寫的通用小專案下載地址:可以提取分類器進行檢測,大家必須配置好OpenCV環境和在原始碼中設定好分類器的路徑。


結果預覽



轉載請註明出處!