您的位置:首页 > 编程语言 > C语言/C++

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

2016-06-15 16:01 344 查看
由于在本项目中需要进行行人检测,而直接使用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 0
std::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);
#endif
cv::HOGDescriptor myHOG;
loadDetector(myHOG);
std::vector<cv::Rect> found, found_filtered;
cv::Rect r;

while(1){
cam>>frame;

#if 0
mog(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();
#endif
mog(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);
}
}
}虽然速率提上来了,但是,还是存在误检测的问题,而且当人运动速度比较慢的时候就检测不到了,这需要进一步的研究。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息