微视图像(microview)gige相机开发手记(2)

来源:互联网 发布:小米口罩知乎 编辑:程序博客网 时间:2024/05/29 04:06

由于在本项目中需要进行行人检测,而直接使用hog+svm行人检测速度太慢,无法检测视频流,在知乎上:http://cache.baiducontent.com/c?m=9d78d513d9d437ad4f9b96690c66c0171343f1132bd6a0020fa5843fe2732b415011e3ac27530772d7d20f1416df3a4b9ef72235775d2feddd8eca5ddcc88f356acd6223706bce1b49895eb8cb31749c7f8d19aef858a1e1ad6e8eaed7d7db5456c851&p=913fdc0585cc43b508e2947d0a07c6&newp=89769a4796934eaf5beac128554fbb231610db2151d0d701298ffe0cc4241a1a1a3aecbf27291104d6c67c600aae4f58e9f23c74340634f1f689df08d2ecce7e6f&user=baidu&fm=sc&query=%D0%D0%C8%CB%BC%EC%B2%E2+%D6%AA%BA%F5&qid=be576907001ba612&p1=1    看到张岱坤同学的回答,于是进行实现了下,检测速率有了很大的提升。

#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<opencv2\video\video.hpp>#include<vector>#include<opencv2\ml\ml.hpp>#include <opencv2/objdetect/objdetect.hpp>#include<fstream>#include"HumanDetectionAlth.h"int main(){cv::VideoCapture cam("test.avi");cv::BackgroundSubtractorMOG2 mog;cv::Mat frame;cv::Mat fore;cv::Mat openElement(3,3,CV_8U,cv::Scalar(1));cv::Mat dilateElement(7,7,CV_8U,cv::Scalar(1));int sizeMin=200;int sizeMax=10000;std::vector<std::vector<cv::Point>> contours;std::vector<cv::Rect>rects;cv::Rect rect_;std::vector<cv::Rect>persons;#if 0std::vector<float> myDetector;std::ifstream detectorfile("HOGDetectorForOpenCV.txt");float temp;while(!detectorfile.eof()){detectorfile>>temp;myDetector.push_back(temp);}myDetector.pop_back();detectorfile.close();cv::HOGDescriptor myHOG;myHOG.setSVMDetector(myDetector);#endifcv::HOGDescriptor myHOG;loadDetector(myHOG);std::vector<cv::Rect> found, found_filtered;cv::Rect r;while(1){cam>>frame;#if 0mog(frame,fore,0.01);cv::threshold(fore,fore,200,255,CV_THRESH_BINARY);cv::morphologyEx(fore,fore,cv::MORPH_OPEN,openElement,cv::Point(-1,-1),2);cv::dilate(fore,fore,dilateElement,cv::Point(-1,-1),7);cv::findContours(fore,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);auto i=contours.begin();while(i!=contours.end()){if(i->size()<sizeMin||i->size()>sizeMax)i=contours.erase(i);else{rect_=cv::boundingRect(cv::Mat(*i));rects.push_back(rect_);//cv::rectangle(frame,rect_,cv::Scalar(0,255,0),2);cv::Mat ROI=frame(rect_);found.clear(), found_filtered.clear();myHOG.detectMultiScale(ROI, found, 0, cv::Size(8,8), cv::Size(35,35), 1.05, 2);for(size_t i1=0; i1 < found.size(); i1++){ r = found[i1];size_t j=0;for(; j < found.size(); j++)if(j != i1 && (r & found[j]) == r)break;if( j == found.size())found_filtered.push_back(r);}for(int i2=0; i2<found_filtered.size(); i2++){    r = found_filtered[i2];r.x += cvRound(r.width*0.1);r.width = cvRound(r.width*0.8);r.y += cvRound(r.height*0.07);r.height = cvRound(r.height*0.8);rectangle(ROI, r, cv::Scalar(0,255,0), 2);//found.clear(), found_filtered.clear();}++i;}}contours.clear();rects.clear();#endifmog(frame,fore,0.01);getROI(fore,rects,contours);detectPersonInROIs(frame,myHOG,rects,persons,found,found_filtered);for(auto &i :persons)cv::rectangle(frame,i,cv::Scalar(0,255,0),2);cv::imshow("src",frame);//cv::imshow("res",fore);if(cv::waitKey(1)=='c')break;}cv::destroyAllWindows();cam.release();}

相关自定义的函数如下:

void loadDetector(cv::HOGDescriptor&descriptor){descriptor.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());}void getROI(cv::Mat& foreground,std::vector<cv::Rect>&resROI,std::vector<std::vector<cv::Point>> &contours,double thresholdvalue,int openIteration,int dilateIteration,size_t minSize,size_t maxSize){resROI.clear();contours.clear();cv::Mat openElement(3,3,CV_8U,cv::Scalar(1));cv::Mat dilateElement(7,7,CV_8U,cv::Scalar(1));cv::threshold(foreground,foreground,thresholdvalue,255,CV_THRESH_BINARY);cv::morphologyEx(foreground,foreground,cv::MORPH_OPEN,openElement,cv::Point(-1,-1),openIteration);cv::dilate(foreground,foreground,dilateElement,cv::Point(-1,-1),dilateIteration);cv::findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);auto i=contours.begin();while(i!=contours.end()){if(i->size()<minSize||i->size()>maxSize)i=contours.erase(i);else{cv::Rect rect_=cv::boundingRect(cv::Mat(*i));resROI.push_back(rect_);++i;}}}void detectPersonInROIs(cv::Mat&src,cv::HOGDescriptor &myHOG,std::vector<cv::Rect>&ROIs,std::vector<cv::Rect>&persons,std::vector<cv::Rect>&found,std::vector<cv::Rect>&found_filtered){persons.clear();found.clear(), found_filtered.clear();if(ROIs.size()==0)return ;cv::Rect r;for(auto &rect_:ROIs){cv::Mat ROI=src(rect_);found.clear(), found_filtered.clear();myHOG.detectMultiScale(ROI, found, 0, cv::Size(8,8), cv::Size(35,35), 1.05, 2);for(size_t i1=0; i1 < found.size(); i1++){r = found[i1];size_t j=0;for(; j < found.size(); j++)if(j != i1 && (r & found[j]) == r)break;if( j == found.size())found_filtered.push_back(r);}for(int i2=0; i2<found_filtered.size(); i2++){    r = found_filtered[i2];r.x =r.x+cvRound(r.width*0.1)+rect_.x;r.width = cvRound(r.width*0.8);r.y = r.y+cvRound(r.height*0.07)+rect_.y;r.height = cvRound(r.height*0.8);persons.push_back(r);}}}
虽然速率提上来了,但是,还是存在误检测的问题,而且当人运动速度比较慢的时候就检测不到了,这需要进一步的研究。




0 0