forked from opencv/opencv
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request opencv#10999 from mshabunin:do-more-samples
- Loading branch information
Showing
7 changed files
with
301 additions
and
423 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,177 +1,126 @@ | ||
#include <iostream> | ||
#include <stdexcept> | ||
// 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 <opencv2/objdetect.hpp> | ||
#include <opencv2/highgui.hpp> | ||
#include <opencv2/imgproc.hpp> | ||
#include <opencv2/imgcodecs.hpp> | ||
#include <opencv2/video.hpp> | ||
#include <opencv2/videoio.hpp> | ||
#include <iostream> | ||
#include <iomanip> | ||
|
||
using namespace cv; | ||
using namespace std; | ||
|
||
|
||
const char* keys = | ||
class Detector | ||
{ | ||
"{ help h | | print help message }" | ||
"{ image i | | specify input image}" | ||
"{ camera c | | enable camera capturing }" | ||
"{ video v | ../data/vtest.avi | use video as input }" | ||
"{ directory d | | images directory}" | ||
}; | ||
|
||
static void detectAndDraw(const HOGDescriptor &hog, Mat &img) | ||
{ | ||
vector<Rect> found, found_filtered; | ||
double t = (double) getTickCount(); | ||
// 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). | ||
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; | ||
|
||
for(size_t i = 0; i < found.size(); i++ ) | ||
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) | ||
{ | ||
Rect r = found[i]; | ||
|
||
size_t j; | ||
// Do not add small detections inside a bigger detection. | ||
for ( j = 0; j < found.size(); j++ ) | ||
if ( j != i && (r & found[j]) == r ) | ||
break; | ||
|
||
if ( j == found.size() ) | ||
found_filtered.push_back(r); | ||
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); | ||
hog_d.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector()); | ||
} | ||
|
||
for (size_t i = 0; i < found_filtered.size(); i++) | ||
void toggleMode() { m = (m == Default ? Daimler : Default); } | ||
string modeName() const { return (m == Default ? "Default" : "Daimler"); } | ||
vector<Rect> 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<Rect> 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 | ||
{ | ||
Rect r = found_filtered[i]; | ||
|
||
// 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); | ||
rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3); | ||
} | ||
} | ||
}; | ||
|
||
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")) | ||
{ | ||
cout << "\nThis program demonstrates the use of the HoG descriptor using\n" | ||
" HOGDescriptor::hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());\n"; | ||
parser.printMessage(); | ||
cout << "During execution:\n\tHit q or ESC key to quit.\n" | ||
"\tUsing OpenCV version " << CV_VERSION << "\n" | ||
"Note: camera device number must be different from -1.\n" << endl; | ||
return 0; | ||
} | ||
|
||
HOGDescriptor hog; | ||
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); | ||
namedWindow("people detector", 1); | ||
|
||
string pattern_glob = ""; | ||
string video_filename = "../data/vtest.avi"; | ||
int camera_id = -1; | ||
if (parser.has("directory")) | ||
int camera = parser.get<int>("camera"); | ||
string file = parser.get<string>("video"); | ||
if (!parser.check()) | ||
{ | ||
pattern_glob = parser.get<string>("directory"); | ||
parser.printErrors(); | ||
return 1; | ||
} | ||
else if (parser.has("image")) | ||
{ | ||
pattern_glob = parser.get<string>("image"); | ||
} | ||
else if (parser.has("camera")) | ||
{ | ||
camera_id = parser.get<int>("camera"); | ||
} | ||
else if (parser.has("video")) | ||
|
||
VideoCapture cap; | ||
if (file.empty()) | ||
cap.open(camera); | ||
else | ||
cap.open(file.c_str()); | ||
if (!cap.isOpened()) | ||
{ | ||
video_filename = parser.get<string>("video"); | ||
cout << "Can not open video stream: '" << (file.empty() ? "<camera>" : file) << "'" << endl; | ||
return 2; | ||
} | ||
|
||
if (!pattern_glob.empty() || camera_id != -1 || !video_filename.empty()) | ||
cout << "Press 'q' or <ESC> to quit." << endl; | ||
cout << "Press <space> to toggle between Default and Daimler detector" << endl; | ||
Detector detector; | ||
Mat frame; | ||
for (;;) | ||
{ | ||
//Read from input image files | ||
vector<String> filenames; | ||
//Read from video file | ||
VideoCapture vc; | ||
Mat frame; | ||
|
||
if (!pattern_glob.empty()) | ||
cap >> frame; | ||
if (frame.empty()) | ||
{ | ||
String folder(pattern_glob); | ||
glob(folder, filenames); | ||
cout << "Finished reading: empty frame" << endl; | ||
break; | ||
} | ||
else if (camera_id != -1) | ||
int64 t = getTickCount(); | ||
vector<Rect> found = detector.detect(frame); | ||
t = getTickCount() - t; | ||
|
||
// show the window | ||
{ | ||
vc.open(camera_id); | ||
if (!vc.isOpened()) | ||
{ | ||
stringstream msg; | ||
msg << "can't open camera: " << camera_id; | ||
throw runtime_error(msg.str()); | ||
} | ||
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); | ||
} | ||
else | ||
for (vector<Rect>::iterator i = found.begin(); i != found.end(); ++i) | ||
{ | ||
vc.open(video_filename.c_str()); | ||
if (!vc.isOpened()) | ||
throw runtime_error(string("can't open video file: " + video_filename)); | ||
Rect &r = *i; | ||
detector.adjustRect(r); | ||
rectangle(frame, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2); | ||
} | ||
imshow("People detector", frame); | ||
|
||
vector<String>::const_iterator it_image = filenames.begin(); | ||
|
||
for (;;) | ||
// interact with user | ||
const char key = (char)waitKey(30); | ||
if (key == 27 || key == 'q') // ESC | ||
{ | ||
if (!pattern_glob.empty()) | ||
{ | ||
bool read_image_ok = false; | ||
for (; it_image != filenames.end(); ++it_image) | ||
{ | ||
cout << "\nRead: " << *it_image << endl; | ||
// Read current image | ||
frame = imread(*it_image); | ||
|
||
if (!frame.empty()) | ||
{ | ||
++it_image; | ||
read_image_ok = true; | ||
break; | ||
} | ||
} | ||
|
||
//No more valid images | ||
if (!read_image_ok) | ||
{ | ||
//Release the image in order to exit the while loop | ||
frame.release(); | ||
} | ||
} | ||
else | ||
{ | ||
vc >> frame; | ||
} | ||
|
||
if (frame.empty()) | ||
break; | ||
|
||
detectAndDraw(hog, frame); | ||
|
||
imshow("people detector", frame); | ||
int c = waitKey( vc.isOpened() ? 30 : 0 ) & 255; | ||
if ( c == 'q' || c == 'Q' || c == 27) | ||
break; | ||
cout << "Exit requested" << endl; | ||
break; | ||
} | ||
else if (key == ' ') | ||
{ | ||
detector.toggleMode(); | ||
} | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.