]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/blob - main_vot.cpp
eddb39f9dbedfd167dd4310c1c54c604f9b26e5b
[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[] = {
45             {"debug",     no_argument,       0,  'd' },
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
53         int c = getopt_long(argc, argv, "dhv::f::o:", long_options, &option_index);
54         if (c == -1)
55             break;
56
57         switch (c) {
58         case 'd':
59             tracker.m_debug = true;
60             break;
61         case 'h':
62             std::cerr << "Usage: \n"
63                       << argv[0] << " [options]\n"
64                       << argv[0] << " [options] <directory>\n"
65                       << argv[0] << " [options] <path/to/region.txt or groundtruth.txt> <path/to/images.txt> [path/to/output.txt]\n"
66                       << "Options:\n"
67                       << " --visualize | -v[delay_ms]\n"
68                       << " --output    | -o <output.txt>\n"
69                       << " --debug     | -d\n"
70                       << " --fit       | -f[WxH]\n";
71             exit(0);
72             break;
73         case 'o':
74             output = optarg;
75             break;
76         case 'v':
77             visualize_delay = optarg ? atol(optarg) : 1;
78             break;
79         case 'f':
80             if (!optarg) {
81                 fit_size_x = fit_size_y = 128;
82             } else {
83                 char tail;
84                 if (sscanf(optarg, "%d%c", &fit_size_x, &tail) == 1) {
85                     fit_size_y = fit_size_x;
86                 } else if (sscanf(optarg, "%dx%d%c", &fit_size_x, &fit_size_y, &tail) != 2) {
87                     fprintf(stderr, "Cannot parse -f argument: %s\n", optarg);
88                     return 1;
89                 }
90             }
91             int min_size = 2 * tracker.p_cell_size;
92             if (fit_size_x <  min_size || fit_size_x < min_size) {
93                 fprintf(stderr, "Fit size %dx%d too small. Minimum is %dx%d.\n",
94                         fit_size_x, fit_size_y, min_size, min_size);
95                 return 1;
96             }
97             break;
98         }
99     }
100
101     switch (argc - optind) {
102     case 1:
103         if (chdir(argv[optind]) == -1) {
104             perror(argv[optind]);
105             exit(1);
106         }
107         // Fall through
108     case 0:
109         region = access("groundtruth.txt", F_OK) == 0 ? "groundtruth.txt" : "region.txt";
110         images = "images.txt";
111         if (output.empty())
112             output = "output.txt";
113         break;
114     case 2:
115         // Fall through
116     case 3:
117         region = std::string(argv[optind + 0]);
118         images = std::string(argv[optind + 1]);
119         if (output.empty()) {
120             if ((argc - optind) == 3)
121                 output = std::string(argv[optind + 2]);
122             else
123                 output = std::string(dirname(argv[optind + 0])) + "/output.txt";
124         }
125         break;
126     default:
127         std::cerr << "Too many arguments\n";
128         return 1;
129     }
130     VOT vot_io(region, images, output);
131
132     // if groundtruth.txt is used use intersection over union (IOU) to calculate tracker accuracy
133     std::ifstream groundtruth_stream;
134     if (region.compare("groundtruth.txt") == 0) {
135         groundtruth_stream.open(region.c_str());
136         std::string line;
137         std::getline(groundtruth_stream, line);
138     }
139
140     cv::Mat image;
141
142     //img = firts frame, initPos = initial position in the first frame
143     cv::Rect init_rect = vot_io.getInitRectangle();
144     vot_io.outputBoundingBox(init_rect);
145     vot_io.getNextImage(image);
146
147     tracker.init(image, init_rect, fit_size_x, fit_size_y);
148
149     BBox_c bb;
150     cv::Rect bb_rect;
151     double avg_time = 0., sum_accuracy = 0.;
152     int frames = 0;
153
154     std::cout << std::fixed << std::setprecision(2);
155
156     while (vot_io.getNextImage(image) == 1){
157         double time_profile_counter = cv::getCPUTickCount();
158         tracker.track(image);
159         time_profile_counter = cv::getCPUTickCount() - time_profile_counter;
160          std::cout << "  -> speed : " <<  time_profile_counter/((double)cvGetTickFrequency()*1000) << "ms per frame, "
161                       "response : " << tracker.getFilterResponse();
162         avg_time += time_profile_counter/((double)cvGetTickFrequency()*1000);
163         frames++;
164
165         bb = tracker.getBBox();
166         bb_rect = cv::Rect(bb.cx - bb.w/2., bb.cy - bb.h/2., bb.w, bb.h);
167         vot_io.outputBoundingBox(bb_rect);
168
169         if (groundtruth_stream.is_open()) {
170             std::string line;
171             std::getline(groundtruth_stream, line);
172
173             cv::Rect groundtruthRect;
174             double accuracy = calcAccuracy(line, bb_rect, groundtruthRect);
175             if (visualize_delay >= 0)
176                 cv::rectangle(image, groundtruthRect, CV_RGB(255, 0,0), 1);
177             std::cout << ", accuracy: " << accuracy;
178             sum_accuracy += accuracy;
179         }
180
181         std::cout << std::endl;
182
183         if (visualize_delay >= 0) {
184             cv::rectangle(image, bb_rect, CV_RGB(0,255,0), 2);
185             cv::imshow("output", image);
186             int ret = cv::waitKey(visualize_delay);
187             if (visualize_delay > 0 && ret != -1 && ret < 128)
188                 break;
189         }
190
191 //        std::stringstream s;
192 //        std::string ss;
193 //        int countTmp = frames;
194 //        s << "imgs" << "/img" << (countTmp/10000);
195 //        countTmp = countTmp%10000;
196 //        s << (countTmp/1000);
197 //        countTmp = countTmp%1000;
198 //        s << (countTmp/100);
199 //        countTmp = countTmp%100;
200 //        s << (countTmp/10);
201 //        countTmp = countTmp%10;
202 //        s << (countTmp);
203 //        s << ".jpg";
204 //        s >> ss;
205 //        //set image output parameters
206 //        std::vector<int> compression_params;
207 //        compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
208 //        compression_params.push_back(90);
209 //        cv::imwrite(ss.c_str(), image, compression_params);
210     }
211
212     std::cout << "Average processing speed: " << avg_time / frames << "ms (" << 1. / (avg_time / frames) * 1000 << " fps)";
213     if (groundtruth_stream.is_open()) {
214         std::cout << "; Average accuracy: " << sum_accuracy/frames << std::endl;
215         groundtruth_stream.close();
216     }
217     std::cout << std::endl;
218
219     return EXIT_SUCCESS;
220 }