这个是用前后帧对比的方式进行的人脸检测,因为之前用的视频单帧图片进行人脸检测的效果有限,所以企图能通过其他手段优化视频人脸检测的处理。
我现在的思路就是先尽量精确的检测出人的范围(外接矩形),然后只在这个范围里面人脸检测,这样就可以提高误判率
老师要求的时间限制是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; }