【行人检测】检测视频中的行人

    【行人检测】检测视频中的行人

    在上一节检测图片中的行人的基础上,实现检测视频中的行人。

完整程序:

// Hog_SVM_Pedestrian.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/objdetect.hpp> // include hog
#include<iostream>

using namespace std;
using namespace cv;



void detectAndDraw(HOGDescriptor &hog,Mat &img)
{
	vector<Rect> found, found_filtered;
	double t = (double)getTickCount();
	
	hog.detectMultiScale(img, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);//多尺度检测目标,返回的矩形从大到小排列
	t = (double)getTickCount() - t;
	cout << "detection time = " << (t*1000. / cv::getTickFrequency()) << " ms" << endl;
	cout << "detection result = " << found.size() << " Rects" << endl;

	for (size_t i = 0; i < found.size(); i++)
	{
		Rect r = found[i];

		size_t j;
		// Do not add small detections inside a bigger detection. 如果有嵌套的话,则取外面最大的那个矩形框放入found_filtered中
		for (j = 0; j < found.size(); j++)
			if (j != i && (r & found[j]) == r)
				break;

		if (j == found.size())
			found_filtered.push_back(r);
	}

	cout << "Real detection result = " << found_filtered.size() << " Rects" << endl;
	for (size_t i = 0; i < found_filtered.size(); i++)
	{
		Rect r = found_filtered[i];

		// The HOG detector returns slightly larger rectangles than the real objects,
		// hog检测结果返回的矩形比实际的要大一些
		// so we slightly shrink the rectangles to get a nicer output.
		/*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.9);*/
		rectangle(img, r.tl(), r.br(), cv::Scalar(0, 255, 0), 3);
	}

}



int main()
{
	//Mat img = imread("pedestrian.jpg");

	HOGDescriptor hog;
	hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector() ); //getDefaultPeopleDetector(): 
																	//Returns coefficients of the classifier trained for people detection (for 64x128 windows).
	string video_filename = "vtest.avi";
	VideoCapture vc;
	Mat frame;
	vc.open(video_filename.c_str());//为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式
	if (!vc.isOpened())
		throw runtime_error(string("can't open video file: " + video_filename));

	for (;;)
	{
		vc >> frame;
		if (frame.empty()) break;
		
		detectAndDraw(hog, frame);
		namedWindow("frame");
		imshow("frame", frame);

		int c = waitKey(vc.isOpened() ? 30 : 0) & 255;
		if (c == 'q' || c == 'Q' || c == 27)
			break;


		/*while (waitKey(10) != 27);
		destroyWindow("frame");*/
	}



	

    return 0;
}

运行结果:


    

    因为每一次检测要耗时3秒,所以整个视频是卡的,不连续,若要改进可以采取:以图片形式保存每一帧处理结果,然后将图片连续显示,是指看起来连续。但这只是后台处理的办法,并不能实现实时检测和显示。感兴趣的同学可以自己尝试一下,若有好的想法可实现实时动态显示,还请留言告知,非常感谢!

-------------------------------------------         END      -------------------------------------

猜你喜欢

转载自blog.csdn.net/u012679707/article/details/80661668