9 double calcAccuracy(std::string line, cv::Rect bb_rect, cv::Rect &groundtruth_rect)
11 std::vector<float> numbers;
12 std::istringstream s(line);
20 double x1 = std::min(numbers[0], std::min(numbers[2], std::min(numbers[4], numbers[6])));
21 double x2 = std::max(numbers[0], std::max(numbers[2], std::max(numbers[4], numbers[6])));
22 double y1 = std::min(numbers[1], std::min(numbers[3], std::min(numbers[5], numbers[7])));
23 double y2 = std::max(numbers[1], std::max(numbers[3], std::max(numbers[5], numbers[7])));
25 groundtruth_rect = cv::Rect(x1, y1, x2 - x1, y2 - y1);
27 double rects_intersection = (groundtruth_rect & bb_rect).area();
28 double rects_union = (groundtruth_rect | bb_rect).area();
29 double accuracy = rects_intersection / rects_union;
34 int main(int argc, char *argv[])
36 // load region, images and prepare for output
37 std::string region, images, output;
38 int visualize_delay = -1, fit_size_x = -1, fit_size_y = -1;
43 static struct option long_options[] = {{"debug", no_argument, 0, 'd'},
44 {"visualDebug", no_argument, 0, 'p'},
45 {"help", no_argument, 0, 'h'},
46 {"output", required_argument, 0, 'o'},
47 {"visualize", optional_argument, 0, 'v'},
48 {"fit", optional_argument, 0, 'f'},
51 int c = getopt_long(argc, argv, "dphv::f::o:", long_options, &option_index);
56 tracker.m_debug = true;
59 tracker.m_visual_debug = true;
60 visualize_delay = 500;
65 << argv[0] << " [options]\n"
66 << argv[0] << " [options] <directory>\n"
68 << " [options] <path/to/region.txt or groundtruth.txt> <path/to/images.txt> [path/to/output.txt]\n"
70 << " --visualize | -v[delay_ms]\n"
71 << " --output | -o <output.txt>\n"
73 << " --visualDebug | -p\n"
74 << " --fit | -f[WxH]\n";
81 visualize_delay = optarg ? atol(optarg) : 1;
84 std::string sizes = optarg ? optarg : "128x128";
85 std::string delimiter = "x";
86 size_t pos = sizes.find(delimiter);
87 std::string first_argument = sizes.substr(0, pos);
88 sizes.erase(0, pos + delimiter.length());
90 fit_size_x = stol(first_argument);
91 fit_size_y = stol(sizes);
96 switch (argc - optind) {
98 if (chdir(argv[optind]) == -1) {
104 region = access("groundtruth.txt", F_OK) == 0 ? "groundtruth.txt" : "region.txt";
105 images = "images.txt";
106 if (output.empty()) output = "output.txt";
111 region = std::string(argv[optind + 0]);
112 images = std::string(argv[optind + 1]);
113 if (output.empty()) {
114 if ((argc - optind) == 3)
115 output = std::string(argv[optind + 2]);
117 output = std::string(dirname(argv[optind + 0])) + "/output.txt";
121 std::cerr << "Too many arguments\n";
124 VOT vot_io(region, images, output);
126 // if groundtruth.txt is used use intersection over union (IOU) to calculate tracker accuracy
127 std::ifstream groundtruth_stream;
128 if (region.compare("groundtruth.txt") == 0) {
129 groundtruth_stream.open(region.c_str());
131 std::getline(groundtruth_stream, line);
136 // img = firts frame, initPos = initial position in the first frame
137 cv::Rect init_rect = vot_io.getInitRectangle();
138 vot_io.outputBoundingBox(init_rect);
139 vot_io.getNextImage(image);
141 tracker.init(image, init_rect, fit_size_x, fit_size_y);
145 double avg_time = 0., sum_accuracy = 0.;
147 while (vot_io.getNextImage(image) == 1) {
148 double time_profile_counter = cv::getCPUTickCount();
149 tracker.track(image);
150 time_profile_counter = cv::getCPUTickCount() - time_profile_counter;
151 std::cout << " -> speed : " << time_profile_counter / ((double)cvGetTickFrequency() * 1000) << "ms. per frame";
152 avg_time += time_profile_counter / ((double)cvGetTickFrequency() * 1000);
155 bb = tracker.getBBox();
156 bb_rect = cv::Rect(bb.cx - bb.w / 2., bb.cy - bb.h / 2., bb.w, bb.h);
157 vot_io.outputBoundingBox(bb_rect);
159 if (groundtruth_stream.is_open()) {
161 std::getline(groundtruth_stream, line);
163 cv::Rect groundtruthRect;
164 double accuracy = calcAccuracy(line, bb_rect, groundtruthRect);
165 if (visualize_delay >= 0) cv::rectangle(image, groundtruthRect, CV_RGB(255, 0, 0), 1);
166 std::cout << ", accuracy: " << accuracy;
167 sum_accuracy += accuracy;
170 std::cout << std::endl;
172 if (visualize_delay >= 0) {
173 cv::Point pt(bb.cx, bb.cy);
174 cv::Size size(bb.w, bb.h);
175 cv::RotatedRect rotatedRectangle(pt, size, bb.a);
177 cv::Point2f vertices[4];
178 rotatedRectangle.points(vertices);
180 for (int i = 0; i < 4; i++)
181 cv::line(image, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 2);
182 // cv::rectangle(image, cv::Rect(bb.cx - bb.w/2., bb.cy - bb.h/2., bb.w, bb.h), CV_RGB(0,255,0),
184 std::string angle = std::to_string(bb.a);
185 angle.erase(angle.find_last_not_of('0') + 1, std::string::npos);
186 angle.erase(angle.find_last_not_of('.') + 1, std::string::npos);
187 cv::putText(image, "Frame: " + std::to_string(frames) + " " + angle + " angle",
188 cv::Point(0, image.rows - 1), cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 255, 0), 2);
189 cv::imshow("output", image);
190 int ret = cv::waitKey(visualize_delay);
191 if (visualize_delay > 0 && ret != -1 && ret != 255) break;
194 // std::stringstream s;
196 // int countTmp = frames;
197 // s << "imgs" << "/img" << (countTmp/10000);
198 // countTmp = countTmp%10000;
199 // s << (countTmp/1000);
200 // countTmp = countTmp%1000;
201 // s << (countTmp/100);
202 // countTmp = countTmp%100;
203 // s << (countTmp/10);
204 // countTmp = countTmp%10;
208 // //set image output parameters
209 // std::vector<int> compression_params;
210 // compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
211 // compression_params.push_back(90);
212 // cv::imwrite(ss.c_str(), image, compression_params);
215 std::cout << "Average processing speed " << avg_time / frames << "ms. (" << 1. / (avg_time / frames) * 1000
216 << " fps)" << std::endl;
217 if (groundtruth_stream.is_open()) {
218 std::cout << "Average accuracy: " << sum_accuracy / frames << std::endl;
219 groundtruth_stream.close();