]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/blobdiff - main_vot.cpp
Prepare for rotation branch merge
[hercules2020/kcf.git] / main_vot.cpp
index fd4632119065ed65e414f0ecf16d317e03cbc7d8..3a846e86af00aa4999de8d8c4e904781596c6f97 100644 (file)
@@ -2,15 +2,41 @@
 #include <getopt.h>
 #include <libgen.h>
 #include <unistd.h>
+#include <iomanip>
 
 #include "kcf.h"
 #include "vot.hpp"
 
+double calcAccuracy(std::string line, cv::Rect bb_rect, cv::Rect &groundtruth_rect)
+{
+    std::vector<float> numbers;
+    std::istringstream s(line);
+    float x;
+    char ch;
+
+    while (s >> x) {
+        numbers.push_back(x);
+        s >> ch;
+    }
+    double x1 = std::min(numbers[0], std::min(numbers[2], std::min(numbers[4], numbers[6])));
+    double x2 = std::max(numbers[0], std::max(numbers[2], std::max(numbers[4], numbers[6])));
+    double y1 = std::min(numbers[1], std::min(numbers[3], std::min(numbers[5], numbers[7])));
+    double y2 = std::max(numbers[1], std::max(numbers[3], std::max(numbers[5], numbers[7])));
+
+    groundtruth_rect = cv::Rect(x1, y1, x2 - x1, y2 - y1);
+
+    double rects_intersection = (groundtruth_rect & bb_rect).area();
+    double rects_union = (groundtruth_rect | bb_rect).area();
+    double accuracy = rects_intersection / rects_union;
+
+    return accuracy;
+}
+
 int main(int argc, char *argv[])
 {
     //load region, images and prepare for output
     std::string region, images, output;
-    int visualize_delay = -1, fit_size = -1;
+    int visualize_delay = -1, fit_size_x = -1, fit_size_y = -1;
     KCF_Tracker tracker;
 
     while (1) {
@@ -24,8 +50,7 @@ int main(int argc, char *argv[])
             {0,           0,                 0,  0 }
         };
 
-        int c = getopt_long(argc, argv, "dhv::o:f:",
-                        long_options, &option_index);
+        int c = getopt_long(argc, argv, "dhv::f::o:", long_options, &option_index);
         if (c == -1)
             break;
 
@@ -39,10 +64,10 @@ int main(int argc, char *argv[])
                       << argv[0] << " [options] <directory>\n"
                       << argv[0] << " [options] <path/to/region.txt or groundtruth.txt> <path/to/images.txt> [path/to/output.txt]\n"
                       << "Options:\n"
-                      << " --visualize | -v [delay_ms]\n"
-                      << " --output    | -o <outout.txt>\n"
+                      << " --visualize | -v[delay_ms]\n"
+                      << " --output    | -o <output.txt>\n"
                       << " --debug     | -d\n"
-                      << " --fit       | -f [dimension_size]\n";
+                      << " --fit       | -f[WxH]\n";
             exit(0);
             break;
         case 'o':
@@ -52,7 +77,14 @@ int main(int argc, char *argv[])
             visualize_delay = optarg ? atol(optarg) : 1;
             break;
         case 'f':
-            fit_size = optarg ? atol(optarg) : 128;
+            std::string sizes = optarg ? optarg : "128x128";
+            std::string delimiter = "x";
+            size_t pos = sizes.find(delimiter);
+            std::string first_argument = sizes.substr(0, pos);
+            sizes.erase(0, pos + delimiter.length());
+
+            fit_size_x = stol(first_argument);
+            fit_size_y = stol(sizes);
             break;
         }
     }
@@ -88,6 +120,14 @@ int main(int argc, char *argv[])
     }
     VOT vot_io(region, images, output);
 
+    // if groundtruth.txt is used use intersection over union (IOU) to calculate tracker accuracy
+    std::ifstream groundtruth_stream;
+    if (region.compare("groundtruth.txt") == 0) {
+        groundtruth_stream.open(region.c_str());
+        std::string line;
+        std::getline(groundtruth_stream, line);
+    }
+
     cv::Mat image;
 
     //img = firts frame, initPos = initial position in the first frame
@@ -95,24 +135,44 @@ int main(int argc, char *argv[])
     vot_io.outputBoundingBox(init_rect);
     vot_io.getNextImage(image);
 
-    tracker.init(image, init_rect, fit_size);
+    tracker.init(image, init_rect, fit_size_x, fit_size_y);
 
     BBox_c bb;
-    double avg_time = 0.;
+    cv::Rect bb_rect;
+    double avg_time = 0., sum_accuracy = 0.;
     int frames = 0;
+
+    std::cout << std::fixed << std::setprecision(2);
+
     while (vot_io.getNextImage(image) == 1){
         double time_profile_counter = cv::getCPUTickCount();
         tracker.track(image);
         time_profile_counter = cv::getCPUTickCount() - time_profile_counter;
-         std::cout << "  -> speed : " <<  time_profile_counter/((double)cvGetTickFrequency()*1000) << "ms. per frame" << std::endl;
+         std::cout << "  -> speed : " <<  time_profile_counter/((double)cvGetTickFrequency()*1000) << "ms per frame, "
+                      "response : " << tracker.getFilterResponse();
         avg_time += time_profile_counter/((double)cvGetTickFrequency()*1000);
         frames++;
 
         bb = tracker.getBBox();
-        vot_io.outputBoundingBox(cv::Rect(bb.cx - bb.w/2., bb.cy - bb.h/2., bb.w, bb.h));
+        bb_rect = cv::Rect(bb.cx - bb.w/2., bb.cy - bb.h/2., bb.w, bb.h);
+        vot_io.outputBoundingBox(bb_rect);
+
+        if (groundtruth_stream.is_open()) {
+            std::string line;
+            std::getline(groundtruth_stream, line);
+
+            cv::Rect groundtruthRect;
+            double accuracy = calcAccuracy(line, bb_rect, groundtruthRect);
+            if (visualize_delay >= 0)
+                cv::rectangle(image, groundtruthRect, CV_RGB(255, 0,0), 1);
+            std::cout << ", accuracy: " << accuracy;
+            sum_accuracy += accuracy;
+        }
+
+        std::cout << std::endl;
 
         if (visualize_delay >= 0) {
-            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);
+            cv::rectangle(image, bb_rect, CV_RGB(0,255,0), 2);
             cv::imshow("output", image);
             int ret = cv::waitKey(visualize_delay);
             if (visualize_delay > 0 && ret != -1 && ret != 255)
@@ -140,7 +200,12 @@ int main(int argc, char *argv[])
 //        cv::imwrite(ss.c_str(), image, compression_params);
     }
 
-    std::cout << "Average processing speed " << avg_time/frames <<  "ms. (" << 1./(avg_time/frames)*1000 << " fps)" << std::endl;
+    std::cout << "Average processing speed: " << avg_time / frames << "ms (" << 1. / (avg_time / frames) * 1000 << " fps)";
+    if (groundtruth_stream.is_open()) {
+        std::cout << "; Average accuracy: " << sum_accuracy/frames << std::endl;
+        groundtruth_stream.close();
+    }
+    std::cout << std::endl;
 
     return EXIT_SUCCESS;
 }