168
技術社區[雲棲]
視頻幀人臉檢測 (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