Commit c27db0d1 authored by Alex Leontiev's avatar Alex Leontiev

Tracking-Learning-Detection and MedianFlow

This contribution includes the following logical components into
tracking module:

.) Change Rect to Rect2d into headers for Tracker's methods;
This contribution includes the following logical components into
tracking module:

.) Change Rect to Rect2d into headers for Tracker's methods;
.) MedianFlow tracker;
.) extensible benchmark to compare trackers interactively and
	assess them quantitatively;
.) TLD tracker (work-in-progress);

Work was funded by Google Summer of Code 2014 initiative. Mentors:
Gary
Bradski and Vadim Pisarevsky.
parent ed3e4506
set(the_description "Tracking API")
ocv_define_module(tracking opencv_imgproc opencv_optim)
ocv_define_module(tracking opencv_imgproc opencv_optim opencv_video opencv_highgui)
......@@ -39,8 +39,8 @@
//
//M*/
#ifndef __OPENCV_TRACKING_HPP__
#define __OPENCV_TRACKING_HPP__
#ifndef __OPENCV_TRACKING_LENLEN_HPP__
#define __OPENCV_TRACKING_LENLEN_HPP__
#include "opencv2/core/cvdef.h"
......@@ -50,5 +50,4 @@ CV_EXPORTS bool initModule_tracking(void);
}
#include "opencv2/tracking/tracker.hpp"
#endif //__OPENCV_TRACKING_HPP__
#endif //__OPENCV_TRACKING_LENLEN
......@@ -1005,6 +1005,58 @@ class CV_EXPORTS_W TrackerBoosting : public Tracker
BOILERPLATE_CODE("BOOSTING",TrackerBoosting);
};
/**
\brief Median Flow tracker implementation.
Implementation of a paper "Forward-Backward Error: Automatic Detection of Tracking Failures" by Z. Kalal, K. Mikolajczyk
and Jiri Matas.
*/
class CV_EXPORTS_W TrackerMedianFlow : public Tracker
{
public:
struct CV_EXPORTS Params
{
Params();
int pointsInGrid;
void read( const FileNode& /*fn*/ );
void write( FileStorage& /*fs*/ ) const;
};
TrackerMedianFlow( const TrackerMedianFlow::Params &parameters = TrackerMedianFlow::Params() );
virtual ~TrackerMedianFlow();
void read( const FileNode& fn );
void write( FileStorage& fs ) const;
protected:
bool initImpl( const Mat& image, const Rect2d& boundingBox );
bool updateImpl( const Mat& image, Rect2d& boundingBox );
Params params;
AlgorithmInfo* info() const;
};
class CV_EXPORTS_W TrackerTLD : public Tracker
{
public:
struct CV_EXPORTS Params
{
Params();
void read( const FileNode& /*fn*/ );
void write( FileStorage& /*fs*/ ) const;
};
TrackerTLD( const TrackerTLD::Params &parameters = TrackerTLD::Params() );
virtual ~TrackerTLD();
void read( const FileNode& fn );
void write( FileStorage& fs ) const;
class Private{public: virtual ~Private(){}};
protected:
bool initImpl( const Mat& image, const Rect2d& boundingBox );
bool updateImpl( const Mat& image, Rect2d& boundingBox );
Params params;
std::vector<Ptr<Private> > privateInfo;
AlgorithmInfo* info() const;
};
} /* namespace cv */
#endif
This diff is collapsed.
......@@ -2,6 +2,7 @@
#include <opencv2/tracking.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
using namespace std;
using namespace cv;
......@@ -15,21 +16,20 @@ static bool startSelection = false;
static const char* keys =
{ "{@tracker_algorithm | | Tracker algorithm }"
"{@video_name | | video name }"
"{@start_frame |1| Start frame }"
"{@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"
<< endl;
cout << "\n\nHot keys: \n"
"\tq - quit the program\n"
"\tp - pause video\n";
static void listTrackers(){
vector<String> algorithms;
Algorithm::getList(algorithms);
cout << "\nAvailable tracker algorithms:\n";
for (size_t i=0; i < algorithms.size(); i++){
const char* algoname=algorithms[i].c_str();
char *pos=NULL;
if((pos=strstr((char*)algoname,"TRACKER."))!=NULL){
printf("%s\n",pos+8);
}
}
}
static void onMouse( int event, int x, int y, int, void* )
......@@ -58,7 +58,7 @@ static void onMouse( int event, int x, int y, int, void* )
//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 );
rectangle( currentFrame, Point( boundingBox.x, boundingBox.y ), Point( x, y ), Scalar( 255, 0, 0 ), 2, 1 );
imshow( "Tracking API", currentFrame );
}
break;
......@@ -66,8 +66,22 @@ static void onMouse( int event, int x, int y, int, void* )
}
}
int main( int argc, char** argv )
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"
<< endl;
cout << "\n\nHot keys: \n"
"\tq - quit the program\n"
"\tp - pause video\n";
listTrackers();
}
int main( int argc, char** argv ){
CommandLineParser parser( argc, argv, keys );
String tracker_algorithm = parser.get<String>( 0 );
......@@ -81,24 +95,19 @@ int main( int argc, char** argv )
}
int coords[4]={0,0,0,0};
bool initFrameWasGivenInCommandLine=false;
do
{
bool initBoxWasGivenInCommandLine=false;
do{
String initBoundingBox=parser.get<String>(3);
for(size_t pos=0,ctr=0;ctr<4;ctr++)
{
size_t npos=initBoundingBox.find_first_of(',',pos);
if(npos==string::npos && ctr<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 cordinates 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)
{
if(num<=0){
printf("bounding box should be given in format \"x1,y1,x2,y2\",where x's and y's are integer cordinates 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");
......@@ -107,9 +116,10 @@ int main( int argc, char** argv )
coords[ctr]=num;
pos=npos+1;
}
if(coords[0]>0 && coords[1]>0 && coords[2]>0 && coords[3]>0)
initFrameWasGivenInCommandLine=true;
} while((void)0, 0);
if(coords[0]>0 && coords[1]>0 && coords[2]>0 && coords[3]>0){
initBoxWasGivenInCommandLine=true;
}
}while(0);
//open the capture
VideoCapture cap;
......@@ -141,7 +151,7 @@ int main( int argc, char** argv )
//get the first frame
cap >> frame;
frame.copyTo( image );
if(initFrameWasGivenInCommandLine){
if(initBoxWasGivenInCommandLine){
selectObject=true;
paused=false;
boundingBox.x = coords[0];
......@@ -160,15 +170,14 @@ int main( int argc, char** argv )
{
if( !paused )
{
cap >> frame;
if( frame.empty() )
{
break;
if(initialized){
cap >> frame;
if(frame.empty()){
break;
}
frame.copyTo( image );
}
frame.copyTo( image );
if( !initialized && selectObject )
{
//initializes the tracker
......
This diff is collapsed.
/*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 "precomp.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc.hpp"
#include <algorithm>
#include <limits.h>
using namespace cv;
namespace cv
{
//debug functions and variables
#define MEASURE_TIME(a) {\
clock_t start;float milisec=0.0;\
start=clock();{a} milisec=1000.0*(clock()-start)/CLOCKS_PER_SEC;\
printf("%-90s took %f milis\n",#a,milisec); }
#define HERE fprintf(stderr,"%d\n",__LINE__);fflush(stderr);
#define START_TICK(name) { clock_t start;float milisec=0.0; start=clock();
#define END_TICK(name) milisec=1000.0*(clock()-start)/CLOCKS_PER_SEC;\
printf("%s took %f milis\n",name,milisec); }
extern Rect2d etalon;
void myassert(const Mat& img);
void printPatch(const Mat_<uchar>& standardPatch);
std::string type2str(const Mat& mat);
void drawWithRects(const Mat& img,std::vector<Rect2d>& blackOnes,Rect2d whiteOne=Rect2d(-1.0,-1.0,-1.0,-1.0));
void drawWithRects(const Mat& img,std::vector<Rect2d>& blackOnes,std::vector<Rect2d>& whiteOnes);
//aux functions and variables
#define CLIP(x,a,b) MIN(MAX((x),(a)),(b))
double overlap(const Rect2d& r1,const Rect2d& r2);
void resample(const Mat& img,const RotatedRect& r2,Mat_<uchar>& samples);
void resample(const Mat& img,const Rect2d& r2,Mat_<uchar>& samples);
double variance(const Mat& img);
double variance(Mat_<unsigned int>& intImgP,Mat_<unsigned int>& intImgP2,Rect box);
double NCC(Mat_<uchar> patch1,Mat_<uchar> patch2);
void getClosestN(std::vector<Rect2d>& scanGrid,Rect2d bBox,int n,std::vector<Rect2d>& res);
double scaleAndBlur(const Mat& originalImg,int scale,Mat& scaledImg,Mat& blurredImg,Size GaussBlurKernelSize);
unsigned int getMedian(const std::vector<unsigned int>& values, int size=-1);
class TLDEnsembleClassifier{
public:
TLDEnsembleClassifier(int ordinal,Size size);
void integrate(Mat_<uchar> patch,bool isPositive);
double posteriorProbability(const uchar* data,int rowstep)const;
static int getMaxOrdinal();
private:
static int getGridSize();
inline void stepPrefSuff(uchar* arr,int len);
void preinit(int ordinal);
unsigned short int code(const uchar* data,int rowstep)const;
unsigned int pos[8192],neg[8192];//8192=2^13
uchar x1[13],y1[13],x2[13],y2[13];
};
class TrackerProxy : public TrackerTLD::Private{
public:
virtual bool init( const Mat& image, const Rect2d& boundingBox)=0;
virtual bool update(const Mat& image, Rect2d& boundingBox)=0;
virtual ~TrackerProxy(){}
};
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -78,7 +78,7 @@ bool Tracker::init( const Mat& image, const Rect2d& boundingBox )
//check if the model component is initialized
if( model == 0 )
{
CV_Error( -1, "The model are not initialized" );
CV_Error( -1, "The model is not initialized" );
return false;
}
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment