閱讀168 返回首頁    go 阿裏雲 go 技術社區[雲棲]


視頻幀人臉檢測 (I)

這個是用前後幀對比的方式進行的人臉檢測,因為之前用的視頻單幀圖片進行人臉檢測的效果有限,所以企圖能通過其他手段優化視頻人臉檢測的處理。

我現在的思路就是先盡量精確的檢測出人的範圍(外接矩形),然後隻在這個範圍裏麵人臉檢測,這樣就可以提高誤判率


老師要求的時間限製是2周內,這個時間有一點點緊了,雖然這個項目我覺得不難,但是中途遇到的問題是不可預知的。。。

這段代碼存在一個問題,就是用膨脹操作的時候,如果核太大,計算量會陡增,甚至比單幀處理的還慢。。。所以問題必須解決膨脹問題,不能隻用膨脹來形成連通域

而且中值濾波的效率也不高


解決的思路大致有一些了,就是先對整個圖片輪廓檢測,去掉小麵積的,然後再小核膨脹試試


先貼出待修改的facedetect2.cpp的代碼:

//opencv2.0風格

#include "cv.h"
#include "highgui.h"

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

#include <iostream>
#include <cstdio>

using namespace std;
using namespace cv;


int main()
{
	Mat frame;		//每一幀圖像
	Mat gray;		//frame轉成的灰度圖
	Mat frame_copy_8U;	//copy過來的8U圖像
	Mat img1;		//差分輸出
	Mat outBinary; //二值圖輸出
	Mat outDilated;//膨脹輸出

	//獲取自定義核
	Mat elementDilated = getStructuringElement(MORPH_RECT, Size(200, 200));

	int nThreshold; //二值化閾值
	char* input_name = "001.avi";


	//從視頻讀入
	VideoCapture capture(input_name);

	cvNamedWindow( "result", 1 );

	if(capture.isOpened()/*capture*/)	// 攝像頭讀取文件開關
	{
		//對每一幀做處理

		for(;;)
		{
			capture >> frame;

			if(!frame.empty())//如果捕捉到了
			{ 
				//frame->gray 單通道灰度圖
				cvtColor(frame, gray, CV_BGR2GRAY);

				//進行處理
				if (frame_copy_8U.empty())
				{
					//記錄第一幀 gray->frame_copy
					gray.convertTo(frame_copy_8U, CV_8U);
				}

				//差分
				absdiff(frame_copy_8U, gray, img1);

				//二值化
				nThreshold=30;
				threshold(img1, outBinary, nThreshold, 255, THRESH_BINARY);

				//中值濾波
				cv::medianBlur(outBinary, outBinary, 5);


				//進行膨脹操作
				dilate(outBinary,outDilated, elementDilated);


				imshow("resultPre", outDilated);

				//輪廓檢測
				vector<vector<Point>> _contours;//儲存所有輪廓
				vector<Vec4i>hierarchy;

				Mat imageROI;;
				cv::findContours( outDilated, _contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

				double area_threshold = 0;

				for(size_t i = 0; i< _contours.size(); ++i)
				{
					//遍曆所有輪廓

					//獲得外接矩形
					Rect r0 = boundingRect(Mat(_contours[i]));
					//計算輪廓麵積
					double contArea =  fabs(contourArea(_contours[i]));

					cout<<contArea<<endl;
					cout<<"x == "<<r0.x<<endl;
					cout<<"y == "<<r0.y<<endl;

					rectangle(outDilated,r0,cvScalar(255,255,255),1,8,0);

					//去除較小麵積的輪廓
					/*if( contArea < area_threshold)
						continue;*/

				}

				cout<<"\n\n*************************************"<<endl;

				imshow("src", frame);
				imshow("result", outDilated);

			}

			else
			{ 
				printf(" --(!) No captured frame -- Break!");
				break;
			}

			//10ms中按任意鍵進入此if塊
			if( cvWaitKey( 10 ) >= 0 )
				break;
		}
	}

	return 0;
}





最後更新:2017-04-03 05:39:40

  上一篇:go 高質量的HTML
  下一篇:go linux 空間不夠了,怎麼辦?Disk Requirements:At least 11MB more space needed on the / filesystem.