【行人检测】检测视频中的行人
在上一节检测图片中的行人的基础上,实现检测视频中的行人。
完整程序:
// 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 -------------------------------------