Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/tapi/hog.cpp
16337 views
1
#include <iostream>
2
#include <fstream>
3
#include <string>
4
#include <sstream>
5
#include <iomanip>
6
#include <stdexcept>
7
#include <opencv2/core/ocl.hpp>
8
#include <opencv2/core/utility.hpp>
9
#include "opencv2/imgcodecs.hpp"
10
#include <opencv2/video.hpp>
11
#include <opencv2/videoio.hpp>
12
#include <opencv2/highgui.hpp>
13
#include <opencv2/objdetect.hpp>
14
#include <opencv2/imgproc.hpp>
15
16
using namespace std;
17
using namespace cv;
18
19
class App
20
{
21
public:
22
App(CommandLineParser& cmd);
23
void run();
24
void handleKey(char key);
25
void hogWorkBegin();
26
void hogWorkEnd();
27
string hogWorkFps() const;
28
void workBegin();
29
void workEnd();
30
string workFps() const;
31
private:
32
App operator=(App&);
33
34
//Args args;
35
bool running;
36
bool make_gray;
37
double scale;
38
double resize_scale;
39
int win_width;
40
int win_stride_width, win_stride_height;
41
int gr_threshold;
42
int nlevels;
43
double hit_threshold;
44
bool gamma_corr;
45
46
int64 hog_work_begin;
47
double hog_work_fps;
48
int64 work_begin;
49
double work_fps;
50
51
string img_source;
52
string vdo_source;
53
string output;
54
int camera_id;
55
bool write_once;
56
};
57
58
int main(int argc, char** argv)
59
{
60
const char* keys =
61
"{ h help | | print help message }"
62
"{ i input | | specify input image}"
63
"{ c camera | -1 | enable camera capturing }"
64
"{ v video | ../data/vtest.avi | use video as input }"
65
"{ g gray | | convert image to gray one or not}"
66
"{ s scale | 1.0 | resize the image before detect}"
67
"{ o output | output.avi | specify output path when input is images}";
68
CommandLineParser cmd(argc, argv, keys);
69
if (cmd.has("help"))
70
{
71
cmd.printMessage();
72
return EXIT_SUCCESS;
73
}
74
75
App app(cmd);
76
try
77
{
78
app.run();
79
}
80
catch (const Exception& e)
81
{
82
return cout << "error: " << e.what() << endl, 1;
83
}
84
catch (const exception& e)
85
{
86
return cout << "error: " << e.what() << endl, 1;
87
}
88
catch(...)
89
{
90
return cout << "unknown exception" << endl, 1;
91
}
92
return EXIT_SUCCESS;
93
}
94
95
App::App(CommandLineParser& cmd)
96
{
97
cout << "\nControls:\n"
98
<< "\tESC - exit\n"
99
<< "\tm - change mode GPU <-> CPU\n"
100
<< "\tg - convert image to gray or not\n"
101
<< "\to - save output image once, or switch on/off video save\n"
102
<< "\t1/q - increase/decrease HOG scale\n"
103
<< "\t2/w - increase/decrease levels count\n"
104
<< "\t3/e - increase/decrease HOG group threshold\n"
105
<< "\t4/r - increase/decrease hit threshold\n"
106
<< endl;
107
108
make_gray = cmd.has("gray");
109
resize_scale = cmd.get<double>("s");
110
vdo_source = cmd.get<string>("v");
111
img_source = cmd.get<string>("i");
112
output = cmd.get<string>("o");
113
camera_id = cmd.get<int>("c");
114
115
win_width = 48;
116
win_stride_width = 8;
117
win_stride_height = 8;
118
gr_threshold = 8;
119
nlevels = 13;
120
hit_threshold = 1.4;
121
scale = 1.05;
122
gamma_corr = true;
123
write_once = false;
124
125
cout << "Group threshold: " << gr_threshold << endl;
126
cout << "Levels number: " << nlevels << endl;
127
cout << "Win width: " << win_width << endl;
128
cout << "Win stride: (" << win_stride_width << ", " << win_stride_height << ")\n";
129
cout << "Hit threshold: " << hit_threshold << endl;
130
cout << "Gamma correction: " << gamma_corr << endl;
131
cout << endl;
132
}
133
134
void App::run()
135
{
136
running = true;
137
VideoWriter video_writer;
138
139
Size win_size(win_width, win_width * 2);
140
Size win_stride(win_stride_width, win_stride_height);
141
142
// Create HOG descriptors and detectors here
143
144
HOGDescriptor hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9, 1, -1,
145
HOGDescriptor::L2Hys, 0.2, gamma_corr, cv::HOGDescriptor::DEFAULT_NLEVELS);
146
hog.setSVMDetector( HOGDescriptor::getDaimlerPeopleDetector() );
147
148
while (running)
149
{
150
VideoCapture vc;
151
UMat frame;
152
153
if (vdo_source!="")
154
{
155
vc.open(vdo_source.c_str());
156
if (!vc.isOpened())
157
throw runtime_error(string("can't open video file: " + vdo_source));
158
vc >> frame;
159
}
160
else if (camera_id != -1)
161
{
162
vc.open(camera_id);
163
if (!vc.isOpened())
164
{
165
stringstream msg;
166
msg << "can't open camera: " << camera_id;
167
throw runtime_error(msg.str());
168
}
169
vc >> frame;
170
}
171
else
172
{
173
imread(img_source).copyTo(frame);
174
if (frame.empty())
175
throw runtime_error(string("can't open image file: " + img_source));
176
}
177
178
UMat img_aux, img, img_to_show;
179
180
// Iterate over all frames
181
while (running && !frame.empty())
182
{
183
workBegin();
184
185
// Change format of the image
186
if (make_gray) cvtColor(frame, img_aux, COLOR_BGR2GRAY );
187
else frame.copyTo(img_aux);
188
189
// Resize image
190
if (abs(scale-1.0)>0.001)
191
{
192
Size sz((int)((double)img_aux.cols/resize_scale), (int)((double)img_aux.rows/resize_scale));
193
resize(img_aux, img, sz, 0, 0, INTER_LINEAR_EXACT);
194
}
195
else img = img_aux;
196
img.copyTo(img_to_show);
197
hog.nlevels = nlevels;
198
vector<Rect> found;
199
200
// Perform HOG classification
201
hogWorkBegin();
202
203
hog.detectMultiScale(img, found, hit_threshold, win_stride,
204
Size(0, 0), scale, gr_threshold);
205
hogWorkEnd();
206
207
208
// Draw positive classified windows
209
for (size_t i = 0; i < found.size(); i++)
210
{
211
rectangle(img_to_show, found[i], Scalar(0, 255, 0), 3);
212
}
213
214
putText(img_to_show, ocl::useOpenCL() ? "Mode: OpenCL" : "Mode: CPU", Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);
215
putText(img_to_show, "FPS (HOG only): " + hogWorkFps(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);
216
putText(img_to_show, "FPS (total): " + workFps(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);
217
imshow("opencv_hog", img_to_show);
218
if (vdo_source!="" || camera_id!=-1) vc >> frame;
219
220
workEnd();
221
222
if (output!="" && write_once)
223
{
224
if (img_source!="") // write image
225
{
226
write_once = false;
227
imwrite(output, img_to_show);
228
}
229
else //write video
230
{
231
if (!video_writer.isOpened())
232
{
233
video_writer.open(output, VideoWriter::fourcc('x','v','i','d'), 24,
234
img_to_show.size(), true);
235
if (!video_writer.isOpened())
236
throw std::runtime_error("can't create video writer");
237
}
238
239
if (make_gray) cvtColor(img_to_show, img, COLOR_GRAY2BGR);
240
else cvtColor(img_to_show, img, COLOR_BGRA2BGR);
241
242
video_writer << img;
243
}
244
}
245
246
handleKey((char)waitKey(3));
247
}
248
}
249
}
250
251
void App::handleKey(char key)
252
{
253
switch (key)
254
{
255
case 27:
256
running = false;
257
break;
258
case 'm':
259
case 'M':
260
ocl::setUseOpenCL(!cv::ocl::useOpenCL());
261
cout << "Switched to " << (ocl::useOpenCL() ? "OpenCL enabled" : "CPU") << " mode\n";
262
break;
263
case 'g':
264
case 'G':
265
make_gray = !make_gray;
266
cout << "Convert image to gray: " << (make_gray ? "YES" : "NO") << endl;
267
break;
268
case '1':
269
scale *= 1.05;
270
cout << "Scale: " << scale << endl;
271
break;
272
case 'q':
273
case 'Q':
274
scale /= 1.05;
275
cout << "Scale: " << scale << endl;
276
break;
277
case '2':
278
nlevels++;
279
cout << "Levels number: " << nlevels << endl;
280
break;
281
case 'w':
282
case 'W':
283
nlevels = max(nlevels - 1, 1);
284
cout << "Levels number: " << nlevels << endl;
285
break;
286
case '3':
287
gr_threshold++;
288
cout << "Group threshold: " << gr_threshold << endl;
289
break;
290
case 'e':
291
case 'E':
292
gr_threshold = max(0, gr_threshold - 1);
293
cout << "Group threshold: " << gr_threshold << endl;
294
break;
295
case '4':
296
hit_threshold+=0.25;
297
cout << "Hit threshold: " << hit_threshold << endl;
298
break;
299
case 'r':
300
case 'R':
301
hit_threshold = max(0.0, hit_threshold - 0.25);
302
cout << "Hit threshold: " << hit_threshold << endl;
303
break;
304
case 'c':
305
case 'C':
306
gamma_corr = !gamma_corr;
307
cout << "Gamma correction: " << gamma_corr << endl;
308
break;
309
case 'o':
310
case 'O':
311
write_once = !write_once;
312
break;
313
}
314
}
315
316
317
inline void App::hogWorkBegin()
318
{
319
hog_work_begin = getTickCount();
320
}
321
322
inline void App::hogWorkEnd()
323
{
324
int64 delta = getTickCount() - hog_work_begin;
325
double freq = getTickFrequency();
326
hog_work_fps = freq / delta;
327
}
328
329
inline string App::hogWorkFps() const
330
{
331
stringstream ss;
332
ss << hog_work_fps;
333
return ss.str();
334
}
335
336
inline void App::workBegin()
337
{
338
work_begin = getTickCount();
339
}
340
341
inline void App::workEnd()
342
{
343
int64 delta = getTickCount() - work_begin;
344
double freq = getTickFrequency();
345
work_fps = freq / delta;
346
}
347
348
inline string App::workFps() const
349
{
350
stringstream ss;
351
ss << work_fps;
352
return ss.str();
353
}
354
355