// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html #include #include #include #include #include #include using namespace cv; using namespace std; class Detector { enum Mode { Default, Daimler } m; HOGDescriptor hog, hog_d; public: Detector() : m(Default), hog(), hog_d(Size(48, 96), Size(16, 16), Size(8, 8), Size(8, 8), 9) { hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); hog_d.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector()); } void toggleMode() { m = (m == Default ? Daimler : Default); } string modeName() const { return (m == Default ? "Default" : "Daimler"); } vector detect(InputArray img) { // Run the detector with default parameters. to get a higher hit-rate // (and more false alarms, respectively), decrease the hitThreshold and // groupThreshold (set groupThreshold to 0 to turn off the grouping completely). vector found; if (m == Default) hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2, false); else if (m == Daimler) hog_d.detectMultiScale(img, found, 0.5, Size(8,8), Size(32,32), 1.05, 2, true); return found; } void adjustRect(Rect & r) const { // The HOG detector returns slightly larger rectangles than the real objects, // 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.8); } }; static const string keys = "{ help h | | print help message }" "{ camera c | 0 | capture video from camera (device index starting from 0) }" "{ video v | | use video as input }"; int main(int argc, char** argv) { CommandLineParser parser(argc, argv, keys); parser.about("This sample demonstrates the use ot the HoG descriptor."); if (parser.has("help")) { parser.printMessage(); return 0; } int camera = parser.get("camera"); string file = parser.get("video"); if (!parser.check()) { parser.printErrors(); return 1; } VideoCapture cap; if (file.empty()) cap.open(camera); else { file = samples::findFileOrKeep(file); cap.open(file); } if (!cap.isOpened()) { cout << "Can not open video stream: '" << (file.empty() ? "" : file) << "'" << endl; return 2; } cout << "Press 'q' or to quit." << endl; cout << "Press to toggle between Default and Daimler detector" << endl; Detector detector; Mat frame; for (;;) { cap >> frame; if (frame.empty()) { cout << "Finished reading: empty frame" << endl; break; } int64 t = getTickCount(); vector found = detector.detect(frame); t = getTickCount() - t; // show the window { ostringstream buf; buf << "Mode: " << detector.modeName() << " ||| " << "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t); putText(frame, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA); } for (vector::iterator i = found.begin(); i != found.end(); ++i) { Rect &r = *i; detector.adjustRect(r); rectangle(frame, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2); } imshow("People detector", frame); // interact with user const char key = (char)waitKey(30); if (key == 27 || key == 'q') // ESC { cout << "Exit requested" << endl; break; } else if (key == ' ') { detector.toggleMode(); } } return 0; }