欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv视频行人检测2(HOG+SVM)

程序员文章站 2023-12-30 10:47:28
...
//===========================================================
/*
先用VideoCapture读取视频,然后在图片中获取一帧的图片,
对这张图片进行行人检测,再画矩形框。
最后设置一个循环,不断地从视频中获取图片。
行人检测,不太准确。而且因为检测每一帧的图片,所以不能实时检测,有卡顿
opencv2.4+vs2017
使用别人的xml文件(xml是opencv2的,所以用opencv3调用它就出错。)
*/
//===========================================================
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp> 
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/objdetect.hpp> 
#include<iostream>

using namespace std;
using namespace cv;

//定义分类器,加载xml文件
CascadeClassifier faceCascade;

//定义一个方法detectAndDraw,两个参数faceCascade和img
void detectAndDraw(CascadeClassifier &faceCascade, Mat &img)
{
	//矩形框数组
	vector<Rect> found, found_filtered;
	//调用GetTickCount()函数返回(retrieve)从操作系统启动所经过(elapsed)的毫秒数(可以不要)
	double t = (double)getTickCount();
	//多尺度检测目标,返回的矩形从大到小排列
	faceCascade.detectMultiScale(img, found, 1.1, 2, 0
		//|CASCADE_FIND_BIGGEST_OBJECT
		//|CASCADE_DO_ROUGH_SEARCH
		| CASCADE_SCALE_IMAGE,
		Size(30, 30));
	//每测一次的毫秒数
	t = (double)getTickCount() - t;
	//输出getTickFrequency()函数:返回每秒的计时周期数
	//cout << "detection time = " << (t*1000. / cv::getTickFrequency()) << " ms" << endl;
	//cout << "detection result = " << found.size() << " Rects" << endl;
	// 找出所有没有嵌套的矩形框r,并放入found_filtered中,如果有嵌套的话,则取外面最大的那个矩形框放入found_filtered中
	for (int i = 0; i < found.size(); i++)
	{
		Rect r = found[i];
		int j = 0;
		for (; 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 (int i = 0; i<found_filtered.size(); i++)
	{
		Rect r = found[i];
		rectangle(img, r.tl(), r.br(), Scalar(0, 255, 0), 3);
	}
}


int main(int argc, char **argv)
{
	//HOG特征检测器  
	//HOGDescriptor hog;
	//设置分类器
	//hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

	//faceCascade.load("D://XR//cascades.xml");
	faceCascade.load("D://XR//hogcascade_pedestrians.xml");
	
	//通过VideoCaptrue类对视频进行读取操作以及调用摄像头										   
	VideoCapture vc;

	Mat frame;
	//加载视频
	//vc.open("D:\\XR\\xingren.avi");
	vc.open("D:\\XR\\test.avi");
	//如果打不开视频,则。。。。
	if (!vc.isOpened())
		throw runtime_error(string("can't open video file: "));
	//
	while (1)
	{
		vc >> frame;//等价于vc.read(frame);从视频中获取图片
		if (frame.empty()) //如果某帧为空则退出循环
			break;
		//调用detectAndDraw()函数,并传参
		detectAndDraw(faceCascade, frame);
		//创建窗口,显示结果图片
		namedWindow("frame",0);
		resizeWindow("frame", 960, 540);
		imshow("frame", frame);

		//这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下键,则接续等待(循环)
		int c = waitKey(vc.isOpened() ? 30 : 0) & 255;
		if (c == 'q' || c == 'Q' || c == 27)
			break;
		//waitKey(0);//每帧延时20毫秒

		/*while (waitKey(10) != 27);
		destroyWindow("frame");*/
	}
	//vc.release();//释放资源
	return 0;
}

xml文件和视频文件都提供给大家,可以自己试试。

 

上一篇:

下一篇: