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