vendor: OpenCV 5.0.0 snapshot at 755e50675d97db9b7d449d8bd6b09888646f6c6e
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/tracking.hpp"
|
||||
#include "opencv2/videoio.hpp"
|
||||
#include "opencv2/plot.hpp"
|
||||
#include "samples_utility.hpp"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
// TODO: do normalization ala Kalal's assessment protocol for TLD
|
||||
|
||||
static const Scalar gtColor = Scalar(0, 255, 0);
|
||||
|
||||
static Scalar getNextColor()
|
||||
{
|
||||
const int num = 6;
|
||||
static Scalar colors[num] = {Scalar(160, 0, 0), Scalar(0, 0, 160), Scalar(0, 160, 160),
|
||||
Scalar(160, 160, 0), Scalar(160, 0, 160), Scalar(20, 50, 160)};
|
||||
static int id = 0;
|
||||
return colors[id < num ? id++ : num - 1];
|
||||
}
|
||||
|
||||
inline vector<Rect2d> readGT(const string &filename, const string &omitname)
|
||||
{
|
||||
vector<Rect2d> res;
|
||||
{
|
||||
ifstream input(filename.c_str());
|
||||
if (!input.is_open())
|
||||
CV_Error(Error::StsError, "Failed to open file");
|
||||
while (input)
|
||||
{
|
||||
Rect2d one;
|
||||
input >> one.x;
|
||||
input.ignore(numeric_limits<std::streamsize>::max(), ',');
|
||||
input >> one.y;
|
||||
input.ignore(numeric_limits<std::streamsize>::max(), ',');
|
||||
input >> one.width;
|
||||
input.ignore(numeric_limits<std::streamsize>::max(), ',');
|
||||
input >> one.height;
|
||||
input.ignore(numeric_limits<std::streamsize>::max(), '\n');
|
||||
if (input.good())
|
||||
res.push_back(one);
|
||||
}
|
||||
}
|
||||
if (!omitname.empty())
|
||||
{
|
||||
ifstream input(omitname.c_str());
|
||||
if (!input.is_open())
|
||||
CV_Error(Error::StsError, "Failed to open file");
|
||||
while (input)
|
||||
{
|
||||
unsigned int a = 0, b = 0;
|
||||
input >> a >> b;
|
||||
input.ignore(numeric_limits<std::streamsize>::max(), '\n');
|
||||
if (a > 0 && b > 0 && a < res.size() && b < res.size())
|
||||
{
|
||||
if (a > b)
|
||||
swap(a, b);
|
||||
for (vector<Rect2d>::iterator i = res.begin() + a; i != res.begin() + b; ++i)
|
||||
{
|
||||
*i = Rect2d();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline bool isGoodBox(const Rect2d &box) { return box.width > 0. && box.height > 0.; }
|
||||
const int LTRC_COUNT = 100;
|
||||
|
||||
struct AlgoWrap
|
||||
{
|
||||
AlgoWrap(const string &name_)
|
||||
: lastState(NotFound), name(name_), color(getNextColor()),
|
||||
numTotal(0), numResponse(0), numPresent(0), numCorrect_0(0), numCorrect_0_5(0),
|
||||
timeTotal(0), auc(LTRC_COUNT + 1, 0)
|
||||
{
|
||||
tracker = createTrackerByName(name);
|
||||
}
|
||||
|
||||
enum State
|
||||
{
|
||||
NotFound,
|
||||
Overlap_None,
|
||||
Overlap_0,
|
||||
Overlap_0_5,
|
||||
};
|
||||
|
||||
Ptr<Tracker> tracker;
|
||||
bool lastRes;
|
||||
Rect lastBox;
|
||||
State lastState;
|
||||
|
||||
// visual
|
||||
string name;
|
||||
Scalar color;
|
||||
|
||||
// results
|
||||
int numTotal; // frames passed to tracker
|
||||
int numResponse; // frames where tracker had response
|
||||
int numPresent; // frames where ground truth result present
|
||||
int numCorrect_0; // frames where overlap with GT > 0
|
||||
int numCorrect_0_5; // frames where overlap with GT > 0.5
|
||||
int64 timeTotal; // ticks
|
||||
vector<int> auc; // number of frames for each overlap percent
|
||||
|
||||
void eval(const Mat &frame, const Rect2d >Box, bool isVerbose)
|
||||
{
|
||||
// RUN
|
||||
lastBox = Rect();
|
||||
int64 frameTime = getTickCount();
|
||||
lastRes = tracker->update(frame, lastBox);
|
||||
frameTime = getTickCount() - frameTime;
|
||||
|
||||
// RESULTS
|
||||
double intersectArea = (gtBox & (Rect2d)lastBox).area();
|
||||
double unionArea = (gtBox | (Rect2d)lastBox).area();
|
||||
numTotal++;
|
||||
numResponse += (lastRes && isGoodBox(lastBox)) ? 1 : 0;
|
||||
numPresent += isGoodBox(gtBox) ? 1 : 0;
|
||||
double overlap = unionArea > 0. ? intersectArea / unionArea : 0.;
|
||||
numCorrect_0 += overlap > 0. ? 1 : 0;
|
||||
numCorrect_0_5 += overlap > 0.5 ? 1 : 0;
|
||||
auc[std::min(std::max((size_t)(overlap * LTRC_COUNT), (size_t)0), (size_t)LTRC_COUNT)]++;
|
||||
timeTotal += frameTime;
|
||||
|
||||
if (isVerbose)
|
||||
cout << name << " - " << overlap << endl;
|
||||
|
||||
if (isGoodBox(gtBox) != isGoodBox(lastBox)) lastState = NotFound;
|
||||
else if (overlap > 0.5) lastState = Overlap_0_5;
|
||||
else if (overlap > 0.0001) lastState = Overlap_0;
|
||||
else lastState = Overlap_None;
|
||||
}
|
||||
|
||||
void draw(Mat &image, const Point &textPoint) const
|
||||
{
|
||||
if (lastRes)
|
||||
rectangle(image, lastBox, color, 2, LINE_8);
|
||||
string suf;
|
||||
switch (lastState)
|
||||
{
|
||||
case AlgoWrap::NotFound: suf = " X"; break;
|
||||
case AlgoWrap::Overlap_None: suf = " ~"; break;
|
||||
case AlgoWrap::Overlap_0: suf = " +"; break;
|
||||
case AlgoWrap::Overlap_0_5: suf = " ++"; break;
|
||||
}
|
||||
putText(image, name + suf, textPoint, FONT_HERSHEY_PLAIN, 1, color, 1, LINE_AA);
|
||||
}
|
||||
|
||||
// calculates "lost track ratio" curve - row of values growing from 0 to 1
|
||||
// number of elements is LTRC_COUNT + 2
|
||||
Mat getLTRC() const
|
||||
{
|
||||
Mat t, res;
|
||||
Mat(auc).convertTo(t, CV_64F); // integral does not support CV_32S input
|
||||
integral(t.t(), res, CV_64F); // t is a column of values
|
||||
return res.row(1) / (double)numTotal;
|
||||
}
|
||||
|
||||
void plotLTRC(Mat &img) const
|
||||
{
|
||||
Ptr<plot::Plot2d> p_ = plot::Plot2d::create(getLTRC());
|
||||
p_->render(img);
|
||||
}
|
||||
|
||||
double calcAUC() const
|
||||
{
|
||||
return cv::sum(getLTRC())[0] / (double)LTRC_COUNT;
|
||||
}
|
||||
|
||||
void stat(ostream &out) const
|
||||
{
|
||||
out << name << endl;
|
||||
out << setw(20) << "Overlap > 0 " << setw(20) << (double)numCorrect_0 / numTotal * 100
|
||||
<< "%" << setw(20) << numCorrect_0 << endl;
|
||||
out << setw(20) << "Overlap > 0.5" << setw(20) << (double)numCorrect_0_5 / numTotal * 100
|
||||
<< "%" << setw(20) << numCorrect_0_5 << endl;
|
||||
|
||||
double p = (double)numCorrect_0_5 / numResponse;
|
||||
double r = (double)numCorrect_0_5 / numPresent;
|
||||
double f = 2 * p * r / (p + r);
|
||||
out << setw(20) << "Precision" << setw(20) << p * 100 << "%" << endl;
|
||||
out << setw(20) << "Recall " << setw(20) << r * 100 << "%" << endl;
|
||||
out << setw(20) << "f-measure" << setw(20) << f * 100 << "%" << endl;
|
||||
out << setw(20) << "AUC" << setw(20) << calcAUC() << endl;
|
||||
|
||||
double s = (timeTotal / getTickFrequency()) / numTotal;
|
||||
out << setw(20) << "Performance" << setw(20) << s * 1000 << " ms/frame" << setw(20) << 1 / s
|
||||
<< " fps" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
inline ostream &operator<<(ostream &out, const AlgoWrap &w) { w.stat(out); return out; }
|
||||
|
||||
inline vector<AlgoWrap> initAlgorithms(const string &algList)
|
||||
{
|
||||
vector<AlgoWrap> res;
|
||||
istringstream input(algList);
|
||||
for (;;)
|
||||
{
|
||||
char one[30];
|
||||
input.getline(one, 30, ',');
|
||||
if (!input)
|
||||
break;
|
||||
cout << " " << one << " - ";
|
||||
AlgoWrap a(one);
|
||||
if (a.tracker)
|
||||
{
|
||||
res.push_back(a);
|
||||
cout << "OK";
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "FAILED";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static const string &window = "Tracking API";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const string keys =
|
||||
"{help h||show help}"
|
||||
"{video||video file to process}"
|
||||
"{gt||ground truth file (each line describes rectangle in format: '<x>,<y>,<w>,<h>')}"
|
||||
"{start|0|starting frame}"
|
||||
"{num|0|frame number (0 for all)}"
|
||||
"{omit||file with omit ranges (each line describes occluded frames: '<start> <end>')}"
|
||||
"{plot|false|plot LTR curves at the end}"
|
||||
"{v|false|print each frame info}"
|
||||
"{@algos||comma-separated algorithm names}";
|
||||
CommandLineParser p(argc, argv, keys);
|
||||
if (p.has("help"))
|
||||
{
|
||||
p.printMessage();
|
||||
return 0;
|
||||
}
|
||||
int startFrame = p.get<int>("start");
|
||||
int frameCount = p.get<int>("num");
|
||||
string videoFile = p.get<string>("video");
|
||||
string gtFile = p.get<string>("gt");
|
||||
string omitFile = p.get<string>("omit");
|
||||
string algList = p.get<string>("@algos");
|
||||
bool doPlot = p.get<bool>("plot");
|
||||
bool isVerbose = p.get<bool>("v");
|
||||
if (!p.check())
|
||||
{
|
||||
p.printErrors();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cout << "Reading GT from " << gtFile << " ... ";
|
||||
vector<Rect2d> gt = readGT(gtFile, omitFile);
|
||||
if (gt.empty())
|
||||
CV_Error(Error::StsError, "Failed to read GT file");
|
||||
cout << gt.size() << " boxes" << endl;
|
||||
|
||||
cout << "Opening video " << videoFile << " ... ";
|
||||
VideoCapture cap;
|
||||
cap.open(videoFile);
|
||||
if (!cap.isOpened())
|
||||
CV_Error(Error::StsError, "Failed to open video file");
|
||||
cap.set(CAP_PROP_POS_FRAMES, startFrame);
|
||||
cout << "at frame " << startFrame << endl;
|
||||
|
||||
// INIT
|
||||
vector<AlgoWrap> algos = initAlgorithms(algList);
|
||||
Mat frame, image;
|
||||
cap >> frame;
|
||||
for (vector<AlgoWrap>::iterator i = algos.begin(); i != algos.end(); ++i)
|
||||
i->tracker->init(frame, gt[0]);
|
||||
|
||||
// DRAW
|
||||
{
|
||||
namedWindow(window, WINDOW_AUTOSIZE);
|
||||
frame.copyTo(image);
|
||||
rectangle(image, gt[0], gtColor, 2, LINE_8);
|
||||
imshow(window, image);
|
||||
}
|
||||
|
||||
bool paused = false;
|
||||
int frameId = 0;
|
||||
cout << "Hot keys:" << endl << " q - exit" << endl << " p - pause" << endl;
|
||||
for (;;)
|
||||
{
|
||||
if (!paused)
|
||||
{
|
||||
cap >> frame;
|
||||
if (frame.empty())
|
||||
{
|
||||
cout << "Done - video end" << endl;
|
||||
break;
|
||||
}
|
||||
frameId++;
|
||||
if (isVerbose)
|
||||
cout << endl << "Frame " << frameId << endl;
|
||||
// EVAL
|
||||
for (vector<AlgoWrap>::iterator i = algos.begin(); i != algos.end(); ++i)
|
||||
i->eval(frame, gt[frameId], isVerbose);
|
||||
// DRAW
|
||||
{
|
||||
Point textPoint(1, 16);
|
||||
frame.copyTo(image);
|
||||
rectangle(image, gt[frameId], gtColor, 2, LINE_8);
|
||||
putText(image, "GROUND TRUTH", textPoint, FONT_HERSHEY_PLAIN, 1, gtColor, 1, LINE_AA);
|
||||
for (vector<AlgoWrap>::iterator i = algos.begin(); i != algos.end(); ++i)
|
||||
{
|
||||
textPoint.y += 14;
|
||||
i->draw(image, textPoint);
|
||||
}
|
||||
imshow(window, image);
|
||||
}
|
||||
}
|
||||
|
||||
char c = (char)waitKey(1);
|
||||
if (c == 'q')
|
||||
{
|
||||
cout << "Done - manual exit" << endl;
|
||||
break;
|
||||
}
|
||||
else if (c == 'p')
|
||||
{
|
||||
paused = !paused;
|
||||
}
|
||||
if (frameCount && frameId >= frameCount)
|
||||
{
|
||||
cout << "Done - max frame count" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// STAT
|
||||
for (vector<AlgoWrap>::iterator i = algos.begin(); i != algos.end(); ++i)
|
||||
cout << "==========" << endl << *i << endl;
|
||||
|
||||
if (doPlot)
|
||||
{
|
||||
Mat img(300, 300, CV_8UC3);
|
||||
for (vector<AlgoWrap>::iterator i = algos.begin(); i != algos.end(); ++i)
|
||||
{
|
||||
i->plotLTRC(img);
|
||||
imshow("LTR curve for " + i->name, img);
|
||||
}
|
||||
waitKey(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// show help
|
||||
if (argc<2) {
|
||||
cout <<
|
||||
" Usage: example_tracking_csrt <video_name>\n"
|
||||
" examples:\n"
|
||||
" example_tracking_csrt Bolt/img/%04.jpg\n"
|
||||
" example_tracking_csrt Bolt/img/%04.jpg Bolt/grouondtruth.txt\n"
|
||||
" example_tracking_csrt faceocc2.webm\n"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create the tracker
|
||||
Ptr<TrackerCSRT> tracker = TrackerCSRT::create();
|
||||
|
||||
// const char* param_file_path = "/home/amuhic/Workspace/3_dip/params.yml";
|
||||
// FileStorage fs(params_file_path, FileStorage::WRITE);
|
||||
// tracker->write(fs);
|
||||
// FileStorage fs(param_file_path, FileStorage::READ);
|
||||
// tracker->read( fs.root());
|
||||
|
||||
// set input video
|
||||
std::string video = argv[1];
|
||||
VideoCapture cap(video);
|
||||
// and read first frame
|
||||
Mat frame;
|
||||
cap >> frame;
|
||||
|
||||
// target bounding box
|
||||
Rect roi;
|
||||
if (argc > 2) {
|
||||
// read first line of ground-truth file
|
||||
std::string groundtruthPath = argv[2];
|
||||
std::ifstream gtIfstream(groundtruthPath.c_str());
|
||||
std::string gtLine;
|
||||
getline(gtIfstream, gtLine);
|
||||
gtIfstream.close();
|
||||
|
||||
// parse the line by elements
|
||||
std::stringstream gtStream(gtLine);
|
||||
std::string element;
|
||||
std::vector<int> elements;
|
||||
while (std::getline(gtStream, element, ','))
|
||||
{
|
||||
elements.push_back(cvRound(std::atof(element.c_str())));
|
||||
}
|
||||
|
||||
if (elements.size() == 4) {
|
||||
// ground-truth is rectangle
|
||||
roi = cv::Rect(elements[0], elements[1], elements[2], elements[3]);
|
||||
}
|
||||
else if (elements.size() == 8) {
|
||||
// ground-truth is polygon
|
||||
int xMin = cvRound(min(elements[0], min(elements[2], min(elements[4], elements[6]))));
|
||||
int yMin = cvRound(min(elements[1], min(elements[3], min(elements[5], elements[7]))));
|
||||
int xMax = cvRound(max(elements[0], max(elements[2], max(elements[4], elements[6]))));
|
||||
int yMax = cvRound(max(elements[1], max(elements[3], max(elements[5], elements[7]))));
|
||||
roi = cv::Rect(xMin, yMin, xMax - xMin, yMax - yMin);
|
||||
|
||||
// create mask from polygon and set it to the tracker
|
||||
cv::Rect aaRect = cv::Rect(xMin, yMin, xMax - xMin, yMax - yMin);
|
||||
cout << aaRect.size() << endl;
|
||||
Mat mask = Mat::zeros(aaRect.size(), CV_8UC1);
|
||||
const int n = 4;
|
||||
std::vector<cv::Point> poly_points(n);
|
||||
//Translate x and y to rects start position
|
||||
int sx = aaRect.x;
|
||||
int sy = aaRect.y;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
poly_points[i] = Point(elements[2 * i] - sx, elements[2 * i + 1] - sy);
|
||||
}
|
||||
cv::fillConvexPoly(mask, poly_points, Scalar(1.0), 8);
|
||||
mask.convertTo(mask, CV_32FC1);
|
||||
tracker->setInitialMask(mask);
|
||||
}
|
||||
else {
|
||||
std::cout << "Number of ground-truth elements is not 4 or 8." << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// second argument is not given - user selects target
|
||||
roi = selectROI("tracker", frame, true, false);
|
||||
}
|
||||
|
||||
//quit if ROI was not selected
|
||||
if (roi.width == 0 || roi.height == 0)
|
||||
return 0;
|
||||
|
||||
// initialize the tracker
|
||||
int64 t1 = cv::getTickCount();
|
||||
tracker->init(frame, roi);
|
||||
int64 t2 = cv::getTickCount();
|
||||
int64 tick_counter = t2 - t1;
|
||||
|
||||
// do the tracking
|
||||
printf("Start the tracking process, press ESC to quit.\n");
|
||||
int frame_idx = 1;
|
||||
for (;;) {
|
||||
// get frame from the video
|
||||
cap >> frame;
|
||||
|
||||
// stop the program if no more images
|
||||
if (frame.rows == 0 || frame.cols == 0)
|
||||
break;
|
||||
|
||||
// update the tracking result
|
||||
t1 = cv::getTickCount();
|
||||
bool isfound = tracker->update(frame, roi);
|
||||
t2 = cv::getTickCount();
|
||||
tick_counter += t2 - t1;
|
||||
frame_idx++;
|
||||
|
||||
if (!isfound) {
|
||||
cout << "The target has been lost...\n";
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// draw the tracked object and show the image
|
||||
rectangle(frame, roi, Scalar(255, 0, 0), 2, 1);
|
||||
imshow("tracker", frame);
|
||||
|
||||
//quit on ESC button
|
||||
if (waitKey(1) == 27)break;
|
||||
}
|
||||
|
||||
cout << "Elapsed sec: " << static_cast<double>(tick_counter) / cv::getTickFrequency() << endl;
|
||||
cout << "FPS: " << ((double)(frame_idx)) / (static_cast<double>(tick_counter) / cv::getTickFrequency()) << endl;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*----------------------------------------------
|
||||
* Usage:
|
||||
* example_tracking_kcf <video_name>
|
||||
*
|
||||
* example:
|
||||
* example_tracking_kcf Bolt/img/%04.jpg
|
||||
* example_tracking_kcf faceocc2.webm
|
||||
*--------------------------------------------------*/
|
||||
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main( int argc, char** argv ){
|
||||
// show help
|
||||
if(argc<2){
|
||||
cout<<
|
||||
" Usage: example_tracking_kcf <video_name>\n"
|
||||
" examples:\n"
|
||||
" example_tracking_kcf Bolt/img/%04.jpg\n"
|
||||
" example_tracking_kcf faceocc2.webm\n"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create the tracker
|
||||
Ptr<Tracker> tracker = TrackerKCF::create();
|
||||
|
||||
// set input video
|
||||
std::string video = argv[1];
|
||||
VideoCapture cap(video);
|
||||
|
||||
Mat frame;
|
||||
|
||||
// get bounding box
|
||||
cap >> frame;
|
||||
Rect roi = selectROI("tracker", frame, true, false);
|
||||
|
||||
//quit if ROI was not selected
|
||||
if(roi.width==0 || roi.height==0)
|
||||
return 0;
|
||||
|
||||
// initialize the tracker
|
||||
tracker->init(frame,roi);
|
||||
|
||||
// do the tracking
|
||||
printf("Start the tracking process, press ESC to quit.\n");
|
||||
for ( ;; ){
|
||||
// get frame from the video
|
||||
cap >> frame;
|
||||
|
||||
// stop the program if no more images
|
||||
if(frame.rows==0 || frame.cols==0)
|
||||
break;
|
||||
|
||||
// update the tracking result
|
||||
bool isfound = tracker->update(frame,roi);
|
||||
if(!isfound)
|
||||
{
|
||||
cout << "The target has been lost...\n";
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// draw the tracked object
|
||||
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
|
||||
|
||||
// show image with the tracked object
|
||||
imshow("tracker",frame);
|
||||
|
||||
//quit on ESC button
|
||||
if(waitKey(1)==27)break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
#ifdef HAVE_OPENCV_DATASETS
|
||||
|
||||
#include "opencv2/datasets/track_vot.hpp"
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include "samples_utility.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::datasets;
|
||||
|
||||
#define NUM_TEST_FRAMES 1000
|
||||
|
||||
static Mat image;
|
||||
static bool paused;
|
||||
static bool selectObjects = false;
|
||||
static bool startSelection = false;
|
||||
vector<Rect2d> boundingBoxes;
|
||||
int targetsCnt = 0;
|
||||
int targetsNum = 0;
|
||||
Rect2d boundingBox;
|
||||
|
||||
static const char* keys =
|
||||
{ "{@tracker_algorithm | | Tracker algorithm }"
|
||||
"{@target_num |1| Number of targets }"
|
||||
"{@dataset_path |true| Dataset path }"
|
||||
"{@dataset_id |1| Dataset ID }"
|
||||
};
|
||||
|
||||
static void onMouse(int event, int x, int y, int, void*)
|
||||
{
|
||||
if (!selectObjects)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_LBUTTONDOWN:
|
||||
//set origin of the bounding box
|
||||
startSelection = true;
|
||||
boundingBox.x = x;
|
||||
boundingBox.y = y;
|
||||
boundingBox.width = boundingBox.height = 0;
|
||||
break;
|
||||
case EVENT_LBUTTONUP:
|
||||
//sei with and height of the bounding box
|
||||
boundingBox.width = std::abs(x - boundingBox.x);
|
||||
boundingBox.height = std::abs(y - boundingBox.y);
|
||||
boundingBoxes.push_back(boundingBox);
|
||||
targetsCnt++;
|
||||
if (targetsCnt == targetsNum)
|
||||
{
|
||||
paused = false;
|
||||
selectObjects = true;
|
||||
}
|
||||
startSelection = false;
|
||||
break;
|
||||
case EVENT_MOUSEMOVE:
|
||||
|
||||
if (startSelection && !selectObjects)
|
||||
{
|
||||
//draw the bounding box
|
||||
Mat currentFrame;
|
||||
image.copyTo(currentFrame);
|
||||
for (int i = 0; i < (int)boundingBoxes.size(); i++)
|
||||
rectangle(currentFrame, boundingBoxes[i], Scalar(255, 0, 0), 2, 1);
|
||||
rectangle(currentFrame, Point((int)boundingBox.x, (int)boundingBox.y), Point(x, y), Scalar(255, 0, 0), 2, 1);
|
||||
imshow("Tracking API", currentFrame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
|
||||
"TLD dataset ID: 1~10, VOT2015 dataset ID: 1~60\n"
|
||||
"-- pause video [p] and draw a bounding boxes around the targets to start the tracker\n"
|
||||
"Example:\n"
|
||||
"./example_tracking_multiTracker_dataset<tracker_algorithm> <number_of_targets> <dataset_path> <dataset_id>\n"
|
||||
<< endl;
|
||||
|
||||
cout << "\n\nHot keys: \n"
|
||||
"\tq - quit the program\n"
|
||||
"\tp - pause video\n";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
string tracker_algorithm = parser.get<string>(0);
|
||||
targetsNum = parser.get<int>(1);
|
||||
string datasetRootPath = parser.get<string>(2);
|
||||
int datasetID = parser.get<int>(3);
|
||||
if (tracker_algorithm.empty() || datasetRootPath.empty() || targetsNum < 1)
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat frame;
|
||||
paused = false;
|
||||
namedWindow("Tracking API", 0);
|
||||
setMouseCallback("Tracking API", onMouse, 0);
|
||||
|
||||
legacy::MultiTrackerTLD mt;
|
||||
//Init Dataset
|
||||
Ptr<TRACK_vot> dataset = TRACK_vot::create();
|
||||
dataset->load(datasetRootPath);
|
||||
dataset->initDataset(datasetID);
|
||||
|
||||
//Read first frame
|
||||
dataset->getNextFrame(frame);
|
||||
frame.copyTo(image);
|
||||
for (int i = 0; i < (int)boundingBoxes.size(); i++)
|
||||
rectangle(image, boundingBoxes[i], Scalar(255, 0, 0), 2, 1);
|
||||
imshow("Tracking API", image);
|
||||
|
||||
bool initialized = false;
|
||||
paused = true;
|
||||
int frameCounter = 0;
|
||||
|
||||
//Time measurment
|
||||
int64 e3 = getTickCount();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!paused)
|
||||
{
|
||||
//Time measurment
|
||||
int64 e1 = getTickCount();
|
||||
if (initialized){
|
||||
if (!dataset->getNextFrame(frame))
|
||||
break;
|
||||
frame.copyTo(image);
|
||||
}
|
||||
|
||||
if (!initialized && selectObjects)
|
||||
{
|
||||
//Initialize the tracker and add targets
|
||||
for (int i = 0; i < (int)boundingBoxes.size(); i++)
|
||||
{
|
||||
if (!mt.addTarget(frame, boundingBoxes[i], createTrackerByName_legacy(tracker_algorithm)))
|
||||
{
|
||||
cout << "Trackers Init Error!!!";
|
||||
return 0;
|
||||
}
|
||||
rectangle(frame, boundingBoxes[i], mt.colors[0], 2, 1);
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
else if (initialized)
|
||||
{
|
||||
//Update all targets
|
||||
if (mt.update(frame))
|
||||
{
|
||||
for (int i = 0; i < mt.targetNum; i++)
|
||||
{
|
||||
rectangle(frame, mt.boundingBoxes[i], mt.colors[i], 2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
imshow("Tracking API", frame);
|
||||
frameCounter++;
|
||||
//Time measurment
|
||||
int64 e2 = getTickCount();
|
||||
double t1 = (e2 - e1) / getTickFrequency();
|
||||
cout << frameCounter << "\tframe : " << t1 * 1000.0 << "ms" << endl;
|
||||
}
|
||||
|
||||
char c = (char)waitKey(2);
|
||||
if (c == 'q')
|
||||
break;
|
||||
if (c == 'p')
|
||||
paused = !paused;
|
||||
|
||||
//waitKey(0);
|
||||
}
|
||||
|
||||
//Time measurment
|
||||
int64 e4 = getTickCount();
|
||||
double t2 = (e4 - e3) / getTickFrequency();
|
||||
cout << "Average Time for Frame: " << t2 * 1000.0 / frameCounter << "ms" << endl;
|
||||
cout << "Average FPS: " << 1.0 / t2*frameCounter << endl;
|
||||
|
||||
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // ! HAVE_OPENCV_DATASETS
|
||||
#include <opencv2/core.hpp>
|
||||
int main() {
|
||||
CV_Error(cv::Error::StsNotImplemented , "this sample needs to be built with opencv_datasets !");
|
||||
return -1;
|
||||
}
|
||||
#endif // HAVE_OPENCV_DATASETS
|
||||
@@ -0,0 +1,154 @@
|
||||
/*----------------------------------------------
|
||||
* Usage:
|
||||
* example_tracking_multitracker <video_name> [algorithm]
|
||||
*
|
||||
* example:
|
||||
* example_tracking_multitracker Bolt/img/%04d.jpg
|
||||
* example_tracking_multitracker faceocc2.webm KCF
|
||||
*
|
||||
* Note: after the OpenCV library is installed,
|
||||
* please re-compile this code with "HAVE_OPENCV" parameter activated
|
||||
* to enable the high precission of fps computation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
/* after the OpenCV library is installed
|
||||
* please uncomment the the line below and re-compile this code
|
||||
* to enable high precission of fps computation
|
||||
*/
|
||||
//#define HAVE_OPENCV
|
||||
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCV
|
||||
#include <opencv2/flann.hpp>
|
||||
#endif
|
||||
|
||||
#define RESET "\033[0m"
|
||||
#define RED "\033[31m" /* Red */
|
||||
#define GREEN "\033[32m" /* Green */
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main( int argc, char** argv ){
|
||||
// show help
|
||||
if(argc<2){
|
||||
cout<<
|
||||
" Usage: example_tracking_multitracker <video_name> [algorithm]\n"
|
||||
" examples:\n"
|
||||
" example_tracking_multitracker Bolt/img/%04d.jpg\n"
|
||||
" example_tracking_multitracker faceocc2.webm MEDIANFLOW\n"
|
||||
" \n"
|
||||
" Note: after the OpenCV library is installed,\n"
|
||||
" please re-compile with the HAVE_OPENCV parameter activated\n"
|
||||
" to enable the high precission of fps computation.\n"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// timer
|
||||
#ifdef HAVE_OPENCV
|
||||
cvflann::StartStopTimer timer;
|
||||
#else
|
||||
clock_t timer;
|
||||
#endif
|
||||
|
||||
// for showing the speed
|
||||
double fps;
|
||||
String text;
|
||||
char buffer [50];
|
||||
|
||||
// set the default tracking algorithm
|
||||
String trackingAlg = "KCF";
|
||||
|
||||
// set the tracking algorithm from parameter
|
||||
if(argc>2)
|
||||
trackingAlg = argv[2];
|
||||
|
||||
// create the tracker
|
||||
legacy::MultiTracker trackers;
|
||||
|
||||
// container of the tracked objects
|
||||
vector<Rect> ROIs;
|
||||
vector<Rect2d> objects;
|
||||
|
||||
// set input video
|
||||
String video = argv[1];
|
||||
VideoCapture cap(video);
|
||||
|
||||
Mat frame;
|
||||
|
||||
// get bounding box
|
||||
cap >> frame;
|
||||
selectROIs("tracker",frame,ROIs);
|
||||
|
||||
//quit when the tracked object(s) is not provided
|
||||
if(ROIs.size()<1)
|
||||
return 0;
|
||||
|
||||
std::vector<Ptr<legacy::Tracker> > algorithms;
|
||||
for (size_t i = 0; i < ROIs.size(); i++)
|
||||
{
|
||||
algorithms.push_back(createTrackerByName_legacy(trackingAlg));
|
||||
objects.push_back(ROIs[i]);
|
||||
}
|
||||
|
||||
// initialize the tracker
|
||||
trackers.add(algorithms,frame,objects);
|
||||
|
||||
// do the tracking
|
||||
printf(GREEN "Start the tracking process, press ESC to quit.\n" RESET);
|
||||
for ( ;; ){
|
||||
// get frame from the video
|
||||
cap >> frame;
|
||||
|
||||
// stop the program if no more images
|
||||
if(frame.rows==0 || frame.cols==0)
|
||||
break;
|
||||
|
||||
// start the timer
|
||||
#ifdef HAVE_OPENCV
|
||||
timer.start();
|
||||
#else
|
||||
timer=clock();
|
||||
#endif
|
||||
|
||||
//update the tracking result
|
||||
trackers.update(frame);
|
||||
|
||||
// calculate the processing speed
|
||||
#ifdef HAVE_OPENCV
|
||||
timer.stop();
|
||||
fps=1.0/timer.value;
|
||||
timer.reset();
|
||||
#else
|
||||
timer=clock();
|
||||
trackers.update(frame);
|
||||
timer=clock()-timer;
|
||||
fps=(double)CLOCKS_PER_SEC/(double)timer;
|
||||
#endif
|
||||
|
||||
// draw the tracked object
|
||||
for(unsigned i=0;i<trackers.getObjects().size();i++)
|
||||
rectangle( frame, trackers.getObjects()[i], Scalar( 255, 0, 0 ), 2, 1 );
|
||||
|
||||
// draw the processing speed
|
||||
sprintf (buffer, "speed: %.0f fps", fps);
|
||||
text = buffer;
|
||||
putText(frame, text, Point(20,20), FONT_HERSHEY_PLAIN, 1, Scalar(255,255,255));
|
||||
|
||||
// show image with the tracked object
|
||||
imshow("tracker",frame);
|
||||
|
||||
//quit on ESC button
|
||||
if(waitKey(1)==27)break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print('Input video name is missing')
|
||||
exit()
|
||||
|
||||
print('Select 3 tracking targets')
|
||||
|
||||
cv.namedWindow("tracking")
|
||||
camera = cv.VideoCapture(sys.argv[1])
|
||||
tracker = cv.legacy.MultiTracker_create()
|
||||
init_once = False
|
||||
|
||||
ok, image=camera.read()
|
||||
if not ok:
|
||||
print('Failed to read video')
|
||||
exit()
|
||||
|
||||
bbox1 = cv.selectROI('tracking', image)
|
||||
bbox2 = cv.selectROI('tracking', image)
|
||||
bbox3 = cv.selectROI('tracking', image)
|
||||
|
||||
while camera.isOpened():
|
||||
ok, image=camera.read()
|
||||
if not ok:
|
||||
print('no image to read')
|
||||
break
|
||||
|
||||
if not init_once:
|
||||
ok = tracker.add(cv.legacy.TrackerMIL_create(), image, bbox1)
|
||||
ok = tracker.add(cv.legacy.TrackerMIL_create(), image, bbox2)
|
||||
ok = tracker.add(cv.legacy.TrackerMIL_create(), image, bbox3)
|
||||
init_once = True
|
||||
|
||||
ok, boxes = tracker.update(image)
|
||||
print(ok, boxes)
|
||||
|
||||
for newbox in boxes:
|
||||
p1 = (int(newbox[0]), int(newbox[1]))
|
||||
p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
|
||||
cv.rectangle(image, p1, p2, (200,0,0))
|
||||
|
||||
cv.imshow('tracking', image)
|
||||
k = cv.waitKey(1)
|
||||
if k == 27 : break # esc pressed
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef _SAMPLES_UTILITY_HPP_
|
||||
#define _SAMPLES_UTILITY_HPP_
|
||||
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/tracking/tracking_legacy.hpp>
|
||||
|
||||
inline cv::Ptr<cv::Tracker> createTrackerByName(const std::string& name)
|
||||
{
|
||||
using namespace cv;
|
||||
|
||||
cv::Ptr<cv::Tracker> tracker;
|
||||
|
||||
if (name == "KCF")
|
||||
tracker = cv::TrackerKCF::create();
|
||||
else if (name == "TLD")
|
||||
tracker = legacy::upgradeTrackingAPI(legacy::TrackerTLD::create());
|
||||
else if (name == "BOOSTING")
|
||||
tracker = legacy::upgradeTrackingAPI(legacy::TrackerBoosting::create());
|
||||
else if (name == "MEDIAN_FLOW")
|
||||
tracker = legacy::upgradeTrackingAPI(legacy::TrackerMedianFlow::create());
|
||||
else if (name == "MIL")
|
||||
tracker = cv::TrackerMIL::create();
|
||||
else if (name == "MOSSE")
|
||||
tracker = legacy::upgradeTrackingAPI(legacy::TrackerMOSSE::create());
|
||||
else if (name == "CSRT")
|
||||
tracker = cv::TrackerCSRT::create();
|
||||
else
|
||||
CV_Error(cv::Error::StsBadArg, "Invalid tracking algorithm name\n");
|
||||
|
||||
return tracker;
|
||||
}
|
||||
|
||||
inline cv::Ptr<cv::legacy::Tracker> createTrackerByName_legacy(const std::string& name)
|
||||
{
|
||||
using namespace cv;
|
||||
|
||||
cv::Ptr<cv::legacy::Tracker> tracker;
|
||||
|
||||
if (name == "KCF")
|
||||
tracker = legacy::TrackerKCF::create();
|
||||
else if (name == "TLD")
|
||||
tracker = legacy::TrackerTLD::create();
|
||||
else if (name == "BOOSTING")
|
||||
tracker = legacy::TrackerBoosting::create();
|
||||
else if (name == "MEDIAN_FLOW")
|
||||
tracker = legacy::TrackerMedianFlow::create();
|
||||
else if (name == "MIL")
|
||||
tracker = legacy::TrackerMIL::create();
|
||||
else if (name == "MOSSE")
|
||||
tracker = legacy::TrackerMOSSE::create();
|
||||
else if (name == "CSRT")
|
||||
tracker = legacy::TrackerCSRT::create();
|
||||
else
|
||||
CV_Error(cv::Error::StsBadArg, "Invalid tracking algorithm name\n");
|
||||
|
||||
return tracker;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static const char* keys =
|
||||
{ "{@tracker_algorithm | | Tracker algorithm }"
|
||||
"{@video_name | | video name }"
|
||||
"{@start_frame |0| Start frame }"
|
||||
"{@bounding_frame |0,0,0,0| Initial bounding frame}"};
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
|
||||
"-- pause video [p] and draw a bounding box around the target to start the tracker\n"
|
||||
"Example of <video_name> is in opencv_extra/testdata/cv/tracking/\n"
|
||||
"Call:\n"
|
||||
"./tracker <tracker_algorithm> <video_name> <start_frame> [<bounding_frame>]\n"
|
||||
"tracker_algorithm can be: MIL, BOOSTING, MEDIANFLOW, TLD, KCF, MOSSE.\n"
|
||||
<< endl;
|
||||
|
||||
cout << "\n\nHot keys: \n"
|
||||
"\tq - quit the program\n"
|
||||
"\tp - pause video\n";
|
||||
}
|
||||
|
||||
int main( int argc, char** argv ){
|
||||
CommandLineParser parser( argc, argv, keys );
|
||||
|
||||
String tracker_algorithm = parser.get<String>( 0 );
|
||||
String video_name = parser.get<String>( 1 );
|
||||
int start_frame = parser.get<int>( 2 );
|
||||
|
||||
if( tracker_algorithm.empty() || video_name.empty() )
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int coords[4]={0,0,0,0};
|
||||
bool initBoxWasGivenInCommandLine=false;
|
||||
{
|
||||
String initBoundingBox=parser.get<String>(3);
|
||||
for(size_t npos=0,pos=0,ctr=0;ctr<4;ctr++){
|
||||
npos=initBoundingBox.find_first_of(',',pos);
|
||||
if(npos==string::npos && ctr<3){
|
||||
printf("bounding box should be given in format \"x1,y1,x2,y2\",where x's and y's are integer coordinates of opposed corners of bdd box\n");
|
||||
printf("got: %s\n",initBoundingBox.substr(pos,string::npos).c_str());
|
||||
printf("manual selection of bounding box will be employed\n");
|
||||
break;
|
||||
}
|
||||
int num=atoi(initBoundingBox.substr(pos,(ctr==3)?(string::npos):(npos-pos)).c_str());
|
||||
if(num<=0){
|
||||
printf("bounding box should be given in format \"x1,y1,x2,y2\",where x's and y's are integer coordinates of opposed corners of bdd box\n");
|
||||
printf("got: %s\n",initBoundingBox.substr(pos,npos-pos).c_str());
|
||||
printf("manual selection of bounding box will be employed\n");
|
||||
break;
|
||||
}
|
||||
coords[ctr]=num;
|
||||
pos=npos+1;
|
||||
}
|
||||
if(coords[0]>0 && coords[1]>0 && coords[2]>0 && coords[3]>0){
|
||||
initBoxWasGivenInCommandLine=true;
|
||||
}
|
||||
}
|
||||
|
||||
//open the capture
|
||||
VideoCapture cap;
|
||||
cap.open( video_name );
|
||||
cap.set( CAP_PROP_POS_FRAMES, start_frame );
|
||||
|
||||
if( !cap.isOpened() )
|
||||
{
|
||||
help();
|
||||
cout << "***Could not initialize capturing...***\n";
|
||||
cout << "Current parameter's value: \n";
|
||||
parser.printMessage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat frame;
|
||||
namedWindow( "Tracking API", 1 );
|
||||
|
||||
Mat image;
|
||||
Rect boundingBox;
|
||||
bool paused = false;
|
||||
|
||||
//instantiates the specific Tracker
|
||||
Ptr<Tracker> tracker = createTrackerByName(tracker_algorithm);
|
||||
if (!tracker)
|
||||
{
|
||||
cout << "***Error in the instantiation of the tracker...***\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the first frame
|
||||
cap >> frame;
|
||||
frame.copyTo( image );
|
||||
if(initBoxWasGivenInCommandLine){
|
||||
boundingBox.x = coords[0];
|
||||
boundingBox.y = coords[1];
|
||||
boundingBox.width = std::abs( coords[2] - coords[0] );
|
||||
boundingBox.height = std::abs( coords[3]-coords[1]);
|
||||
printf("bounding box with vertices (%d,%d) and (%d,%d) was given in command line\n",coords[0],coords[1],coords[2],coords[3]);
|
||||
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
|
||||
}
|
||||
else
|
||||
boundingBox = selectROI("Tracking API", image);
|
||||
|
||||
imshow( "Tracking API", image );
|
||||
|
||||
bool initialized = false;
|
||||
int frameCounter = 0;
|
||||
int64 timeTotal = 0;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if( !paused )
|
||||
{
|
||||
if(initialized){
|
||||
cap >> frame;
|
||||
if(frame.empty()){
|
||||
break;
|
||||
}
|
||||
frame.copyTo( image );
|
||||
}
|
||||
|
||||
if( !initialized )
|
||||
{
|
||||
//initializes the tracker
|
||||
tracker->init(frame, boundingBox);
|
||||
initialized = true;
|
||||
}
|
||||
else if( initialized )
|
||||
{
|
||||
int64 frameTime = getTickCount();
|
||||
//updates the tracker
|
||||
if( tracker->update( frame, boundingBox ) )
|
||||
{
|
||||
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
|
||||
}
|
||||
frameTime = getTickCount() - frameTime;
|
||||
timeTotal += frameTime;
|
||||
}
|
||||
imshow( "Tracking API", image );
|
||||
frameCounter++;
|
||||
}
|
||||
|
||||
char c = (char) waitKey( 2 );
|
||||
if( c == 'q' )
|
||||
break;
|
||||
if( c == 'p' )
|
||||
paused = !paused;
|
||||
}
|
||||
|
||||
double s = frameCounter / (timeTotal / getTickFrequency());
|
||||
printf("FPS: %f\n", s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print('Input video name is missing')
|
||||
exit()
|
||||
|
||||
cv.namedWindow("tracking")
|
||||
camera = cv.VideoCapture(sys.argv[1])
|
||||
ok, image=camera.read()
|
||||
if not ok:
|
||||
print('Failed to read video')
|
||||
exit()
|
||||
bbox = cv.selectROI("tracking", image)
|
||||
tracker = cv.TrackerMIL_create()
|
||||
init_once = False
|
||||
|
||||
while camera.isOpened():
|
||||
ok, image=camera.read()
|
||||
if not ok:
|
||||
print('no image to read')
|
||||
break
|
||||
|
||||
if not init_once:
|
||||
ok = tracker.init(image, bbox)
|
||||
init_once = True
|
||||
|
||||
ok, newbox = tracker.update(image)
|
||||
print(ok, newbox)
|
||||
|
||||
if ok:
|
||||
p1 = (int(newbox[0]), int(newbox[1]))
|
||||
p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
|
||||
cv.rectangle(image, p1, p2, (200,0,0))
|
||||
|
||||
cv.imshow("tracking", image)
|
||||
k = cv.waitKey(1) & 0xff
|
||||
if k == 27 : break # esc pressed
|
||||
@@ -0,0 +1,239 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
|
||||
//
|
||||
// !!! this sample requires the opencv_datasets module !!!
|
||||
//
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#ifdef HAVE_OPENCV_DATASETS
|
||||
|
||||
#include "opencv2/datasets/track_vot.hpp"
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::datasets;
|
||||
|
||||
#define NUM_TEST_FRAMES 300
|
||||
#define TEST_VIDEO_INDEX 1 //TLD Dataset Video Index from 1-10
|
||||
//#define RECORD_VIDEO_FLG
|
||||
|
||||
static Mat image;
|
||||
static Rect boundingBox;
|
||||
static bool paused;
|
||||
static bool selectObject = false;
|
||||
static bool startSelection = false;
|
||||
|
||||
static const char* keys =
|
||||
{ "{@tracker_algorithm | | Tracker algorithm }"
|
||||
"{@dataset_path |true| Dataset path }"
|
||||
"{@dataset_id |1| Dataset ID }"
|
||||
};
|
||||
|
||||
static void onMouse(int event, int x, int y, int, void*)
|
||||
{
|
||||
if (!selectObject)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_LBUTTONDOWN:
|
||||
//set origin of the bounding box
|
||||
startSelection = true;
|
||||
boundingBox.x = x;
|
||||
boundingBox.y = y;
|
||||
boundingBox.width = boundingBox.height = 0;
|
||||
break;
|
||||
case EVENT_LBUTTONUP:
|
||||
//sei with and height of the bounding box
|
||||
boundingBox.width = std::abs(x - boundingBox.x);
|
||||
boundingBox.height = std::abs(y - boundingBox.y);
|
||||
paused = false;
|
||||
selectObject = true;
|
||||
break;
|
||||
case EVENT_MOUSEMOVE:
|
||||
|
||||
if (startSelection && !selectObject)
|
||||
{
|
||||
//draw the bounding box
|
||||
Mat currentFrame;
|
||||
image.copyTo(currentFrame);
|
||||
rectangle(currentFrame, Point((int)boundingBox.x, (int)boundingBox.y), Point(x, y), Scalar(255, 0, 0), 2, 1);
|
||||
imshow("Tracking API", currentFrame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
|
||||
"TLD dataset ID: 1~10, VOT2015 dataset ID: 1~60\n"
|
||||
"-- pause video [p] and draw a bounding box around the target to start the tracker\n"
|
||||
"Example:\n"
|
||||
"./example_tracking_tracker_dataset <tracker_algorithm> <dataset_path> <dataset_id>\n"
|
||||
<< endl;
|
||||
|
||||
cout << "\n\nHot keys: \n"
|
||||
"\tq - quit the program\n"
|
||||
"\tp - pause video\n";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
string tracker_algorithm = parser.get<string>(0);
|
||||
string datasetRootPath = parser.get<string>(1);
|
||||
int datasetID = parser.get<int>(2);
|
||||
if (tracker_algorithm.empty() || datasetRootPath.empty())
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat frame;
|
||||
paused = false;
|
||||
namedWindow("Tracking API", 0);
|
||||
setMouseCallback("Tracking API", onMouse, 0);
|
||||
|
||||
//Create Tracker
|
||||
Ptr<Tracker> tracker = createTrackerByName(tracker_algorithm);
|
||||
if (!tracker)
|
||||
{
|
||||
cout << "***Error in the instantiation of the tracker...***\n";
|
||||
getchar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Init Dataset
|
||||
Ptr<TRACK_vot> dataset = TRACK_vot::create();
|
||||
dataset->load(datasetRootPath);
|
||||
dataset->initDataset(datasetID);
|
||||
|
||||
//Read first frame
|
||||
dataset->getNextFrame(frame);
|
||||
frame.copyTo(image);
|
||||
|
||||
rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1);
|
||||
imshow("Tracking API", image);
|
||||
|
||||
|
||||
bool initialized = false;
|
||||
paused = true;
|
||||
int frameCounter = 0;
|
||||
|
||||
//Time measurment
|
||||
int64 e3 = getTickCount();
|
||||
for (;;)
|
||||
{
|
||||
if (!paused)
|
||||
{
|
||||
//Time measurment
|
||||
int64 e1 = getTickCount();
|
||||
if (initialized){
|
||||
if (!dataset->getNextFrame(frame))
|
||||
break;
|
||||
frame.copyTo(image);
|
||||
}
|
||||
|
||||
if (!initialized && selectObject)
|
||||
{
|
||||
//initializes the tracker
|
||||
tracker->init(frame, boundingBox);
|
||||
initialized = true;
|
||||
}
|
||||
else if (initialized)
|
||||
{
|
||||
//updates the tracker
|
||||
if (tracker->update(frame, boundingBox))
|
||||
{
|
||||
rectangle(image, boundingBox, Scalar(255, 0, 0), 2, 1);
|
||||
}
|
||||
}
|
||||
imshow("Tracking API", image);
|
||||
frameCounter++;
|
||||
//Time measurment
|
||||
int64 e2 = getTickCount();
|
||||
double t1 = (e2 - e1) / getTickFrequency();
|
||||
cout << frameCounter << "\tframe : " << t1 * 1000.0 << "ms" << endl;
|
||||
}
|
||||
|
||||
char c = (char)waitKey(2);
|
||||
if (c == 'q')
|
||||
break;
|
||||
if (c == 'p')
|
||||
paused = !paused;
|
||||
|
||||
|
||||
|
||||
//waitKey(0);
|
||||
}
|
||||
|
||||
//Time measurment
|
||||
int64 e4 = getTickCount();
|
||||
double t2 = (e4 - e3) / getTickFrequency();
|
||||
cout << "Average Time for Frame: " << t2 * 1000.0 / frameCounter << "ms" << endl;
|
||||
cout << "Average FPS: " << 1.0 / t2*frameCounter << endl;
|
||||
|
||||
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else // ! HAVE_OPENCV_DATASETS
|
||||
#include <opencv2/core.hpp>
|
||||
int main() {
|
||||
CV_Error(cv::Error::StsNotImplemented , "this sample needs to be built with opencv_datasets !");
|
||||
return -1;
|
||||
}
|
||||
#endif // HAVE_OPENCV_DATASETS
|
||||
@@ -0,0 +1,255 @@
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/tracking/tracking_by_matching.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_OPENCV_DNN
|
||||
#include <opencv2/dnn.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::detail::tracking;
|
||||
using namespace cv::detail::tracking::tbm;
|
||||
|
||||
static const char* keys =
|
||||
{ "{video_name | | video name }"
|
||||
"{start_frame |0| Start frame }"
|
||||
"{frame_step |1| Frame step }"
|
||||
"{detector_model | | Path to detector's Caffe model }"
|
||||
"{detector_weights | | Path to detector's Caffe weights }"
|
||||
"{desired_class_id |-1| The desired class that should be tracked }"
|
||||
};
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "\nThis example shows the functionality of \"Tracking-by-Matching\" approach:"
|
||||
" detector is used to detect objects on frames, \n"
|
||||
"matching is used to find correspondences between new detections and tracked objects.\n"
|
||||
"Detection is made by DNN detection network every `--frame_step` frame.\n"
|
||||
"Point a .prototxt file of the network as the parameter `--detector_model`, and a .caffemodel file"
|
||||
" as the parameter `--detector_weights`.\n"
|
||||
"(As an example of such detection network is a popular MobileNet_SSD network trained on VOC dataset.)\n"
|
||||
"If `--desired_class_id` parameter is set, the detection result is filtered by class id,"
|
||||
" returned by the detection network.\n"
|
||||
"(That is, if a detection net was trained on VOC dataset, then to track pedestrians point --desired_class_id=15)\n"
|
||||
"Example of <video_name> is in opencv_extra/testdata/cv/tracking/\n"
|
||||
"Call:\n"
|
||||
"./example_tracking_tracking_by_matching --video_name=<video_name> --detector_model=<detector_model_path> --detector_weights=<detector_weights_path> \\\n"
|
||||
" [--start_frame=<start_frame>] \\\n"
|
||||
" [--frame_step=<frame_step>] \\\n"
|
||||
" [--desired_class_id=<desired_class_id>]\n"
|
||||
<< endl;
|
||||
|
||||
cout << "\n\nHot keys: \n"
|
||||
"\tq - quit the program\n"
|
||||
"\tp - pause/resume video\n";
|
||||
}
|
||||
|
||||
cv::Ptr<ITrackerByMatching> createTrackerByMatchingWithFastDescriptor();
|
||||
|
||||
class DnnObjectDetector
|
||||
{
|
||||
public:
|
||||
DnnObjectDetector(const String& net_caffe_model_path, const String& net_caffe_weights_path,
|
||||
int desired_class_id=-1,
|
||||
float confidence_threshold = 0.2,
|
||||
//the following parameters are default for popular MobileNet_SSD caffe model
|
||||
const String& net_input_name="data",
|
||||
const String& net_output_name="detection_out",
|
||||
double net_scalefactor=0.007843,
|
||||
const Size& net_size = Size(300,300),
|
||||
const Scalar& net_mean = Scalar(127.5, 127.5, 127.5),
|
||||
bool net_swapRB=false)
|
||||
:desired_class_id(desired_class_id),
|
||||
confidence_threshold(confidence_threshold),
|
||||
net_input_name(net_input_name),
|
||||
net_output_name(net_output_name),
|
||||
net_scalefactor(net_scalefactor),
|
||||
net_size(net_size),
|
||||
net_mean(net_mean),
|
||||
net_swapRB(net_swapRB)
|
||||
{
|
||||
net = dnn::readNet(net_caffe_weights_path, net_caffe_model_path);
|
||||
if (net.empty())
|
||||
CV_Error(Error::StsError, "Cannot read Caffe net");
|
||||
}
|
||||
TrackedObjects detect(const cv::Mat& frame, int frame_idx)
|
||||
{
|
||||
Mat resized_frame;
|
||||
resize(frame, resized_frame, net_size);
|
||||
Mat inputBlob = cv::dnn::blobFromImage(resized_frame, net_scalefactor, net_size, net_mean, net_swapRB);
|
||||
|
||||
net.setInput(inputBlob, net_input_name);
|
||||
Mat detection = net.forward(net_output_name);
|
||||
Mat detection_as_mat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
|
||||
|
||||
TrackedObjects res;
|
||||
for (int i = 0; i < detection_as_mat.rows; i++)
|
||||
{
|
||||
float cur_confidence = detection_as_mat.at<float>(i, 2);
|
||||
int cur_class_id = static_cast<int>(detection_as_mat.at<float>(i, 1));
|
||||
int x_left = static_cast<int>(detection_as_mat.at<float>(i, 3) * frame.cols);
|
||||
int y_bottom = static_cast<int>(detection_as_mat.at<float>(i, 4) * frame.rows);
|
||||
int x_right = static_cast<int>(detection_as_mat.at<float>(i, 5) * frame.cols);
|
||||
int y_top = static_cast<int>(detection_as_mat.at<float>(i, 6) * frame.rows);
|
||||
|
||||
Rect cur_rect(x_left, y_bottom, (x_right - x_left), (y_top - y_bottom));
|
||||
|
||||
if (cur_confidence < confidence_threshold)
|
||||
continue;
|
||||
if ((desired_class_id >= 0) && (cur_class_id != desired_class_id))
|
||||
continue;
|
||||
|
||||
//clipping by frame size
|
||||
cur_rect = cur_rect & Rect(Point(), frame.size());
|
||||
if (cur_rect.empty())
|
||||
continue;
|
||||
|
||||
TrackedObject cur_obj(cur_rect, cur_confidence, frame_idx, -1);
|
||||
res.push_back(cur_obj);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
private:
|
||||
cv::dnn::Net net;
|
||||
int desired_class_id;
|
||||
float confidence_threshold;
|
||||
String net_input_name;
|
||||
String net_output_name;
|
||||
double net_scalefactor;
|
||||
Size net_size;
|
||||
Scalar net_mean;
|
||||
bool net_swapRB;
|
||||
};
|
||||
|
||||
cv::Ptr<ITrackerByMatching>
|
||||
createTrackerByMatchingWithFastDescriptor() {
|
||||
tbm::TrackerParams params;
|
||||
|
||||
cv::Ptr<ITrackerByMatching> tracker = createTrackerByMatching(params);
|
||||
|
||||
std::shared_ptr<IImageDescriptor> descriptor_fast =
|
||||
std::make_shared<ResizedImageDescriptor>(
|
||||
cv::Size(16, 32), cv::InterpolationFlags::INTER_LINEAR);
|
||||
std::shared_ptr<IDescriptorDistance> distance_fast =
|
||||
std::make_shared<MatchTemplateDistance>();
|
||||
|
||||
tracker->setDescriptorFast(descriptor_fast);
|
||||
tracker->setDistanceFast(distance_fast);
|
||||
|
||||
return tracker;
|
||||
}
|
||||
int main( int argc, char** argv ){
|
||||
CommandLineParser parser( argc, argv, keys );
|
||||
cv::Ptr<ITrackerByMatching> tracker = createTrackerByMatchingWithFastDescriptor();
|
||||
|
||||
String video_name = parser.get<String>("video_name");
|
||||
int start_frame = parser.get<int>("start_frame");
|
||||
int frame_step = parser.get<int>("frame_step");
|
||||
String detector_model = parser.get<String>("detector_model");
|
||||
String detector_weights = parser.get<String>("detector_weights");
|
||||
int desired_class_id = parser.get<int>("desired_class_id");
|
||||
|
||||
if( video_name.empty() || detector_model.empty() || detector_weights.empty() )
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//open the capture
|
||||
VideoCapture cap;
|
||||
cap.open( video_name );
|
||||
cap.set( CAP_PROP_POS_FRAMES, start_frame );
|
||||
|
||||
if( !cap.isOpened() )
|
||||
{
|
||||
help();
|
||||
cout << "***Could not initialize capturing...***\n";
|
||||
cout << "Current parameter's value: \n";
|
||||
parser.printMessage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If you use the popular MobileNet_SSD detector, the default parameters may be used.
|
||||
// Otherwise, set your own parameters (net_mean, net_scalefactor, etc).
|
||||
DnnObjectDetector detector(detector_model, detector_weights, desired_class_id);
|
||||
|
||||
Mat frame;
|
||||
namedWindow( "Tracking by Matching", 1 );
|
||||
|
||||
int frame_counter = -1;
|
||||
int64 time_total = 0;
|
||||
bool paused = false;
|
||||
for ( ;; )
|
||||
{
|
||||
if( paused )
|
||||
{
|
||||
char c = (char) waitKey(30);
|
||||
if (c == 'p')
|
||||
paused = !paused;
|
||||
if (c == 'q')
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
cap >> frame;
|
||||
if(frame.empty()){
|
||||
break;
|
||||
}
|
||||
frame_counter++;
|
||||
if (frame_counter < start_frame)
|
||||
continue;
|
||||
if (frame_counter % frame_step != 0)
|
||||
continue;
|
||||
|
||||
|
||||
int64 frame_time = getTickCount();
|
||||
|
||||
TrackedObjects detections = detector.detect(frame, frame_counter);
|
||||
|
||||
// timestamp in milliseconds
|
||||
uint64_t cur_timestamp = static_cast<uint64_t>(1000.0 / 30 * frame_counter);
|
||||
tracker->process(frame, detections, cur_timestamp);
|
||||
|
||||
frame_time = getTickCount() - frame_time;
|
||||
time_total += frame_time;
|
||||
|
||||
// Drawing colored "worms" (tracks).
|
||||
frame = tracker->drawActiveTracks(frame);
|
||||
|
||||
|
||||
// Drawing all detected objects on a frame by BLUE COLOR
|
||||
for (const auto &detection : detections) {
|
||||
cv::rectangle(frame, detection.rect, cv::Scalar(255, 0, 0), 3);
|
||||
}
|
||||
|
||||
// Drawing tracked detections only by RED color and print ID and detection
|
||||
// confidence level.
|
||||
for (const auto &detection : tracker->trackedDetections()) {
|
||||
cv::rectangle(frame, detection.rect, cv::Scalar(0, 0, 255), 3);
|
||||
std::string text = std::to_string(detection.object_id) +
|
||||
" conf: " + std::to_string(detection.confidence);
|
||||
cv::putText(frame, text, detection.rect.tl(), cv::FONT_HERSHEY_COMPLEX,
|
||||
1.0, cv::Scalar(0, 0, 255), 3);
|
||||
}
|
||||
|
||||
imshow( "Tracking by Matching", frame );
|
||||
|
||||
char c = (char) waitKey( 2 );
|
||||
if (c == 'q')
|
||||
break;
|
||||
if (c == 'p')
|
||||
paused = !paused;
|
||||
}
|
||||
|
||||
double s = frame_counter / (time_total / getTickFrequency());
|
||||
printf("FPS: %f\n", s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else // #ifdef HAVE_OPENCV_DNN
|
||||
int main(int, char**){
|
||||
CV_Error(cv::Error::StsNotImplemented, "At the moment the sample 'tracking_by_matching' can work only when opencv_dnn module is built.");
|
||||
}
|
||||
#endif // #ifdef HAVE_OPENCV_DNN
|
||||
@@ -0,0 +1,128 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
// prototype of the functino for feature extractor
|
||||
void sobelExtractor(const Mat img, const Rect roi, Mat& feat);
|
||||
|
||||
int main( int argc, char** argv ){
|
||||
// show help
|
||||
if(argc<2){
|
||||
cout<<
|
||||
" Usage: tracker <video_name>\n"
|
||||
" examples:\n"
|
||||
" example_tracking_kcf Bolt/img/%04d.jpg\n"
|
||||
" example_tracking_kcf faceocc2.webm\n"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// declares all required variables
|
||||
Rect roi;
|
||||
Mat frame;
|
||||
|
||||
//! [param]
|
||||
TrackerKCF::Params param;
|
||||
param.desc_pca = TrackerKCF::GRAY | TrackerKCF::CN;
|
||||
param.desc_npca = 0;
|
||||
param.compress_feature = true;
|
||||
param.compressed_size = 2;
|
||||
//! [param]
|
||||
|
||||
// create a tracker object
|
||||
//! [create]
|
||||
Ptr<TrackerKCF> tracker = TrackerKCF::create(param);
|
||||
//! [create]
|
||||
|
||||
//! [setextractor]
|
||||
tracker->setFeatureExtractor(sobelExtractor);
|
||||
//! [setextractor]
|
||||
|
||||
// set input video
|
||||
std::string video = argv[1];
|
||||
VideoCapture cap(video);
|
||||
|
||||
// get bounding box
|
||||
cap >> frame;
|
||||
roi=selectROI("tracker",frame);
|
||||
|
||||
//quit if ROI was not selected
|
||||
if(roi.width==0 || roi.height==0)
|
||||
return 0;
|
||||
|
||||
// initialize the tracker
|
||||
tracker->init(frame,roi);
|
||||
|
||||
// perform the tracking process
|
||||
printf("Start the tracking process, press ESC to quit.\n");
|
||||
for ( ;; ){
|
||||
// get frame from the video
|
||||
cap >> frame;
|
||||
|
||||
// stop the program if no more images
|
||||
if(frame.rows==0 || frame.cols==0)
|
||||
break;
|
||||
|
||||
// update the tracking result
|
||||
tracker->update(frame,roi);
|
||||
|
||||
// draw the tracked object
|
||||
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
|
||||
|
||||
// show image with the tracked object
|
||||
imshow("tracker",frame);
|
||||
|
||||
//quit on ESC button
|
||||
if(waitKey(1)==27)break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sobelExtractor(const Mat img, const Rect roi, Mat& feat){
|
||||
Mat sobel[2];
|
||||
Mat patch;
|
||||
Rect region=roi;
|
||||
|
||||
//! [insideimage]
|
||||
// extract patch inside the image
|
||||
if(roi.x<0){region.x=0;region.width+=roi.x;}
|
||||
if(roi.y<0){region.y=0;region.height+=roi.y;}
|
||||
if(roi.x+roi.width>img.cols)region.width=img.cols-roi.x;
|
||||
if(roi.y+roi.height>img.rows)region.height=img.rows-roi.y;
|
||||
if(region.width>img.cols)region.width=img.cols;
|
||||
if(region.height>img.rows)region.height=img.rows;
|
||||
//! [insideimage]
|
||||
|
||||
patch=img(region).clone();
|
||||
cvtColor(patch,patch, COLOR_BGR2GRAY);
|
||||
|
||||
//! [padding]
|
||||
// add some padding to compensate when the patch is outside image border
|
||||
int addTop,addBottom, addLeft, addRight;
|
||||
addTop=region.y-roi.y;
|
||||
addBottom=(roi.height+roi.y>img.rows?roi.height+roi.y-img.rows:0);
|
||||
addLeft=region.x-roi.x;
|
||||
addRight=(roi.width+roi.x>img.cols?roi.width+roi.x-img.cols:0);
|
||||
|
||||
copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
|
||||
//! [padding]
|
||||
|
||||
//! [sobel]
|
||||
Sobel(patch, sobel[0], CV_32F,1,0,1);
|
||||
Sobel(patch, sobel[1], CV_32F,0,1,1);
|
||||
|
||||
merge(sobel,2,feat);
|
||||
//! [sobel]
|
||||
|
||||
//! [postprocess]
|
||||
feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
|
||||
//! [postprocess]
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main( int argc, char** argv ){
|
||||
// show help
|
||||
//! [help]
|
||||
if(argc<2){
|
||||
cout<<
|
||||
" Usage: tracker <video_name>\n"
|
||||
" examples:\n"
|
||||
" example_tracking_kcf Bolt/img/%04d.jpg\n"
|
||||
" example_tracking_kcf faceocc2.webm\n"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
//! [help]
|
||||
|
||||
// declares all required variables
|
||||
//! [vars]
|
||||
Rect roi;
|
||||
Mat frame;
|
||||
//! [vars]
|
||||
|
||||
// create a tracker object
|
||||
//! [create]
|
||||
Ptr<Tracker> tracker = TrackerKCF::create();
|
||||
//! [create]
|
||||
|
||||
// set input video
|
||||
//! [setvideo]
|
||||
std::string video = argv[1];
|
||||
VideoCapture cap(video);
|
||||
//! [setvideo]
|
||||
|
||||
// get bounding box
|
||||
//! [getframe]
|
||||
cap >> frame;
|
||||
//! [getframe]
|
||||
//! [selectroi]
|
||||
roi=selectROI("tracker",frame);
|
||||
//! [selectroi]
|
||||
|
||||
//quit if ROI was not selected
|
||||
if(roi.width==0 || roi.height==0)
|
||||
return 0;
|
||||
|
||||
// initialize the tracker
|
||||
//! [init]
|
||||
tracker->init(frame,roi);
|
||||
//! [init]
|
||||
|
||||
// perform the tracking process
|
||||
printf("Start the tracking process, press ESC to quit.\n");
|
||||
for ( ;; ){
|
||||
// get frame from the video
|
||||
cap >> frame;
|
||||
|
||||
// stop the program if no more images
|
||||
if(frame.rows==0 || frame.cols==0)
|
||||
break;
|
||||
|
||||
// update the tracking result
|
||||
//! [update]
|
||||
tracker->update(frame,roi);
|
||||
//! [update]
|
||||
|
||||
//! [visualization]
|
||||
// draw the tracked object
|
||||
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
|
||||
|
||||
// show image with the tracked object
|
||||
imshow("tracker",frame);
|
||||
//! [visualization]
|
||||
|
||||
//quit on ESC button
|
||||
if(waitKey(1)==27)break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*----------------------------------------------
|
||||
* Usage:
|
||||
* example_tracking_multitracker <video_name> [algorithm]
|
||||
*
|
||||
* example:
|
||||
* example_tracking_multitracker Bolt/img/%04d.jpg
|
||||
* example_tracking_multitracker faceocc2.webm KCF
|
||||
*--------------------------------------------------*/
|
||||
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/tracking.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include "samples_utility.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main( int argc, char** argv ){
|
||||
// show help
|
||||
if(argc<2){
|
||||
cout<<
|
||||
" Usage: example_tracking_multitracker <video_name> [algorithm]\n"
|
||||
" examples:\n"
|
||||
" example_tracking_multitracker Bolt/img/%04d.jpg\n"
|
||||
" example_tracking_multitracker faceocc2.webm MEDIANFLOW\n"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set the default tracking algorithm
|
||||
std::string trackingAlg = "KCF";
|
||||
|
||||
// set the tracking algorithm from parameter
|
||||
if(argc>2)
|
||||
trackingAlg = argv[2];
|
||||
|
||||
// create the tracker
|
||||
//! [create]
|
||||
legacy::MultiTracker trackers;
|
||||
//! [create]
|
||||
|
||||
// container of the tracked objects
|
||||
//! [roi]
|
||||
vector<Rect2d> objects;
|
||||
//! [roi]
|
||||
|
||||
// set input video
|
||||
std::string video = argv[1];
|
||||
VideoCapture cap(video);
|
||||
|
||||
Mat frame;
|
||||
|
||||
// get bounding box
|
||||
cap >> frame;
|
||||
//! [selectmulti]
|
||||
vector<Rect> ROIs;
|
||||
selectROIs("tracker",frame,ROIs);
|
||||
//! [selectmulti]
|
||||
|
||||
//quit when the tracked object(s) is not provided
|
||||
if(ROIs.size()<1)
|
||||
return 0;
|
||||
|
||||
// initialize the tracker
|
||||
//! [init]
|
||||
std::vector<Ptr<legacy::Tracker> > algorithms;
|
||||
for (size_t i = 0; i < ROIs.size(); i++)
|
||||
{
|
||||
algorithms.push_back(createTrackerByName_legacy(trackingAlg));
|
||||
objects.push_back(ROIs[i]);
|
||||
}
|
||||
|
||||
trackers.add(algorithms,frame,objects);
|
||||
//! [init]
|
||||
|
||||
// do the tracking
|
||||
printf("Start the tracking process, press ESC to quit.\n");
|
||||
for ( ;; ){
|
||||
// get frame from the video
|
||||
cap >> frame;
|
||||
|
||||
// stop the program if no more images
|
||||
if(frame.rows==0 || frame.cols==0)
|
||||
break;
|
||||
|
||||
//update the tracking result
|
||||
//! [update]
|
||||
trackers.update(frame);
|
||||
//! [update]
|
||||
|
||||
//! [result]
|
||||
// draw the tracked object
|
||||
for(unsigned i=0;i<trackers.getObjects().size();i++)
|
||||
rectangle( frame, trackers.getObjects()[i], Scalar( 255, 0, 0 ), 2, 1 );
|
||||
//! [result]
|
||||
|
||||
// show image with the tracked object
|
||||
imshow("tracker",frame);
|
||||
|
||||
//quit on ESC button
|
||||
if(waitKey(1)==27)break;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user