#include <getopt.h>
#include <libgen.h>
#include <unistd.h>
+#include <iomanip>
#include "kcf.h"
#include "vot.hpp"
int main(int argc, char *argv[])
{
- // load region, images and prepare for output
- std::string region, images, output;
+ //load region, images and prepare for output
+ std::string region, images, output, video_out;
int visualize_delay = -1, fit_size_x = -1, fit_size_y = -1;
KCF_Tracker tracker;
+ cv::VideoWriter videoWriter;
while (1) {
int option_index = 0;
- static struct option long_options[] = {{"debug", no_argument, 0, 'd'},
- {"visualDebug", no_argument, 0, 'p'},
- {"help", no_argument, 0, 'h'},
- {"output", required_argument, 0, 'o'},
- {"visualize", optional_argument, 0, 'v'},
- {"fit", optional_argument, 0, 'f'},
- {0, 0, 0, 0}};
-
- int c = getopt_long(argc, argv, "dphv::f::o:", long_options, &option_index);
- if (c == -1) break;
+ static struct option long_options[] = {
+ {"debug", no_argument, 0, 'd' },
+ {"visual_debug", optional_argument, 0, 'p'},
+ {"help", no_argument, 0, 'h' },
+ {"output", required_argument, 0, 'o' },
+ {"video_out", optional_argument, 0, 'O' },
+ {"visualize", optional_argument, 0, 'v' },
+ {"fit", optional_argument, 0, 'f' },
+ {0, 0, 0, 0 }
+ };
+
+ int c = getopt_long(argc, argv, "dp::hv::f::o:O::", long_options, &option_index);
+ if (c == -1)
+ break;
switch (c) {
case 'd':
tracker.m_debug = true;
break;
case 'p':
- tracker.m_visual_debug = true;
- visualize_delay = 500;
+ if (!optarg || *optarg == 'p')
+ tracker.m_visual_debug = KCF_Tracker::vd::PATCH;
+ else if (optarg && *optarg == 'r')
+ tracker.m_visual_debug = KCF_Tracker::vd::RESPONSE;
+ else {
+ fprintf(stderr, "Unknown visual debug mode: %c", *optarg);
+ return 1;
+ }
break;
case 'h':
- std::cerr
- << "Usage: \n"
- << argv[0] << " [options]\n"
- << 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 <output.txt>\n"
- << " --debug | -d\n"
- << " --visualDebug | -p\n"
- << " --fit | -f[WxH]\n";
+ std::cerr << "Usage: \n"
+ << argv[0] << " [options]\n"
+ << 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 <output.txt>\n"
+ << " --fit | -f[W[xH]]\n"
+ << " --debug | -d\n"
+ << " --visual_debug | -p [p|r]\n";
exit(0);
break;
case 'o':
output = optarg;
break;
+ case 'O':
+ video_out = optarg ? optarg : "./output.avi";
+ break;
case 'v':
visualize_delay = optarg ? atol(optarg) : 1;
break;
case 'f':
- 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);
+ if (!optarg) {
+ fit_size_x = fit_size_y = 0;
+ } else {
+ char tail;
+ if (sscanf(optarg, "%d%c", &fit_size_x, &tail) == 1) {
+ fit_size_y = fit_size_x;
+ } else if (sscanf(optarg, "%dx%d%c", &fit_size_x, &fit_size_y, &tail) != 2) {
+ fprintf(stderr, "Cannot parse -f argument: %s\n", optarg);
+ return 1;
+ }
+ }
break;
}
}
case 0:
region = access("groundtruth.txt", F_OK) == 0 ? "groundtruth.txt" : "region.txt";
images = "images.txt";
- if (output.empty()) output = "output.txt";
+ if (output.empty())
+ output = "output.txt";
break;
case 2:
// Fall through
cv::Mat image;
- // img = firts frame, initPos = initial position in the first frame
+ //img = firts frame, initPos = initial position in the first frame
cv::Rect init_rect = vot_io.getInitRectangle();
vot_io.outputBoundingBox(init_rect);
vot_io.getNextImage(image);
+ if (!video_out.empty()) {
+ int codec = CV_FOURCC('M', 'J', 'P', 'G'); // select desired codec (must be available at runtime)
+ double fps = 25.0; // framerate of the created video stream
+ videoWriter.open(video_out, codec, fps, image.size(), true);
+ }
+
tracker.init(image, init_rect, fit_size_x, fit_size_y);
+
BBox_c bb;
cv::Rect bb_rect;
double avg_time = 0., sum_accuracy = 0.;
int frames = 0;
- while (vot_io.getNextImage(image) == 1) {
+
+ 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";
- avg_time += time_profile_counter / ((double)cvGetTickFrequency() * 1000);
+ 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();
- bb_rect = 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()) {
cv::Rect groundtruthRect;
double accuracy = calcAccuracy(line, bb_rect, groundtruthRect);
- if (visualize_delay >= 0) cv::rectangle(image, groundtruthRect, CV_RGB(255, 0, 0), 1);
+ 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) {
+ if (visualize_delay >= 0 || !video_out.empty()) {
cv::Point pt(bb.cx, bb.cy);
cv::Size size(bb.w, bb.h);
cv::RotatedRect rotatedRectangle(pt, size, bb.a);
for (int i = 0; i < 4; i++)
cv::line(image, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 2);
- // 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);
- std::string angle = std::to_string(bb.a);
- angle.erase(angle.find_last_not_of('0') + 1, std::string::npos);
- angle.erase(angle.find_last_not_of('.') + 1, std::string::npos);
- 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::imshow("output", image);
- int ret = cv::waitKey(visualize_delay);
- if (visualize_delay > 0 && ret != -1 && ret != 255) break;
+ if (visualize_delay >= 0) {
+ cv::imshow("KCF output", image);
+ int ret = cv::waitKey(visualize_delay);
+ if ((visualize_delay > 0 && ret != -1 && ret < 128) ||
+ (visualize_delay == 0 && (ret == 27 /*esc*/ || ret == 'q')))
+ break;
+ }
+ if (!video_out.empty())
+ videoWriter << image;
}
- // std::stringstream s;
- // std::string ss;
- // int countTmp = frames;
- // s << "imgs" << "/img" << (countTmp/10000);
- // countTmp = countTmp%10000;
- // s << (countTmp/1000);
- // countTmp = countTmp%1000;
- // s << (countTmp/100);
- // countTmp = countTmp%100;
- // s << (countTmp/10);
- // countTmp = countTmp%10;
- // s << (countTmp);
- // s << ".jpg";
- // s >> ss;
- // //set image output parameters
- // std::vector<int> compression_params;
- // compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
- // compression_params.push_back(90);
- // cv::imwrite(ss.c_str(), image, compression_params);
+// std::stringstream s;
+// std::string ss;
+// int countTmp = frames;
+// s << "imgs" << "/img" << (countTmp/10000);
+// countTmp = countTmp%10000;
+// s << (countTmp/1000);
+// countTmp = countTmp%1000;
+// s << (countTmp/100);
+// countTmp = countTmp%100;
+// s << (countTmp/10);
+// countTmp = countTmp%10;
+// s << (countTmp);
+// s << ".jpg";
+// s >> ss;
+// //set image output parameters
+// std::vector<int> compression_params;
+// compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
+// compression_params.push_back(90);
+// 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;
+ std::cout << "; Average accuracy: " << sum_accuracy/frames << std::endl;
groundtruth_stream.close();
}
+ if (!video_out.empty())
+ videoWriter.release();
+ std::cout << std::endl;
return EXIT_SUCCESS;
}