微視圖像(microview)gige相機開發手記(2)

由於在本項目中需要進行行人檢測,而直接使用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);	
		}
	}
}
雖然速率提上來了,但是,還是存在誤檢測的問題,而且當人運動速度比較慢的時候就檢測不到了,這需要進一步的研究。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章