视频帧人脸检测 (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