視頻幀人臉檢測 (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