forked from opencv/opencv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpeopledetect.cpp
179 lines (146 loc) · 6.17 KB
/
peopledetect.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/softcascade.hpp>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
void filter_rects(const std::vector<cv::Rect>& candidates, std::vector<cv::Rect>& objects);
int main(int argc, char** argv)
{
const std::string keys =
"{help h usage ? | | print this message and exit }"
"{cascade c | | path to cascade xml, if empty HOG detector will be executed }"
"{frame f | | wildchart pattern to frame source}"
"{min_scale |0.4 | minimum scale to detect }"
"{max_scale |5.0 | maxamum scale to detect }"
"{total_scales |55 | prefered number of scales between min and max }"
"{write_file wf |0 | write to .txt. Disabled by default.}"
"{write_image wi |0 | write to image. Disabled by default.}"
"{show_image si |1 | show image. Enabled by default.}"
"{threshold thr |-1 | detection threshold. Detections with score less then threshold will be ignored.}"
;
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Soft cascade training application.");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
if (!parser.check())
{
parser.printErrors();
return 1;
}
int wf = parser.get<int>("write_file");
if (wf) std::cout << "resulte will be stored to .txt file with the same name as image." << std::endl;
int wi = parser.get<int>("write_image");
if (wi) std::cout << "resulte will be stored to image with the same name as input plus dt." << std::endl;
int si = parser.get<int>("show_image");
float minScale = parser.get<float>("min_scale");
float maxScale = parser.get<float>("max_scale");
int scales = parser.get<int>("total_scales");
int thr = parser.get<int>("threshold");
cv::HOGDescriptor hog;
cv::softcascade::Detector cascade;
bool useHOG = false;
std::string cascadePath = parser.get<std::string>("cascade");
if (cascadePath.empty())
{
useHOG = true;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::cout << "going to use HOG detector." << std::endl;
}
else
{
cv::FileStorage fs(cascadePath, cv::FileStorage::READ);
if( !fs.isOpened())
{
std::cout << "Soft Cascade file " << cascadePath << " can't be opened." << std::endl << std::flush;
return 1;
}
cascade = cv::softcascade::Detector(minScale, maxScale, scales, cv::softcascade::Detector::DOLLAR);
if (!cascade.load(fs.getFirstTopLevelNode()))
{
std::cout << "Soft Cascade can't be parsed." << std::endl << std::flush;
return 1;
}
}
std::string src = parser.get<std::string>("frame");
std::vector<std::string> frames;
cv::glob(parser.get<std::string>("frame"), frames);
std::cout << "collected " << src << " " << frames.size() << " frames." << std::endl;
for (int i = 0; i < (int)frames.size(); ++i)
{
std::string& frame_sourse = frames[i];
cv::Mat frame = cv::imread(frame_sourse);
if(frame.empty())
{
std::cout << "Frame source " << frame_sourse << " can't be opened." << std::endl << std::flush;
continue;
}
std::ofstream myfile;
if (wf)
myfile.open((frame_sourse.replace(frame_sourse.end() - 3, frame_sourse.end(), "txt")).c_str(), std::ios::out);
////
if (useHOG)
{
std::vector<cv::Rect> found, found_filtered;
// 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(frame, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2);
filter_rects(found, found_filtered);
std::cout << "collected: " << (int)found_filtered.size() << " detections." << std::endl;
for (size_t ff = 0; ff < found_filtered.size(); ++ff)
{
cv::Rect r = found_filtered[ff];
cv::rectangle(frame, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
if (wf) myfile << r.x << "," << r.y << "," << r.width << "," << r.height << "," << 0.f << "\n";
}
}
else
{
std::vector<cv::softcascade::Detection> objects;
cascade.detect(frame, cv::noArray(), objects);
std::cout << "collected: " << (int)objects.size() << " detections." << std::endl;
for (int obj = 0; obj < (int)objects.size(); ++obj)
{
cv::softcascade::Detection d = objects[obj];
if(d.confidence > thr)
{
float b = d.confidence * 1.5f;
std::stringstream conf(std::stringstream::in | std::stringstream::out);
conf << d.confidence;
cv::rectangle(frame, cv::Rect((int)d.x, (int)d.y, (int)d.w, (int)d.h), cv::Scalar(b, 0, 255 - b, 255), 2);
cv::putText(frame, conf.str() , cv::Point((int)d.x + 10, (int)d.y - 5),1, 1.1, cv::Scalar(25, 133, 255, 0), 1, CV_AA);
if (wf)
myfile << d.x << "," << d.y << "," << d.w << "," << d.h << "," << d.confidence << "\n";
}
}
}
if (wi) cv::imwrite(frame_sourse + ".dt.png", frame);
if (wf) myfile.close();
if (si)
{
cv::imshow("pedestrian detector", frame);
cv::waitKey(10);
}
}
if (si) cv::waitKey(0);
return 0;
}
void filter_rects(const std::vector<cv::Rect>& candidates, std::vector<cv::Rect>& objects)
{
size_t i, j;
for (i = 0; i < candidates.size(); ++i)
{
cv::Rect r = candidates[i];
for (j = 0; j < candidates.size(); ++j)
if (j != i && (r & candidates[j]) == r)
break;
if (j == candidates.size())
objects.push_back(r);
}
}