]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/blob - main_vot.cpp
Merge branch 'master' into rotation
[hercules2020/kcf.git] / main_vot.cpp
1 #include <stdlib.h>
2 #include <getopt.h>
3 #include <libgen.h>
4 #include <unistd.h>
5 #include <iomanip>
6
7 #include "kcf.h"
8 #include "vot.hpp"
9
10 double calcAccuracy(std::string line, cv::Rect bb_rect, cv::Rect &groundtruth_rect)
11 {
12     std::vector<float> numbers;
13     std::istringstream s(line);
14     float x;
15     char ch;
16
17     while (s >> x) {
18         numbers.push_back(x);
19         s >> ch;
20     }
21     double x1 = std::min(numbers[0], std::min(numbers[2], std::min(numbers[4], numbers[6])));
22     double x2 = std::max(numbers[0], std::max(numbers[2], std::max(numbers[4], numbers[6])));
23     double y1 = std::min(numbers[1], std::min(numbers[3], std::min(numbers[5], numbers[7])));
24     double y2 = std::max(numbers[1], std::max(numbers[3], std::max(numbers[5], numbers[7])));
25
26     groundtruth_rect = cv::Rect(x1, y1, x2 - x1, y2 - y1);
27
28     double rects_intersection = (groundtruth_rect & bb_rect).area();
29     double rects_union = (groundtruth_rect | bb_rect).area();
30     double accuracy = rects_intersection / rects_union;
31
32     return accuracy;
33 }
34
35 int main(int argc, char *argv[])
36 {
37     // load region, images and prepare for output
38     std::string region, images, output;
39     int visualize_delay = -1, fit_size_x = -1, fit_size_y = -1;
40     KCF_Tracker tracker;
41
42     while (1) {
43         int option_index = 0;
44         static struct option long_options[] = {{"debug", no_argument, 0, 'd'},
45                                                {"visualDebug", no_argument, 0, 'p'},
46                                                {"help", no_argument, 0, 'h'},
47                                                {"output", required_argument, 0, 'o'},
48                                                {"visualize", optional_argument, 0, 'v'},
49                                                {"fit", optional_argument, 0, 'f'},
50                                                {0, 0, 0, 0}};
51
52         int c = getopt_long(argc, argv, "dphv::f::o:", long_options, &option_index);
53         if (c == -1) break;
54
55         switch (c) {
56         case 'd':
57             tracker.m_debug = true;
58             break;
59         case 'p':
60             tracker.m_visual_debug = true;
61             visualize_delay = 500;
62             break;
63         case 'h':
64             std::cerr
65                 << "Usage: \n"
66                 << argv[0] << " [options]\n"
67                 << argv[0] << " [options] <directory>\n"
68                 << argv[0]
69                 << " [options] <path/to/region.txt or groundtruth.txt> <path/to/images.txt> [path/to/output.txt]\n"
70                 << "Options:\n"
71                 << " --visualize | -v[delay_ms]\n"
72                 << " --output    | -o <output.txt>\n"
73                 << " --debug     | -d\n"
74                 << " --visualDebug | -p\n"
75                 << " --fit       | -f[WxH]\n";
76             exit(0);
77             break;
78         case 'o':
79             output = optarg;
80             break;
81         case 'v':
82             visualize_delay = optarg ? atol(optarg) : 1;
83             break;
84         case 'f':
85             std::string sizes = optarg ? optarg : "128x128";
86             std::string delimiter = "x";
87             size_t pos = sizes.find(delimiter);
88             std::string first_argument = sizes.substr(0, pos);
89             sizes.erase(0, pos + delimiter.length());
90
91             fit_size_x = stol(first_argument);
92             fit_size_y = stol(sizes);
93             break;
94         }
95     }
96
97     switch (argc - optind) {
98     case 1:
99         if (chdir(argv[optind]) == -1) {
100             perror(argv[optind]);
101             exit(1);
102         }
103         // Fall through
104     case 0:
105         region = access("groundtruth.txt", F_OK) == 0 ? "groundtruth.txt" : "region.txt";
106         images = "images.txt";
107         if (output.empty()) output = "output.txt";
108         break;
109     case 2:
110         // Fall through
111     case 3:
112         region = std::string(argv[optind + 0]);
113         images = std::string(argv[optind + 1]);
114         if (output.empty()) {
115             if ((argc - optind) == 3)
116                 output = std::string(argv[optind + 2]);
117             else
118                 output = std::string(dirname(argv[optind + 0])) + "/output.txt";
119         }
120         break;
121     default:
122         std::cerr << "Too many arguments\n";
123         return 1;
124     }
125     VOT vot_io(region, images, output);
126
127     // if groundtruth.txt is used use intersection over union (IOU) to calculate tracker accuracy
128     std::ifstream groundtruth_stream;
129     if (region.compare("groundtruth.txt") == 0) {
130         groundtruth_stream.open(region.c_str());
131         std::string line;
132         std::getline(groundtruth_stream, line);
133     }
134
135     cv::Mat image;
136
137     // img = firts frame, initPos = initial position in the first frame
138     cv::Rect init_rect = vot_io.getInitRectangle();
139     vot_io.outputBoundingBox(init_rect);
140     vot_io.getNextImage(image);
141
142     tracker.init(image, init_rect, fit_size_x, fit_size_y);
143
144     BBox_c bb;
145     cv::Rect bb_rect;
146     double avg_time = 0., sum_accuracy = 0.;
147     int frames = 0;
148
149     std::cout << std::fixed << std::setprecision(2);
150
151     while (vot_io.getNextImage(image) == 1){
152         double time_profile_counter = cv::getCPUTickCount();
153         tracker.track(image);
154         time_profile_counter = cv::getCPUTickCount() - time_profile_counter;
155          std::cout << "  -> speed : " <<  time_profile_counter/((double)cvGetTickFrequency()*1000) << "ms per frame, "
156                       "response : " << tracker.getFilterResponse();
157         avg_time += time_profile_counter/((double)cvGetTickFrequency()*1000);
158         frames++;
159
160         bb = tracker.getBBox();
161         bb_rect = cv::Rect(bb.cx - bb.w / 2., bb.cy - bb.h / 2., bb.w, bb.h);
162         vot_io.outputBoundingBox(bb_rect);
163
164         if (groundtruth_stream.is_open()) {
165             std::string line;
166             std::getline(groundtruth_stream, line);
167
168             cv::Rect groundtruthRect;
169             double accuracy = calcAccuracy(line, bb_rect, groundtruthRect);
170             if (visualize_delay >= 0) cv::rectangle(image, groundtruthRect, CV_RGB(255, 0, 0), 1);
171             std::cout << ", accuracy: " << accuracy;
172             sum_accuracy += accuracy;
173         }
174
175         std::cout << std::endl;
176
177         if (visualize_delay >= 0) {
178             cv::Point pt(bb.cx, bb.cy);
179             cv::Size size(bb.w, bb.h);
180             cv::RotatedRect rotatedRectangle(pt, size, bb.a);
181
182             cv::Point2f vertices[4];
183             rotatedRectangle.points(vertices);
184
185             for (int i = 0; i < 4; i++)
186                 cv::line(image, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 2);
187             //             cv::rectangle(image, cv::Rect(bb.cx - bb.w/2., bb.cy - bb.h/2., bb.w, bb.h), CV_RGB(0,255,0),
188             //             2);
189             std::string angle = std::to_string(bb.a);
190             angle.erase(angle.find_last_not_of('0') + 1, std::string::npos);
191             angle.erase(angle.find_last_not_of('.') + 1, std::string::npos);
192             cv::putText(image, "Frame: " + std::to_string(frames) + " " + angle + " angle",
193                         cv::Point(0, image.rows - 1), cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 255, 0), 2);
194             cv::imshow("output", image);
195             int ret = cv::waitKey(visualize_delay);
196             if (visualize_delay > 0 && ret != -1 && ret != 255) break;
197         }
198
199         //        std::stringstream s;
200         //        std::string ss;
201         //        int countTmp = frames;
202         //        s << "imgs" << "/img" << (countTmp/10000);
203         //        countTmp = countTmp%10000;
204         //        s << (countTmp/1000);
205         //        countTmp = countTmp%1000;
206         //        s << (countTmp/100);
207         //        countTmp = countTmp%100;
208         //        s << (countTmp/10);
209         //        countTmp = countTmp%10;
210         //        s << (countTmp);
211         //        s << ".jpg";
212         //        s >> ss;
213         //        //set image output parameters
214         //        std::vector<int> compression_params;
215         //        compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
216         //        compression_params.push_back(90);
217         //        cv::imwrite(ss.c_str(), image, compression_params);
218     }
219
220     std::cout << "Average processing speed: " << avg_time / frames << "ms (" << 1. / (avg_time / frames) * 1000 << " fps)";
221     if (groundtruth_stream.is_open()) {
222         std::cout << "; Average accuracy: " << sum_accuracy/frames << std::endl;
223         groundtruth_stream.close();
224     }
225     std::cout << std::endl;
226
227     return EXIT_SUCCESS;
228 }