阅读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.