tracking: move Tracking API to the main repository

pull/2753/head
Alexander Alekhin 4 years ago
parent f1c3d0e5e7
commit a51b1b1e94
  1. 4
      modules/tracking/CMakeLists.txt
  2. 38
      modules/tracking/doc/tracking.bib
  3. 114
      modules/tracking/include/opencv2/tracking.hpp
  4. 2
      modules/tracking/include/opencv2/tracking/feature.hpp
  5. 119
      modules/tracking/include/opencv2/tracking/onlineMIL.hpp
  6. 547
      modules/tracking/include/opencv2/tracking/tracking_internals.hpp
  7. 8
      modules/tracking/include/opencv2/tracking/tracking_legacy.hpp
  8. 7
      modules/tracking/misc/java/test/TrackerCreateTest.java
  9. 2
      modules/tracking/misc/python/pyopencv_tracking.hpp
  10. 17
      modules/tracking/perf/perf_trackers.cpp
  11. 177
      modules/tracking/src/gtrTracker.cpp
  12. 16
      modules/tracking/src/legacy/tracker.legacy.hpp
  13. 4
      modules/tracking/src/legacy/trackerCSRT.legacy.hpp
  14. 4
      modules/tracking/src/legacy/trackerKCF.legacy.hpp
  15. 381
      modules/tracking/src/onlineMIL.cpp
  16. 16
      modules/tracking/src/tracker.cpp
  17. 24
      modules/tracking/src/trackerBoosting.cpp
  18. 38
      modules/tracking/src/trackerFeature.cpp
  19. 24
      modules/tracking/src/trackerFeatureSet.cpp
  20. 265
      modules/tracking/src/trackerMIL.cpp
  21. 126
      modules/tracking/src/trackerMILModel.cpp
  22. 102
      modules/tracking/src/trackerMILModel.hpp
  23. 26
      modules/tracking/src/trackerMIL_legacy.cpp
  24. 178
      modules/tracking/src/trackerModel.cpp
  25. 20
      modules/tracking/src/trackerSampler.cpp
  26. 28
      modules/tracking/src/trackerSamplerAlgorithm.cpp
  27. 181
      modules/tracking/src/trackerStateEstimator.cpp
  28. 457
      modules/tracking/test/test_trackers.cpp

@ -22,3 +22,7 @@ ocv_define_module(tracking
)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-shadow /wd4458)
if(TARGET opencv_test_${name})
ocv_target_include_directories(opencv_test_${name} "${OpenCV_SOURCE_DIR}/modules") # use common files from video tests
endif()

@ -1,12 +1,3 @@
@inproceedings{MIL,
title={Visual tracking with online multiple instance learning},
author={Babenko, Boris and Yang, Ming-Hsuan and Belongie, Serge},
booktitle={Computer Vision and Pattern Recognition, 2009. CVPR 2009. IEEE Conference on},
pages={983--990},
year={2009},
organization={IEEE}
}
@inproceedings{OLB,
title={Real-Time Tracking via On-line Boosting.},
author={Grabner, Helmut and Grabner, Michael and Bischof, Horst},
@ -37,28 +28,6 @@
publisher={IEEE}
}
@article{AAM,
title={Adaptive appearance modeling for video tracking: survey and evaluation},
author={Salti, Samuele and Cavallaro, Andrea and Di Stefano, Luigi},
journal={Image Processing, IEEE Transactions on},
volume={21},
number={10},
pages={4334--4348},
year={2012},
publisher={IEEE}
}
@article{AMVOT,
title={A survey of appearance models in visual object tracking},
author={Li, Xi and Hu, Weiming and Shen, Chunhua and Zhang, Zhongfei and Dick, Anthony and Hengel, Anton Van Den},
journal={ACM Transactions on Intelligent Systems and Technology (TIST)},
volume={4},
number={4},
pages={58},
year={2013},
publisher={ACM}
}
@inproceedings{OOT,
title={Online object tracking: A benchmark},
author={Wu, Yi and Lim, Jongwoo and Yang, Ming-Hsuan},
@ -94,13 +63,6 @@
doi={10.1109/CVPR.2014.143},
}
@inproceedings{GOTURN,
title={Learning to Track at 100 FPS with Deep Regression Networks},
author={Held, David and Thrun, Sebastian and Savarese, Silvio},
booktitle = {European Conference Computer Vision (ECCV)},
year = {2016}
}
@inproceedings{MOSSE,
title={Visual Object Tracking using Adaptive Correlation Filters},
author={Bolme, David S. and Beveridge, J. Ross and Draper, Bruce A. and Lui Yui, Man},

@ -6,6 +6,7 @@
#define OPENCV_CONTRIB_TRACKING_HPP
#include "opencv2/core.hpp"
#include "opencv2/video/tracking.hpp"
namespace cv {
#ifndef CV_DOXYGEN
@ -26,37 +27,6 @@ The development in this area is very fragmented and this API is an interface use
*/
/** @brief Base abstract class for the long-term tracker
*/
class CV_EXPORTS_W Tracker
{
protected:
Tracker();
public:
virtual ~Tracker();
/** @brief Initialize the tracker with a known bounding box that surrounded the target
@param image The initial frame
@param boundingBox The initial bounding box
*/
CV_WRAP virtual
void init(InputArray image, const Rect& boundingBox) = 0;
/** @brief Update the tracker, find the new most likely bounding box for the target
@param image The current frame
@param boundingBox The bounding box that represent the new target location, if true was returned, not
modified otherwise
@return True means that target was located and false means that tracker cannot locate target in
current frame. Note, that latter *does not* imply that tracker has failed, maybe target is indeed
missing from the frame (say, out of sight)
*/
CV_WRAP virtual
bool update(InputArray image, CV_OUT Rect& boundingBox) = 0;
};
/** @brief the CSRT tracker
The implementation is based on @cite Lukezic_IJCV2018 Discriminative Correlation Filter with Channel and Spatial Reliability
@ -117,7 +87,6 @@ public:
};
/** @brief the KCF (Kernelized Correlation Filter) tracker
* KCF is a novel tracking framework that utilizes properties of circulant matrix to enhance the processing speed.
@ -180,87 +149,6 @@ public:
};
/** @brief The MIL algorithm trains a classifier in an online manner to separate the object from the
background.
Multiple Instance Learning avoids the drift problem for a robust tracking. The implementation is
based on @cite MIL .
Original code can be found here <http://vision.ucsd.edu/~bbabenko/project_miltrack.shtml>
*/
class CV_EXPORTS_W TrackerMIL : public Tracker
{
protected:
TrackerMIL(); // use ::create()
public:
virtual ~TrackerMIL() CV_OVERRIDE;
struct CV_EXPORTS_W_SIMPLE Params
{
CV_WRAP Params();
//parameters for sampler
CV_PROP_RW float samplerInitInRadius; //!< radius for gathering positive instances during init
CV_PROP_RW int samplerInitMaxNegNum; //!< # negative samples to use during init
CV_PROP_RW float samplerSearchWinSize; //!< size of search window
CV_PROP_RW float samplerTrackInRadius; //!< radius for gathering positive instances during tracking
CV_PROP_RW int samplerTrackMaxPosNum; //!< # positive samples to use during tracking
CV_PROP_RW int samplerTrackMaxNegNum; //!< # negative samples to use during tracking
CV_PROP_RW int featureSetNumFeatures; //!< # features
};
/** @brief Create MIL tracker instance
* @param parameters MIL parameters TrackerMIL::Params
*/
static CV_WRAP
Ptr<TrackerMIL> create(const TrackerMIL::Params &parameters = TrackerMIL::Params());
//void init(InputArray image, const Rect& boundingBox) CV_OVERRIDE;
//bool update(InputArray image, CV_OUT Rect& boundingBox) CV_OVERRIDE;
};
/** @brief the GOTURN (Generic Object Tracking Using Regression Networks) tracker
*
* GOTURN (@cite GOTURN) is kind of trackers based on Convolutional Neural Networks (CNN). While taking all advantages of CNN trackers,
* GOTURN is much faster due to offline training without online fine-tuning nature.
* GOTURN tracker addresses the problem of single target tracking: given a bounding box label of an object in the first frame of the video,
* we track that object through the rest of the video. NOTE: Current method of GOTURN does not handle occlusions; however, it is fairly
* robust to viewpoint changes, lighting changes, and deformations.
* Inputs of GOTURN are two RGB patches representing Target and Search patches resized to 227x227.
* Outputs of GOTURN are predicted bounding box coordinates, relative to Search patch coordinate system, in format X1,Y1,X2,Y2.
* Original paper is here: <http://davheld.github.io/GOTURN/GOTURN.pdf>
* As long as original authors implementation: <https://github.com/davheld/GOTURN#train-the-tracker>
* Implementation of training algorithm is placed in separately here due to 3d-party dependencies:
* <https://github.com/Auron-X/GOTURN_Training_Toolkit>
* GOTURN architecture goturn.prototxt and trained model goturn.caffemodel are accessible on opencv_extra GitHub repository.
*/
class CV_EXPORTS_W TrackerGOTURN : public Tracker
{
protected:
TrackerGOTURN(); // use ::create()
public:
virtual ~TrackerGOTURN() CV_OVERRIDE;
struct CV_EXPORTS_W_SIMPLE Params
{
CV_WRAP Params();
CV_PROP_RW std::string modelTxt;
CV_PROP_RW std::string modelBin;
};
/** @brief Constructor
@param parameters GOTURN parameters TrackerGOTURN::Params
*/
static CV_WRAP
Ptr<TrackerGOTURN> create(const TrackerGOTURN::Params& parameters = TrackerGOTURN::Params());
//void init(InputArray image, const Rect& boundingBox) CV_OVERRIDE;
//bool update(InputArray image, CV_OUT Rect& boundingBox) CV_OVERRIDE;
};
//! @}
#ifndef CV_DOXYGEN

@ -60,7 +60,7 @@ inline namespace tracking {
//! @addtogroup tracking_detail
//! @{
inline namespace feature {
inline namespace contrib_feature {
#define FEATURES "features"

@ -1,119 +0,0 @@
/*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*/
#ifndef __OPENCV_ONLINEMIL_HPP__
#define __OPENCV_ONLINEMIL_HPP__
#include "opencv2/core.hpp"
#include <limits>
namespace cv {
namespace detail {
inline namespace tracking {
//! @addtogroup tracking_detail
//! @{
//TODO based on the original implementation
//http://vision.ucsd.edu/~bbabenko/project_miltrack.shtml
class ClfOnlineStump;
class CV_EXPORTS ClfMilBoost
{
public:
struct CV_EXPORTS Params
{
Params();
int _numSel;
int _numFeat;
float _lRate;
};
ClfMilBoost();
~ClfMilBoost();
void init( const ClfMilBoost::Params &parameters = ClfMilBoost::Params() );
void update( const Mat& posx, const Mat& negx );
std::vector<float> classify( const Mat& x, bool logR = true );
inline float sigmoid( float x )
{
return 1.0f / ( 1.0f + exp( -x ) );
}
private:
uint _numsamples;
ClfMilBoost::Params _myParams;
std::vector<int> _selectors;
std::vector<ClfOnlineStump*> _weakclf;
uint _counter;
};
class ClfOnlineStump
{
public:
float _mu0, _mu1, _sig0, _sig1;
float _q;
int _s;
float _log_n1, _log_n0;
float _e1, _e0;
float _lRate;
ClfOnlineStump();
ClfOnlineStump( int ind );
void init();
void update( const Mat& posx, const Mat& negx, const cv::Mat_<float> & posw = cv::Mat_<float>(), const cv::Mat_<float> & negw = cv::Mat_<float>() );
bool classify( const Mat& x, int i );
float classifyF( const Mat& x, int i );
std::vector<float> classifySetF( const Mat& x );
private:
bool _trained;
int _ind;
};
//! @}
}}} // namespace
#endif

@ -1,43 +1,6 @@
/*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 file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_TRACKING_DETAIL_HPP
#define OPENCV_TRACKING_DETAIL_HPP
@ -52,11 +15,10 @@
*
*/
#include "opencv2/core.hpp"
#include "opencv2/video/detail/tracking.private.hpp"
#include "feature.hpp" // CvHaarEvaluator
#include "onlineBoosting.hpp" // StrongClassifierDirectSelection
#include "onlineMIL.hpp" // ClfMilBoost
namespace cv {
namespace detail {
@ -77,13 +39,13 @@ These algorithms start from a bounding box of the target and with their internal
avoid the drift during the tracking. These long-term trackers are able to evaluate online the
quality of the location of the target in the new frame, without ground truth.
There are three main components: the TrackerSampler, the TrackerFeatureSet and the TrackerModel. The
There are three main components: the TrackerContribSampler, the TrackerContribFeatureSet and the TrackerModel. The
first component is the object that computes the patches over the frame based on the last target
location. The TrackerFeatureSet is the class that manages the Features, is possible plug many kind
location. The TrackerContribFeatureSet is the class that manages the Features, is possible plug many kind
of these (HAAR, HOG, LBP, Feature2D, etc). The last component is the internal representation of the
target, it is the appearance model. It stores all state candidates and compute the trajectory (the
most likely target states). The class TrackerTargetState represents a possible state of the target.
The TrackerSampler and the TrackerFeatureSet are the visual representation of the target, instead
The TrackerContribSampler and the TrackerContribFeatureSet are the visual representation of the target, instead
the TrackerModel is the statistical model.
A recent benchmark between these algorithms can be found in @cite OOT
@ -131,25 +93,25 @@ trackerMIL, trackerBoosting) -- we shall refer to this choice as to "classname"
That function can (and probably will) return a pointer to some derived class of "classname",
which will probably have a real constructor.
Every tracker has three component TrackerSampler, TrackerFeatureSet and TrackerModel. The first two
Every tracker has three component TrackerContribSampler, TrackerContribFeatureSet and TrackerModel. The first two
are instantiated from Tracker base class, instead the last component is abstract, so you must
implement your TrackerModel.
### TrackerSampler
### TrackerContribSampler
TrackerSampler is already instantiated, but you should define the sampling algorithm and add the
classes (or single class) to TrackerSampler. You can choose one of the ready implementation as
TrackerSamplerCSC or you can implement your sampling method, in this case the class must inherit
TrackerSamplerAlgorithm. Fill the samplingImpl method that writes the result in "sample" output
TrackerContribSampler is already instantiated, but you should define the sampling algorithm and add the
classes (or single class) to TrackerContribSampler. You can choose one of the ready implementation as
TrackerContribSamplerCSC or you can implement your sampling method, in this case the class must inherit
TrackerContribSamplerAlgorithm. Fill the samplingImpl method that writes the result in "sample" output
argument.
Example of creating specialized TrackerSamplerAlgorithm TrackerSamplerCSC : :
Example of creating specialized TrackerContribSamplerAlgorithm TrackerContribSamplerCSC : :
@code
class CV_EXPORTS_W TrackerSamplerCSC : public TrackerSamplerAlgorithm
class CV_EXPORTS_W TrackerContribSamplerCSC : public TrackerContribSamplerAlgorithm
{
public:
TrackerSamplerCSC( const TrackerSamplerCSC::Params &parameters = TrackerSamplerCSC::Params() );
~TrackerSamplerCSC();
TrackerContribSamplerCSC( const TrackerContribSamplerCSC::Params &parameters = TrackerContribSamplerCSC::Params() );
~TrackerContribSamplerCSC();
...
protected:
@ -159,10 +121,10 @@ Example of creating specialized TrackerSamplerAlgorithm TrackerSamplerCSC : :
};
@endcode
Example of adding TrackerSamplerAlgorithm to TrackerSampler : :
Example of adding TrackerContribSamplerAlgorithm to TrackerContribSampler : :
@code
//sampler is the TrackerSampler
Ptr<TrackerSamplerAlgorithm> CSCSampler = new TrackerSamplerCSC( CSCparameters );
//sampler is the TrackerContribSampler
Ptr<TrackerContribSamplerAlgorithm> CSCSampler = new TrackerContribSamplerCSC( CSCparameters );
if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) )
return false;
@ -170,23 +132,23 @@ Example of adding TrackerSamplerAlgorithm to TrackerSampler : :
//sampler->addTrackerSamplerAlgorithm( "CSC" );
@endcode
@sa
TrackerSamplerCSC, TrackerSamplerAlgorithm
TrackerContribSamplerCSC, TrackerContribSamplerAlgorithm
### TrackerFeatureSet
### TrackerContribFeatureSet
TrackerFeatureSet is already instantiated (as first) , but you should define what kinds of features
TrackerContribFeatureSet is already instantiated (as first) , but you should define what kinds of features
you'll use in your tracker. You can use multiple feature types, so you can add a ready
implementation as TrackerFeatureHAAR in your TrackerFeatureSet or develop your own implementation.
implementation as TrackerContribFeatureHAAR in your TrackerContribFeatureSet or develop your own implementation.
In this case, in the computeImpl method put the code that extract the features and in the selection
method optionally put the code for the refinement and selection of the features.
Example of creating specialized TrackerFeature TrackerFeatureHAAR : :
Example of creating specialized TrackerFeature TrackerContribFeatureHAAR : :
@code
class CV_EXPORTS_W TrackerFeatureHAAR : public TrackerFeature
class CV_EXPORTS_W TrackerContribFeatureHAAR : public TrackerFeature
{
public:
TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parameters = TrackerFeatureHAAR::Params() );
~TrackerFeatureHAAR();
TrackerContribFeatureHAAR( const TrackerContribFeatureHAAR::Params &parameters = TrackerContribFeatureHAAR::Params() );
~TrackerContribFeatureHAAR();
void selection( Mat& response, int npoints );
...
@ -196,14 +158,14 @@ Example of creating specialized TrackerFeature TrackerFeatureHAAR : :
};
@endcode
Example of adding TrackerFeature to TrackerFeatureSet : :
Example of adding TrackerFeature to TrackerContribFeatureSet : :
@code
//featureSet is the TrackerFeatureSet
Ptr<TrackerFeature> trackerFeature = new TrackerFeatureHAAR( HAARparameters );
//featureSet is the TrackerContribFeatureSet
Ptr<TrackerFeature> trackerFeature = new TrackerContribFeatureHAAR( HAARparameters );
featureSet->addTrackerFeature( trackerFeature );
@endcode
@sa
TrackerFeatureHAAR, TrackerFeatureSet
TrackerContribFeatureHAAR, TrackerContribFeatureSet
### TrackerModel
@ -298,23 +260,17 @@ Example of creating specialized TrackerTargetState TrackerMILTargetState : :
*/
/************************************ TrackerFeature Base Classes ************************************/
/************************************ TrackerContribFeature Base Classes ************************************/
/** @brief Abstract base class for TrackerFeature that represents the feature.
/** @brief Abstract base class for TrackerContribFeature that represents the feature.
*/
class CV_EXPORTS TrackerFeature
class CV_EXPORTS TrackerContribFeature : public TrackerFeature
{
public:
virtual ~TrackerFeature();
virtual ~TrackerContribFeature();
/** @brief Compute the features in the images collection
@param images The images
@param response The output response
*/
void compute( const std::vector<Mat>& images, Mat& response );
/** @brief Create TrackerFeature by tracker feature type
@param trackerFeatureType The TrackerFeature name
/** @brief Create TrackerContribFeature by tracker feature type
@param trackerFeatureType The TrackerContribFeature name
The modes available now:
@ -325,25 +281,22 @@ class CV_EXPORTS TrackerFeature
- "HOG" -- Histogram of Oriented Gradients features
- "LBP" -- Local Binary Pattern features
- "FEATURE2D" -- All types of Feature2D
*/
static Ptr<TrackerFeature> create( const String& trackerFeatureType );
*/
static Ptr<TrackerContribFeature> create( const String& trackerFeatureType );
/** @brief Identify most effective features
@param response Collection of response for the specific TrackerFeature
@param response Collection of response for the specific TrackerContribFeature
@param npoints Max number of features
@note This method modifies the response parameter
*/
virtual void selection( Mat& response, int npoints ) = 0;
/** @brief Get the name of the specific TrackerFeature
/** @brief Get the name of the specific TrackerContribFeature
*/
String getClassName() const;
protected:
virtual bool computeImpl( const std::vector<Mat>& images, Mat& response ) = 0;
String className;
};
@ -353,19 +306,19 @@ class CV_EXPORTS TrackerFeature
See table I and section III C @cite AMVOT Appearance modelling -\> Visual representation (Table II,
section 3.1 - 3.2)
TrackerFeatureSet is an aggregation of TrackerFeature
TrackerContribFeatureSet is an aggregation of TrackerContribFeature
@sa
TrackerFeature
TrackerContribFeature
*/
class CV_EXPORTS TrackerFeatureSet
class CV_EXPORTS TrackerContribFeatureSet
{
public:
TrackerFeatureSet();
TrackerContribFeatureSet();
~TrackerFeatureSet();
~TrackerContribFeatureSet();
/** @brief Extract features from the images collection
@param images The input images
@ -380,8 +333,8 @@ class CV_EXPORTS TrackerFeatureSet
*/
void removeOutliers();
/** @brief Add TrackerFeature in the collection. Return true if TrackerFeature is added, false otherwise
@param trackerFeatureType The TrackerFeature name
/** @brief Add TrackerContribFeature in the collection. Return true if TrackerContribFeature is added, false otherwise
@param trackerFeatureType The TrackerContribFeature name
The modes available now:
@ -393,32 +346,32 @@ class CV_EXPORTS TrackerFeatureSet
- "LBP" -- Local Binary Pattern features
- "FEATURE2D" -- All types of Feature2D
Example TrackerFeatureSet::addTrackerFeature : :
Example TrackerContribFeatureSet::addTrackerFeature : :
@code
//sample usage:
Ptr<TrackerFeature> trackerFeature = new TrackerFeatureHAAR( HAARparameters );
Ptr<TrackerContribFeature> trackerFeature = ...;
featureSet->addTrackerFeature( trackerFeature );
//or add CSC sampler with default parameters
//featureSet->addTrackerFeature( "HAAR" );
@endcode
@note If you use the second method, you must initialize the TrackerFeature
@note If you use the second method, you must initialize the TrackerContribFeature
*/
bool addTrackerFeature( String trackerFeatureType );
/** @overload
@param feature The TrackerFeature class
@param feature The TrackerContribFeature class
*/
bool addTrackerFeature( Ptr<TrackerFeature>& feature );
bool addTrackerFeature( Ptr<TrackerContribFeature>& feature );
/** @brief Get the TrackerFeature collection (TrackerFeature name, TrackerFeature pointer)
/** @brief Get the TrackerContribFeature collection (TrackerContribFeature name, TrackerContribFeature pointer)
*/
const std::vector<std::pair<String, Ptr<TrackerFeature> > >& getTrackerFeature() const;
const std::vector<std::pair<String, Ptr<TrackerContribFeature> > >& getTrackerFeature() const;
/** @brief Get the responses
@note Be sure to call extraction before getResponses Example TrackerFeatureSet::getResponses : :
@note Be sure to call extraction before getResponses Example TrackerContribFeatureSet::getResponses : :
*/
const std::vector<Mat>& getResponses() const;
@ -427,25 +380,26 @@ class CV_EXPORTS TrackerFeatureSet
void clearResponses();
bool blockAddTrackerFeature;
std::vector<std::pair<String, Ptr<TrackerFeature> > > features; //list of features
std::vector<std::pair<String, Ptr<TrackerContribFeature> > > features; //list of features
std::vector<Mat> responses; //list of response after compute
};
/************************************ TrackerSampler Base Classes ************************************/
/** @brief Abstract base class for TrackerSamplerAlgorithm that represents the algorithm for the specific
/************************************ TrackerContribSampler Base Classes ************************************/
/** @brief Abstract base class for TrackerContribSamplerAlgorithm that represents the algorithm for the specific
sampler.
*/
class CV_EXPORTS TrackerSamplerAlgorithm
class CV_EXPORTS TrackerContribSamplerAlgorithm : public TrackerSamplerAlgorithm
{
public:
/**
* \brief Destructor
*/
virtual ~TrackerSamplerAlgorithm();
virtual ~TrackerContribSamplerAlgorithm();
/** @brief Create TrackerSamplerAlgorithm by tracker sampler type.
/** @brief Create TrackerContribSamplerAlgorithm by tracker sampler type.
@param trackerSamplerType The trackerSamplerType name
The modes available now:
@ -453,7 +407,7 @@ class CV_EXPORTS TrackerSamplerAlgorithm
- "CSC" -- Current State Center
- "CS" -- Current State
*/
static Ptr<TrackerSamplerAlgorithm> create( const String& trackerSamplerType );
static Ptr<TrackerContribSamplerAlgorithm> create( const String& trackerSamplerType );
/** @brief Computes the regions starting from a position in an image.
@ -464,9 +418,9 @@ class CV_EXPORTS TrackerSamplerAlgorithm
@param sample The computed samples @cite AAM Fig. 1 variable Sk
*/
bool sampling( const Mat& image, Rect boundingBox, std::vector<Mat>& sample );
virtual bool sampling(const Mat& image, const Rect& boundingBox, std::vector<Mat>& sample) CV_OVERRIDE;
/** @brief Get the name of the specific TrackerSamplerAlgorithm
/** @brief Get the name of the specific TrackerContribSamplerAlgorithm
*/
String getClassName() const;
@ -485,23 +439,23 @@ class CV_EXPORTS TrackerSamplerAlgorithm
@cite AAM Sampling e Labeling. See table I and section III B
TrackerSampler is an aggregation of TrackerSamplerAlgorithm
TrackerContribSampler is an aggregation of TrackerContribSamplerAlgorithm
@sa
TrackerSamplerAlgorithm
TrackerContribSamplerAlgorithm
*/
class CV_EXPORTS TrackerSampler
class CV_EXPORTS TrackerContribSampler
{
public:
/**
* \brief Constructor
*/
TrackerSampler();
TrackerContribSampler();
/**
* \brief Destructor
*/
~TrackerSampler();
~TrackerContribSampler();
/** @brief Computes the regions starting from a position in an image
@param image The current frame
@ -509,26 +463,26 @@ class CV_EXPORTS TrackerSampler
*/
void sampling( const Mat& image, Rect boundingBox );
/** @brief Return the collection of the TrackerSamplerAlgorithm
/** @brief Return the collection of the TrackerContribSamplerAlgorithm
*/
const std::vector<std::pair<String, Ptr<TrackerSamplerAlgorithm> > >& getSamplers() const;
const std::vector<std::pair<String, Ptr<TrackerContribSamplerAlgorithm> > >& getSamplers() const;
/** @brief Return the samples from all TrackerSamplerAlgorithm, @cite AAM Fig. 1 variable Sk
/** @brief Return the samples from all TrackerContribSamplerAlgorithm, @cite AAM Fig. 1 variable Sk
*/
const std::vector<Mat>& getSamples() const;
/** @brief Add TrackerSamplerAlgorithm in the collection. Return true if sampler is added, false otherwise
@param trackerSamplerAlgorithmType The TrackerSamplerAlgorithm name
/** @brief Add TrackerContribSamplerAlgorithm in the collection. Return true if sampler is added, false otherwise
@param trackerSamplerAlgorithmType The TrackerContribSamplerAlgorithm name
The modes available now:
- "CSC" -- Current State Center
- "CS" -- Current State
- "PF" -- Particle Filtering
Example TrackerSamplerAlgorithm::addTrackerSamplerAlgorithm : :
Example TrackerContribSamplerAlgorithm::addTrackerContribSamplerAlgorithm : :
@code
TrackerSamplerCSC::Params CSCparameters;
Ptr<TrackerSamplerAlgorithm> CSCSampler = new TrackerSamplerCSC( CSCparameters );
TrackerContribSamplerCSC::Params CSCparameters;
Ptr<TrackerContribSamplerAlgorithm> CSCSampler = new TrackerContribSamplerCSC( CSCparameters );
if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) )
return false;
@ -536,300 +490,23 @@ class CV_EXPORTS TrackerSampler
//or add CSC sampler with default parameters
//sampler->addTrackerSamplerAlgorithm( "CSC" );
@endcode
@note If you use the second method, you must initialize the TrackerSamplerAlgorithm
@note If you use the second method, you must initialize the TrackerContribSamplerAlgorithm
*/
bool addTrackerSamplerAlgorithm( String trackerSamplerAlgorithmType );
/** @overload
@param sampler The TrackerSamplerAlgorithm
@param sampler The TrackerContribSamplerAlgorithm
*/
bool addTrackerSamplerAlgorithm( Ptr<TrackerSamplerAlgorithm>& sampler );
bool addTrackerSamplerAlgorithm( Ptr<TrackerContribSamplerAlgorithm>& sampler );
private:
std::vector<std::pair<String, Ptr<TrackerSamplerAlgorithm> > > samplers;
std::vector<std::pair<String, Ptr<TrackerContribSamplerAlgorithm> > > samplers;
std::vector<Mat> samples;
bool blockAddTrackerSampler;
void clearSamples();
};
/************************************ TrackerModel Base Classes ************************************/
/** @brief Abstract base class for TrackerTargetState that represents a possible state of the target.
See @cite AAM \f$\hat{x}^{i}_{k}\f$ all the states candidates.
Inherits this class with your Target state, In own implementation you can add scale variation,
width, height, orientation, etc.
*/
class CV_EXPORTS TrackerTargetState
{
public:
virtual ~TrackerTargetState()
{
}
;
/**
* \brief Get the position
* \return The position
*/
Point2f getTargetPosition() const;
/**
* \brief Set the position
* \param position The position
*/
void setTargetPosition( const Point2f& position );
/**
* \brief Get the width of the target
* \return The width of the target
*/
int getTargetWidth() const;
/**
* \brief Set the width of the target
* \param width The width of the target
*/
void setTargetWidth( int width );
/**
* \brief Get the height of the target
* \return The height of the target
*/
int getTargetHeight() const;
/**
* \brief Set the height of the target
* \param height The height of the target
*/
void setTargetHeight( int height );
protected:
Point2f targetPosition;
int targetWidth;
int targetHeight;
};
/** @brief Represents the model of the target at frame \f$k\f$ (all states and scores)
See @cite AAM The set of the pair \f$\langle \hat{x}^{i}_{k}, C^{i}_{k} \rangle\f$
@sa TrackerTargetState
*/
typedef std::vector<std::pair<Ptr<TrackerTargetState>, float> > ConfidenceMap;
/** @brief Represents the estimate states for all frames
@cite AAM \f$x_{k}\f$ is the trajectory of the target up to time \f$k\f$
@sa TrackerTargetState
*/
typedef std::vector<Ptr<TrackerTargetState> > Trajectory;
/** @brief Abstract base class for TrackerStateEstimator that estimates the most likely target state.
See @cite AAM State estimator
See @cite AMVOT Statistical modeling (Fig. 3), Table III (generative) - IV (discriminative) - V (hybrid)
*/
class CV_EXPORTS TrackerStateEstimator
{
public:
virtual ~TrackerStateEstimator();
/** @brief Estimate the most likely target state, return the estimated state
@param confidenceMaps The overall appearance model as a list of :cConfidenceMap
*/
Ptr<TrackerTargetState> estimate( const std::vector<ConfidenceMap>& confidenceMaps );
/** @brief Update the ConfidenceMap with the scores
@param confidenceMaps The overall appearance model as a list of :cConfidenceMap
*/
void update( std::vector<ConfidenceMap>& confidenceMaps );
/** @brief Create TrackerStateEstimator by tracker state estimator type
@param trackeStateEstimatorType The TrackerStateEstimator name
The modes available now:
- "BOOSTING" -- Boosting-based discriminative appearance models. See @cite AMVOT section 4.4
The modes available soon:
- "SVM" -- SVM-based discriminative appearance models. See @cite AMVOT section 4.5
*/
static Ptr<TrackerStateEstimator> create( const String& trackeStateEstimatorType );
/** @brief Get the name of the specific TrackerStateEstimator
*/
String getClassName() const;
protected:
virtual Ptr<TrackerTargetState> estimateImpl( const std::vector<ConfidenceMap>& confidenceMaps ) = 0;
virtual void updateImpl( std::vector<ConfidenceMap>& confidenceMaps ) = 0;
String className;
};
/** @brief Abstract class that represents the model of the target. It must be instantiated by specialized
tracker
See @cite AAM Ak
Inherits this with your TrackerModel
*/
class CV_EXPORTS TrackerModel
{
public:
/**
* \brief Constructor
*/
TrackerModel();
/**
* \brief Destructor
*/
virtual ~TrackerModel();
/** @brief Set TrackerEstimator, return true if the tracker state estimator is added, false otherwise
@param trackerStateEstimator The TrackerStateEstimator
@note You can add only one TrackerStateEstimator
*/
bool setTrackerStateEstimator( Ptr<TrackerStateEstimator> trackerStateEstimator );
/** @brief Estimate the most likely target location
@cite AAM ME, Model Estimation table I
@param responses Features extracted from TrackerFeatureSet
*/
void modelEstimation( const std::vector<Mat>& responses );
/** @brief Update the model
@cite AAM MU, Model Update table I
*/
void modelUpdate();
/** @brief Run the TrackerStateEstimator, return true if is possible to estimate a new state, false otherwise
*/
bool runStateEstimator();
/** @brief Set the current TrackerTargetState in the Trajectory
@param lastTargetState The current TrackerTargetState
*/
void setLastTargetState( const Ptr<TrackerTargetState>& lastTargetState );
/** @brief Get the last TrackerTargetState from Trajectory
*/
Ptr<TrackerTargetState> getLastTargetState() const;
/** @brief Get the list of the ConfidenceMap
*/
const std::vector<ConfidenceMap>& getConfidenceMaps() const;
/** @brief Get the last ConfidenceMap for the current frame
*/
const ConfidenceMap& getLastConfidenceMap() const;
/** @brief Get the TrackerStateEstimator
*/
Ptr<TrackerStateEstimator> getTrackerStateEstimator() const;
private:
void clearCurrentConfidenceMap();
protected:
std::vector<ConfidenceMap> confidenceMaps;
Ptr<TrackerStateEstimator> stateEstimator;
ConfidenceMap currentConfidenceMap;
Trajectory trajectory;
int maxCMLength;
virtual void modelEstimationImpl( const std::vector<Mat>& responses ) = 0;
virtual void modelUpdateImpl() = 0;
};
/************************************ Specific TrackerStateEstimator Classes ************************************/
/** @brief TrackerStateEstimator based on Boosting
*/
class CV_EXPORTS TrackerStateEstimatorMILBoosting : public TrackerStateEstimator
{
public:
/**
* Implementation of the target state for TrackerStateEstimatorMILBoosting
*/
class TrackerMILTargetState : public TrackerTargetState
{
public:
/**
* \brief Constructor
* \param position Top left corner of the bounding box
* \param width Width of the bounding box
* \param height Height of the bounding box
* \param foreground label for target or background
* \param features features extracted
*/
TrackerMILTargetState( const Point2f& position, int width, int height, bool foreground, const Mat& features );
/**
* \brief Destructor
*/
~TrackerMILTargetState()
{
}
;
/** @brief Set label: true for target foreground, false for background
@param foreground Label for background/foreground
*/
void setTargetFg( bool foreground );
/** @brief Set the features extracted from TrackerFeatureSet
@param features The features extracted
*/
void setFeatures( const Mat& features );
/** @brief Get the label. Return true for target foreground, false for background
*/
bool isTargetFg() const;
/** @brief Get the features extracted
*/
Mat getFeatures() const;
private:
bool isTarget;
Mat targetFeatures;
};
/** @brief Constructor
@param nFeatures Number of features for each sample
*/
TrackerStateEstimatorMILBoosting( int nFeatures = 250 );
~TrackerStateEstimatorMILBoosting();
/** @brief Set the current confidenceMap
@param confidenceMap The current :cConfidenceMap
*/
void setCurrentConfidenceMap( ConfidenceMap& confidenceMap );
protected:
Ptr<TrackerTargetState> estimateImpl( const std::vector<ConfidenceMap>& confidenceMaps ) CV_OVERRIDE;
void updateImpl( std::vector<ConfidenceMap>& confidenceMaps ) CV_OVERRIDE;
private:
uint max_idx( const std::vector<float> &v );
void prepareData( const ConfidenceMap& confidenceMap, Mat& positive, Mat& negative );
ClfMilBoost boostMILModel;
bool trained;
int numFeatures;
ConfidenceMap currentConfidenceMap;
};
/** @brief TrackerStateEstimatorAdaBoosting based on ADA-Boosting
*/
@ -838,7 +515,7 @@ class CV_EXPORTS TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator
public:
/** @brief Implementation of the target state for TrackerAdaBoostingTargetState
*/
class TrackerAdaBoostingTargetState : public TrackerTargetState
class CV_EXPORTS TrackerAdaBoostingTargetState : public TrackerTargetState
{
public:
@ -860,7 +537,7 @@ class CV_EXPORTS TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator
}
;
/** @brief Set the features extracted from TrackerFeatureSet
/** @brief Set the features extracted from TrackerContribFeatureSet
@param responses The features extracted
*/
void setTargetResponses( const Mat& responses );
@ -940,6 +617,7 @@ class CV_EXPORTS TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator
ConfidenceMap currentConfidenceMap;
};
/**
* \brief TrackerStateEstimator based on SVM
*/
@ -954,11 +632,13 @@ class CV_EXPORTS TrackerStateEstimatorSVM : public TrackerStateEstimator
void updateImpl( std::vector<ConfidenceMap>& confidenceMaps ) CV_OVERRIDE;
};
/************************************ Specific TrackerSamplerAlgorithm Classes ************************************/
/** @brief TrackerSampler based on CSC (current state centered), used by MIL algorithm TrackerMIL
*/
class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm
class CV_EXPORTS TrackerContribSamplerCSC : public TrackerContribSamplerAlgorithm
{
public:
enum
@ -982,11 +662,11 @@ class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm
};
/** @brief Constructor
@param parameters TrackerSamplerCSC parameters TrackerSamplerCSC::Params
@param parameters TrackerContribSamplerCSC parameters TrackerContribSamplerCSC::Params
*/
TrackerSamplerCSC( const TrackerSamplerCSC::Params &parameters = TrackerSamplerCSC::Params() );
TrackerContribSamplerCSC( const TrackerContribSamplerCSC::Params &parameters = TrackerContribSamplerCSC::Params() );
/** @brief Set the sampling mode of TrackerSamplerCSC
/** @brief Set the sampling mode of TrackerContribSamplerCSC
@param samplingMode The sampling mode
The modes are:
@ -999,11 +679,11 @@ class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm
*/
void setMode( int samplingMode );
~TrackerSamplerCSC();
~TrackerContribSamplerCSC();
protected:
bool samplingImpl( const Mat& image, Rect boundingBox, std::vector<Mat>& sample ) CV_OVERRIDE;
bool samplingImpl(const Mat& image, Rect boundingBox, std::vector<Mat>& sample) CV_OVERRIDE;
private:
@ -1014,9 +694,10 @@ class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm
std::vector<Mat> sampleImage( const Mat& img, int x, int y, int w, int h, float inrad, float outrad = 0, int maxnum = 1000000 );
};
/** @brief TrackerSampler based on CS (current state), used by algorithm TrackerBoosting
/** @brief TrackerContribSampler based on CS (current state), used by algorithm TrackerBoosting
*/
class CV_EXPORTS TrackerSamplerCS : public TrackerSamplerAlgorithm
class CV_EXPORTS TrackerSamplerCS : public TrackerContribSamplerAlgorithm
{
public:
enum
@ -1083,7 +764,7 @@ It should be noted, that the definition of "similarity" between two rectangles i
their histograms. As experiments show, tracker is *not* very succesfull if target is assumed to
strongly change its dimensions.
*/
class CV_EXPORTS TrackerSamplerPF : public TrackerSamplerAlgorithm
class CV_EXPORTS TrackerSamplerPF : public TrackerContribSamplerAlgorithm
{
public:
/** @brief This structure contains all the parameters that can be varied during the course of sampling
@ -1113,12 +794,14 @@ private:
Ptr<MinProblemSolver::Function> _function;
};
/************************************ Specific TrackerFeature Classes ************************************/
/************************************ Specific TrackerContribFeature Classes ************************************/
/**
* \brief TrackerFeature based on Feature2D
* \brief TrackerContribFeature based on Feature2D
*/
class CV_EXPORTS TrackerFeatureFeature2d : public TrackerFeature
class CV_EXPORTS TrackerFeatureFeature2d : public TrackerContribFeature
{
public:
@ -1143,9 +826,9 @@ class CV_EXPORTS TrackerFeatureFeature2d : public TrackerFeature
};
/**
* \brief TrackerFeature based on HOG
* \brief TrackerContribFeature based on HOG
*/
class CV_EXPORTS TrackerFeatureHOG : public TrackerFeature
class CV_EXPORTS TrackerFeatureHOG : public TrackerContribFeature
{
public:
@ -1161,10 +844,10 @@ class CV_EXPORTS TrackerFeatureHOG : public TrackerFeature
};
/** @brief TrackerFeature based on HAAR features, used by TrackerMIL and many others algorithms
/** @brief TrackerContribFeature based on HAAR features, used by TrackerMIL and many others algorithms
@note HAAR features implementation is copied from apps/traincascade and modified according to MIL
*/
class CV_EXPORTS TrackerFeatureHAAR : public TrackerFeature
class CV_EXPORTS TrackerContribFeatureHAAR : public TrackerContribFeature
{
public:
struct CV_EXPORTS Params
@ -1176,21 +859,21 @@ class CV_EXPORTS TrackerFeatureHAAR : public TrackerFeature
};
/** @brief Constructor
@param parameters TrackerFeatureHAAR parameters TrackerFeatureHAAR::Params
@param parameters TrackerContribFeatureHAAR parameters TrackerContribFeatureHAAR::Params
*/
TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parameters = TrackerFeatureHAAR::Params() );
TrackerContribFeatureHAAR( const TrackerContribFeatureHAAR::Params &parameters = TrackerContribFeatureHAAR::Params() );
~TrackerFeatureHAAR() CV_OVERRIDE;
~TrackerContribFeatureHAAR() CV_OVERRIDE;
/** @brief Compute the features only for the selected indices in the images collection
@param selFeatures indices of selected features
@param images The images
@param response Collection of response for the specific TrackerFeature
@param response Collection of response for the specific TrackerContribFeature
*/
bool extractSelected( const std::vector<int> selFeatures, const std::vector<Mat>& images, Mat& response );
/** @brief Identify most effective features
@param response Collection of response for the specific TrackerFeature
@param response Collection of response for the specific TrackerContribFeature
@param npoints Max number of features
@note This method modifies the response parameter
@ -1224,9 +907,9 @@ class CV_EXPORTS TrackerFeatureHAAR : public TrackerFeature
};
/**
* \brief TrackerFeature based on LBP
* \brief TrackerContribFeature based on LBP
*/
class CV_EXPORTS TrackerFeatureLBP : public TrackerFeature
class CV_EXPORTS TrackerFeatureLBP : public TrackerContribFeature
{
public:

@ -104,8 +104,8 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm
bool isInit;
Ptr<TrackerFeatureSet> featureSet;
Ptr<TrackerSampler> sampler;
Ptr<TrackerContribFeatureSet> featureSet;
Ptr<TrackerContribSampler> sampler;
Ptr<TrackerModel> model;
};
@ -123,7 +123,7 @@ Original code can be found here <http://vision.ucsd.edu/~bbabenko/project_miltra
class CV_EXPORTS_W TrackerMIL : public cv::legacy::Tracker
{
public:
struct CV_EXPORTS Params : cv::tracking::TrackerMIL::Params
struct CV_EXPORTS Params : cv::TrackerMIL::Params
{
void read( const FileNode& fn );
void write( FileStorage& fs ) const;
@ -526,7 +526,7 @@ public:
};
CV_EXPORTS_W Ptr<cv::tracking::Tracker> upgradeTrackingAPI(const Ptr<legacy::Tracker>& legacy_tracker);
CV_EXPORTS_W Ptr<cv::Tracker> upgradeTrackingAPI(const Ptr<legacy::Tracker>& legacy_tracker);
//! @}

@ -4,11 +4,10 @@ import org.opencv.core.Core;
import org.opencv.core.CvException;
import org.opencv.test.OpenCVTestCase;
import org.opencv.tracking.Tracking;
import org.opencv.tracking.Tracker;
import org.opencv.tracking.TrackerGOTURN;
import org.opencv.video.Tracker;
import org.opencv.video.TrackerGOTURN;
import org.opencv.tracking.TrackerKCF;
import org.opencv.tracking.TrackerMIL;
import org.opencv.video.TrackerMIL;
public class TrackerCreateTest extends OpenCVTestCase {

@ -1,6 +1,4 @@
#ifdef HAVE_OPENCV_TRACKING
typedef TrackerCSRT::Params TrackerCSRT_Params;
typedef TrackerKCF::Params TrackerKCF_Params;
typedef TrackerMIL::Params TrackerMIL_Params;
typedef TrackerGOTURN::Params TrackerGOTURN_Params;
#endif

@ -87,12 +87,6 @@ void Tracking::runTrackingTest(const Ptr<Tracker>& tracker, const TrackingParams
//==================================================================================================
PERF_TEST_P(Tracking, MIL, testing::ValuesIn(getTrackingParams()))
{
auto tracker = TrackerMIL::create();
runTrackingTest<Rect>(tracker, GetParam());
}
PERF_TEST_P(Tracking, Boosting, testing::ValuesIn(getTrackingParams()))
{
auto tracker = legacy::TrackerBoosting::create();
@ -105,15 +99,4 @@ PERF_TEST_P(Tracking, TLD, testing::ValuesIn(getTrackingParams()))
runTrackingTest(tracker, GetParam());
}
PERF_TEST_P(Tracking, GOTURN, testing::ValuesIn(getTrackingParams()))
{
std::string model = cvtest::findDataFile("dnn/gsoc2016-goturn/goturn.prototxt");
std::string weights = cvtest::findDataFile("dnn/gsoc2016-goturn/goturn.caffemodel", false);
TrackerGOTURN::Params params;
params.modelTxt = model;
params.modelBin = weights;
auto tracker = TrackerGOTURN::create(params);
runTrackingTest<Rect>(tracker, GetParam());
}
}} // namespace

@ -1,177 +0,0 @@
/*///////////////////////////////////////////////////////////////////////////////////////
//
// 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"
#ifdef HAVE_OPENCV_DNN
#include "opencv2/dnn.hpp"
#endif
namespace cv {
inline namespace tracking {
TrackerGOTURN::TrackerGOTURN()
{
// nothing
}
TrackerGOTURN::~TrackerGOTURN()
{
// nothing
}
TrackerGOTURN::Params::Params()
{
modelTxt = "goturn.prototxt";
modelBin = "goturn.caffemodel";
}
#ifdef HAVE_OPENCV_DNN
class TrackerGOTURNImpl : public TrackerGOTURN
{
public:
TrackerGOTURNImpl(const TrackerGOTURN::Params &parameters)
: params(parameters)
{
// Load GOTURN architecture from *.prototxt and pretrained weights from *.caffemodel
net = dnn::readNetFromCaffe(params.modelTxt, params.modelBin);
CV_Assert(!net.empty());
}
void init(InputArray image, const Rect& boundingBox) CV_OVERRIDE;
bool update(InputArray image, Rect& boundingBox) CV_OVERRIDE;
void setBoudingBox(Rect boundingBox)
{
if (image_.empty())
CV_Error(Error::StsInternal, "Set image first");
boundingBox_ = boundingBox & Rect(Point(0, 0), image_.size());
}
TrackerGOTURN::Params params;
dnn::Net net;
Rect boundingBox_;
Mat image_;
};
void TrackerGOTURNImpl::init(InputArray image, const Rect& boundingBox)
{
image_ = image.getMat().clone();
setBoudingBox(boundingBox);
}
bool TrackerGOTURNImpl::update(InputArray image, Rect& boundingBox)
{
int INPUT_SIZE = 227;
//Using prevFrame & prevBB from model and curFrame GOTURN calculating curBB
InputArray curFrame = image;
Mat prevFrame = image_;
Rect2d prevBB = boundingBox_;
Rect curBB;
float padTargetPatch = 2.0;
Rect2f searchPatchRect, targetPatchRect;
Point2f currCenter, prevCenter;
Mat prevFramePadded, curFramePadded;
Mat searchPatch, targetPatch;
prevCenter.x = (float)(prevBB.x + prevBB.width / 2);
prevCenter.y = (float)(prevBB.y + prevBB.height / 2);
targetPatchRect.width = (float)(prevBB.width*padTargetPatch);
targetPatchRect.height = (float)(prevBB.height*padTargetPatch);
targetPatchRect.x = (float)(prevCenter.x - prevBB.width*padTargetPatch / 2.0 + targetPatchRect.width);
targetPatchRect.y = (float)(prevCenter.y - prevBB.height*padTargetPatch / 2.0 + targetPatchRect.height);
targetPatchRect.width = std::min(targetPatchRect.width, (float)prevFrame.cols);
targetPatchRect.height = std::min(targetPatchRect.height, (float)prevFrame.rows);
targetPatchRect.x = std::max(-prevFrame.cols * 0.5f, std::min(targetPatchRect.x, prevFrame.cols * 1.5f));
targetPatchRect.y = std::max(-prevFrame.rows * 0.5f, std::min(targetPatchRect.y, prevFrame.rows * 1.5f));
copyMakeBorder(prevFrame, prevFramePadded, (int)targetPatchRect.height, (int)targetPatchRect.height, (int)targetPatchRect.width, (int)targetPatchRect.width, BORDER_REPLICATE);
targetPatch = prevFramePadded(targetPatchRect).clone();
copyMakeBorder(curFrame, curFramePadded, (int)targetPatchRect.height, (int)targetPatchRect.height, (int)targetPatchRect.width, (int)targetPatchRect.width, BORDER_REPLICATE);
searchPatch = curFramePadded(targetPatchRect).clone();
// Preprocess
// Resize
resize(targetPatch, targetPatch, Size(INPUT_SIZE, INPUT_SIZE), 0, 0, INTER_LINEAR_EXACT);
resize(searchPatch, searchPatch, Size(INPUT_SIZE, INPUT_SIZE), 0, 0, INTER_LINEAR_EXACT);
// Convert to Float type and subtract mean
Mat targetBlob = dnn::blobFromImage(targetPatch, 1.0f, Size(), Scalar::all(128), false);
Mat searchBlob = dnn::blobFromImage(searchPatch, 1.0f, Size(), Scalar::all(128), false);
net.setInput(targetBlob, "data1");
net.setInput(searchBlob, "data2");
Mat resMat = net.forward("scale").reshape(1, 1);
curBB.x = cvRound(targetPatchRect.x + (resMat.at<float>(0) * targetPatchRect.width / INPUT_SIZE) - targetPatchRect.width);
curBB.y = cvRound(targetPatchRect.y + (resMat.at<float>(1) * targetPatchRect.height / INPUT_SIZE) - targetPatchRect.height);
curBB.width = cvRound((resMat.at<float>(2) - resMat.at<float>(0)) * targetPatchRect.width / INPUT_SIZE);
curBB.height = cvRound((resMat.at<float>(3) - resMat.at<float>(1)) * targetPatchRect.height / INPUT_SIZE);
// Predicted BB
boundingBox = curBB & Rect(Point(0, 0), image_.size());
// Set new model image and BB from current frame
image_ = image.getMat().clone();
setBoudingBox(curBB);
return true;
}
Ptr<TrackerGOTURN> TrackerGOTURN::create(const TrackerGOTURN::Params& parameters)
{
return makePtr<TrackerGOTURNImpl>(parameters);
}
#else // OPENCV_HAVE_DNN
Ptr<TrackerGOTURN> TrackerGOTURN::create(const TrackerGOTURN::Params& parameters)
{
(void)(parameters);
CV_Error(cv::Error::StsNotImplemented, "to use GOTURN, the tracking module needs to be built with opencv_dnn !");
}
#endif // OPENCV_HAVE_DNN
}} // namespace

@ -65,19 +65,13 @@ bool Tracker::init( InputArray image, const Rect2d& boundingBox )
if( image.empty() )
return false;
sampler = Ptr<TrackerSampler>( new TrackerSampler() );
featureSet = Ptr<TrackerFeatureSet>( new TrackerFeatureSet() );
sampler = Ptr<TrackerContribSampler>( new TrackerContribSampler() );
featureSet = Ptr<TrackerContribFeatureSet>( new TrackerContribFeatureSet() );
model = Ptr<TrackerModel>();
bool initTracker = initImpl( image.getMat(), boundingBox );
//check if the model component is initialized
if (!model)
{
CV_Error( -1, "The model is not initialized" );
}
if( initTracker )
if (initTracker)
{
isInit = true;
}
@ -101,7 +95,7 @@ bool Tracker::update( InputArray image, Rect2d& boundingBox )
class LegacyTrackerWrapper : public cv::tracking::Tracker
class LegacyTrackerWrapper : public cv::Tracker
{
const Ptr<legacy::Tracker> legacy_tracker_;
public:
@ -132,7 +126,7 @@ public:
};
CV_EXPORTS_W Ptr<cv::tracking::Tracker> upgradeTrackingAPI(const Ptr<legacy::Tracker>& legacy_tracker)
CV_EXPORTS_W Ptr<cv::Tracker> upgradeTrackingAPI(const Ptr<legacy::Tracker>& legacy_tracker)
{
return makePtr<LegacyTrackerWrapper>(legacy_tracker);
}

@ -33,8 +33,8 @@ public:
{
impl.init(image, boundingBox);
model = impl.model;
sampler = makePtr<TrackerSampler>();
featureSet = makePtr<TrackerFeatureSet>();
sampler = makePtr<TrackerContribSampler>();
featureSet = makePtr<TrackerContribFeatureSet>();
isInit = true;
return true;
}

@ -72,8 +72,8 @@ public:
{
impl.init(image, boundingBox);
model = impl.model;
sampler = makePtr<TrackerSampler>();
featureSet = makePtr<TrackerFeatureSet>();
sampler = makePtr<TrackerContribSampler>();
featureSet = makePtr<TrackerContribFeatureSet>();
isInit = true;
return true;
}

@ -1,381 +0,0 @@
/*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/tracking/onlineMIL.hpp"
#define sign(s) ((s > 0 ) ? 1 : ((s<0) ? -1 : 0))
template<class T> class SortableElementRev
{
public:
T _val;
int _ind;
SortableElementRev() :
_ind( 0 )
{
}
SortableElementRev( T val, int ind )
{
_val = val;
_ind = ind;
}
bool operator<( SortableElementRev<T> &b )
{
return ( _val < b._val );
}
;
};
static bool CompareSortableElementRev( const SortableElementRev<float>& i, const SortableElementRev<float>& j )
{
return i._val < j._val;
}
template<class T> void sort_order_des( std::vector<T> &v, std::vector<int> &order )
{
uint n = (uint) v.size();
std::vector<SortableElementRev<T> > v2;
v2.resize( n );
order.clear();
order.resize( n );
for ( uint i = 0; i < n; i++ )
{
v2[i]._ind = i;
v2[i]._val = v[i];
}
//std::sort( v2.begin(), v2.end() );
std::sort( v2.begin(), v2.end(), CompareSortableElementRev );
for ( uint i = 0; i < n; i++ )
{
order[i] = v2[i]._ind;
v[i] = v2[i]._val;
}
}
;
namespace cv
{
//implementations for strong classifier
ClfMilBoost::Params::Params()
{
_numSel = 50;
_numFeat = 250;
_lRate = 0.85f;
}
ClfMilBoost::ClfMilBoost()
{
_myParams = ClfMilBoost::Params();
_numsamples = 0;
}
ClfMilBoost::~ClfMilBoost()
{
_selectors.clear();
for ( size_t i = 0; i < _weakclf.size(); i++ )
delete _weakclf.at( i );
}
void ClfMilBoost::init( const ClfMilBoost::Params &parameters )
{
_myParams = parameters;
_numsamples = 0;
//_ftrs = Ftr::generate( _myParams->_ftrParams, _myParams->_numFeat );
// if( params->_storeFtrHistory )
// Ftr::toViz( _ftrs, "haarftrs" );
_weakclf.resize( _myParams._numFeat );
for ( int k = 0; k < _myParams._numFeat; k++ )
{
_weakclf[k] = new ClfOnlineStump( k );
_weakclf[k]->_lRate = _myParams._lRate;
}
_counter = 0;
}
void ClfMilBoost::update( const Mat& posx, const Mat& negx )
{
int numneg = negx.rows;
int numpos = posx.rows;
// compute ftrs
//if( !posx.ftrsComputed() )
// Ftr::compute( posx, _ftrs );
//if( !negx.ftrsComputed() )
// Ftr::compute( negx, _ftrs );
// initialize H
static std::vector<float> Hpos, Hneg;
Hpos.clear();
Hneg.clear();
Hpos.resize( posx.rows, 0.0f ), Hneg.resize( negx.rows, 0.0f );
_selectors.clear();
std::vector<float> posw( posx.rows ), negw( negx.rows );
std::vector<std::vector<float> > pospred( _weakclf.size() ), negpred( _weakclf.size() );
// train all weak classifiers without weights
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int m = 0; m < _myParams._numFeat; m++ )
{
_weakclf[m]->update( posx, negx );
pospred[m] = _weakclf[m]->classifySetF( posx );
negpred[m] = _weakclf[m]->classifySetF( negx );
}
// pick the best features
for ( int s = 0; s < _myParams._numSel; s++ )
{
// compute errors/likl for all weak clfs
std::vector<float> poslikl( _weakclf.size(), 1.0f ), neglikl( _weakclf.size() ), likl( _weakclf.size() );
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int w = 0; w < (int) _weakclf.size(); w++ )
{
float lll = 1.0f;
for ( int j = 0; j < numpos; j++ )
lll *= ( 1 - sigmoid( Hpos[j] + pospred[w][j] ) );
poslikl[w] = (float) -log( 1 - lll + 1e-5 );
lll = 0.0f;
for ( int j = 0; j < numneg; j++ )
lll += (float) -log( 1e-5f + 1 - sigmoid( Hneg[j] + negpred[w][j] ) );
neglikl[w] = lll;
likl[w] = poslikl[w] / numpos + neglikl[w] / numneg;
}
// pick best weak clf
std::vector<int> order;
sort_order_des( likl, order );
// find best weakclf that isn't already included
for ( uint k = 0; k < order.size(); k++ )
if( std::count( _selectors.begin(), _selectors.end(), order[k] ) == 0 )
{
_selectors.push_back( order[k] );
break;
}
// update H = H + h_m
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int k = 0; k < posx.rows; k++ )
Hpos[k] += pospred[_selectors[s]][k];
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int k = 0; k < negx.rows; k++ )
Hneg[k] += negpred[_selectors[s]][k];
}
//if( _myParams->_storeFtrHistory )
//for ( uint j = 0; j < _selectors.size(); j++ )
// _ftrHist( _selectors[j], _counter ) = 1.0f / ( j + 1 );
_counter++;
/* */
return;
}
std::vector<float> ClfMilBoost::classify( const Mat& x, bool logR )
{
int numsamples = x.rows;
std::vector<float> res( numsamples );
std::vector<float> tr;
for ( uint w = 0; w < _selectors.size(); w++ )
{
tr = _weakclf[_selectors[w]]->classifySetF( x );
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int j = 0; j < numsamples; j++ )
{
res[j] += tr[j];
}
}
// return probabilities or log odds ratio
if( !logR )
{
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int j = 0; j < (int) res.size(); j++ )
{
res[j] = sigmoid( res[j] );
}
}
return res;
}
//implementations for weak classifier
ClfOnlineStump::ClfOnlineStump()
{
_trained = false;
_ind = -1;
init();
}
ClfOnlineStump::ClfOnlineStump( int ind )
{
_trained = false;
_ind = ind;
init();
}
void ClfOnlineStump::init()
{
_mu0 = 0;
_mu1 = 0;
_sig0 = 1;
_sig1 = 1;
_lRate = 0.85f;
_trained = false;
}
void ClfOnlineStump::update( const Mat& posx, const Mat& negx, const Mat_<float>& /*posw*/, const Mat_<float>& /*negw*/)
{
//std::cout << " ClfOnlineStump::update" << _ind << std::endl;
float posmu = 0.0, negmu = 0.0;
if( posx.cols > 0 )
posmu = float( mean( posx.col( _ind ) )[0] );
if( negx.cols > 0 )
negmu = float( mean( negx.col( _ind ) )[0] );
if( _trained )
{
if( posx.cols > 0 )
{
_mu1 = ( _lRate * _mu1 + ( 1 - _lRate ) * posmu );
cv::Mat diff = posx.col( _ind ) - _mu1;
_sig1 = _lRate * _sig1 + ( 1 - _lRate ) * float( mean( diff.mul( diff ) )[0] );
}
if( negx.cols > 0 )
{
_mu0 = ( _lRate * _mu0 + ( 1 - _lRate ) * negmu );
cv::Mat diff = negx.col( _ind ) - _mu0;
_sig0 = _lRate * _sig0 + ( 1 - _lRate ) * float( mean( diff.mul( diff ) )[0] );
}
_q = ( _mu1 - _mu0 ) / 2;
_s = sign( _mu1 - _mu0 );
_log_n0 = std::log( float( 1.0f / pow( _sig0, 0.5f ) ) );
_log_n1 = std::log( float( 1.0f / pow( _sig1, 0.5f ) ) );
//_e1 = -1.0f/(2.0f*_sig1+1e-99f);
//_e0 = -1.0f/(2.0f*_sig0+1e-99f);
_e1 = -1.0f / ( 2.0f * _sig1 + std::numeric_limits<float>::min() );
_e0 = -1.0f / ( 2.0f * _sig0 + std::numeric_limits<float>::min() );
}
else
{
_trained = true;
if( posx.cols > 0 )
{
_mu1 = posmu;
cv::Scalar scal_mean, scal_std_dev;
cv::meanStdDev( posx.col( _ind ), scal_mean, scal_std_dev );
_sig1 = float( scal_std_dev[0] ) * float( scal_std_dev[0] ) + 1e-9f;
}
if( negx.cols > 0 )
{
_mu0 = negmu;
cv::Scalar scal_mean, scal_std_dev;
cv::meanStdDev( negx.col( _ind ), scal_mean, scal_std_dev );
_sig0 = float( scal_std_dev[0] ) * float( scal_std_dev[0] ) + 1e-9f;
}
_q = ( _mu1 - _mu0 ) / 2;
_s = sign( _mu1 - _mu0 );
_log_n0 = std::log( float( 1.0f / pow( _sig0, 0.5f ) ) );
_log_n1 = std::log( float( 1.0f / pow( _sig1, 0.5f ) ) );
//_e1 = -1.0f/(2.0f*_sig1+1e-99f);
//_e0 = -1.0f/(2.0f*_sig0+1e-99f);
_e1 = -1.0f / ( 2.0f * _sig1 + std::numeric_limits<float>::min() );
_e0 = -1.0f / ( 2.0f * _sig0 + std::numeric_limits<float>::min() );
}
}
bool ClfOnlineStump::classify( const Mat& x, int i )
{
float xx = x.at<float>( i, _ind );
double log_p0 = ( xx - _mu0 ) * ( xx - _mu0 ) * _e0 + _log_n0;
double log_p1 = ( xx - _mu1 ) * ( xx - _mu1 ) * _e1 + _log_n1;
return log_p1 > log_p0;
}
float ClfOnlineStump::classifyF( const Mat& x, int i )
{
float xx = x.at<float>( i, _ind );
double log_p0 = ( xx - _mu0 ) * ( xx - _mu0 ) * _e0 + _log_n0;
double log_p1 = ( xx - _mu1 ) * ( xx - _mu1 ) * _e1 + _log_n1;
return float( log_p1 - log_p0 );
}
inline std::vector<float> ClfOnlineStump::classifySetF( const Mat& x )
{
std::vector<float> res( x.rows );
#ifdef _OPENMP
#pragma omp parallel for
#endif
for ( int k = 0; k < (int) res.size(); k++ )
{
res[k] = classifyF( x, k );
}
return res;
}
} /* namespace cv */

@ -4,20 +4,6 @@
#include "precomp.hpp"
namespace cv {
inline namespace tracking {
Tracker::Tracker()
{
// nothing
}
Tracker::~Tracker()
{
// nothing
}
}} // namespace
// see modules/video/src/tracking/tracker.cpp
#include "legacy/tracker.legacy.hpp"

@ -136,7 +136,7 @@ bool TrackerBoostingImpl::initImpl( const Mat& image, const Rect2d& boundingBox
CSparameters.overlap = params.samplerOverlap;
CSparameters.searchFactor = params.samplerSearchFactor;
Ptr<TrackerSamplerAlgorithm> CSSampler = Ptr<TrackerSamplerCS>( new TrackerSamplerCS( CSparameters ) );
Ptr<TrackerContribSamplerAlgorithm> CSSampler = Ptr<TrackerSamplerCS>( new TrackerSamplerCS( CSparameters ) );
if( !sampler->addTrackerSamplerAlgorithm( CSSampler ) )
return false;
@ -155,11 +155,11 @@ bool TrackerBoostingImpl::initImpl( const Mat& image, const Rect2d& boundingBox
Rect ROI = CSSampler.staticCast<TrackerSamplerCS>()->getROI();
//compute HAAR features
TrackerFeatureHAAR::Params HAARparameters;
TrackerContribFeatureHAAR::Params HAARparameters;
HAARparameters.numFeatures = params.featureSetNumFeatures;
HAARparameters.isIntegral = true;
HAARparameters.rectSize = Size( static_cast<int>(boundingBox.width), static_cast<int>(boundingBox.height) );
Ptr<TrackerFeature> trackerFeature = Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR( HAARparameters ) );
Ptr<TrackerContribFeature> trackerFeature = Ptr<TrackerContribFeatureHAAR>( new TrackerContribFeatureHAAR( HAARparameters ) );
if( !featureSet->addTrackerFeature( trackerFeature ) )
return false;
@ -179,11 +179,11 @@ bool TrackerBoostingImpl::initImpl( const Mat& image, const Rect2d& boundingBox
for ( int i = 0; i < params.iterationInit; i++ )
{
//compute temp features
TrackerFeatureHAAR::Params HAARparameters2;
TrackerContribFeatureHAAR::Params HAARparameters2;
HAARparameters2.numFeatures = static_cast<int>( posSamples.size() + negSamples.size() );
HAARparameters2.isIntegral = true;
HAARparameters2.rectSize = Size( static_cast<int>(boundingBox.width), static_cast<int>(boundingBox.height) );
Ptr<TrackerFeatureHAAR> trackerFeature2 = Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR( HAARparameters2 ) );
Ptr<TrackerContribFeatureHAAR> trackerFeature2 = Ptr<TrackerContribFeatureHAAR>( new TrackerContribFeatureHAAR( HAARparameters2 ) );
model.staticCast<TrackerBoostingModel>()->setMode( TrackerBoostingModel::MODE_NEGATIVE, negSamples );
model->modelEstimation( negResponse );
@ -198,8 +198,8 @@ bool TrackerBoostingImpl::initImpl( const Mat& image, const Rect2d& boundingBox
{
if( replacedClassifier[j] != -1 && swappedClassified[j] != -1 )
{
trackerFeature.staticCast<TrackerFeatureHAAR>()->swapFeature( replacedClassifier[j], swappedClassified[j] );
trackerFeature.staticCast<TrackerFeatureHAAR>()->swapFeature( swappedClassified[j], trackerFeature2->getFeatureAt( (int)j ) );
trackerFeature.staticCast<TrackerContribFeatureHAAR>()->swapFeature( replacedClassifier[j], swappedClassified[j] );
trackerFeature.staticCast<TrackerContribFeatureHAAR>()->swapFeature( swappedClassified[j], trackerFeature2->getFeatureAt( (int)j ) );
}
}
}
@ -244,7 +244,7 @@ bool TrackerBoostingImpl::updateImpl( const Mat& image, Rect2d& boundingBox )
Mat response;
std::vector<int> classifiers = model->getTrackerStateEstimator().staticCast<TrackerStateEstimatorAdaBoosting>()->computeSelectedWeakClassifier();
Ptr<TrackerFeatureHAAR> extractor = featureSet->getTrackerFeature()[0].second.staticCast<TrackerFeatureHAAR>();
Ptr<TrackerContribFeatureHAAR> extractor = featureSet->getTrackerFeature()[0].second.staticCast<TrackerContribFeatureHAAR>();
extractor->extractSelected( classifiers, detectSamples, response );
responses.push_back( response );
@ -292,11 +292,11 @@ bool TrackerBoostingImpl::updateImpl( const Mat& image, Rect2d& boundingBox )
const std::vector<Mat> negResponse = featureSet->getResponses();
//compute temp features
TrackerFeatureHAAR::Params HAARparameters2;
TrackerContribFeatureHAAR::Params HAARparameters2;
HAARparameters2.numFeatures = static_cast<int>( posSamples.size() + negSamples.size() );
HAARparameters2.isIntegral = true;
HAARparameters2.rectSize = Size( static_cast<int>(boundingBox.width), static_cast<int>(boundingBox.height) );
Ptr<TrackerFeatureHAAR> trackerFeature2 = Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR( HAARparameters2 ) );
Ptr<TrackerContribFeatureHAAR> trackerFeature2 = Ptr<TrackerContribFeatureHAAR>( new TrackerContribFeatureHAAR( HAARparameters2 ) );
//model estimate
model.staticCast<TrackerBoostingModel>()->setMode( TrackerBoostingModel::MODE_NEGATIVE, negSamples );
@ -314,8 +314,8 @@ bool TrackerBoostingImpl::updateImpl( const Mat& image, Rect2d& boundingBox )
{
if( replacedClassifier[j] != -1 && swappedClassified[j] != -1 )
{
featureSet->getTrackerFeature().at( 0 ).second.staticCast<TrackerFeatureHAAR>()->swapFeature( replacedClassifier[j], swappedClassified[j] );
featureSet->getTrackerFeature().at( 0 ).second.staticCast<TrackerFeatureHAAR>()->swapFeature( swappedClassified[j],
featureSet->getTrackerFeature().at( 0 ).second.staticCast<TrackerContribFeatureHAAR>()->swapFeature( replacedClassifier[j], swappedClassified[j] );
featureSet->getTrackerFeature().at( 0 ).second.staticCast<TrackerContribFeatureHAAR>()->swapFeature( swappedClassified[j],
trackerFeature2->getFeatureAt( (int)j ) );
}
}

@ -46,23 +46,15 @@ namespace detail {
inline namespace tracking {
/*
* TrackerFeature
* TrackerContribFeature
*/
TrackerFeature::~TrackerFeature()
TrackerContribFeature::~TrackerContribFeature()
{
}
void TrackerFeature::compute( const std::vector<Mat>& images, Mat& response )
{
if( images.empty() )
return;
computeImpl( images, response );
}
Ptr<TrackerFeature> TrackerFeature::create( const String& trackerFeatureType )
Ptr<TrackerContribFeature> TrackerContribFeature::create( const String& trackerFeatureType )
{
if( trackerFeatureType.find( "FEATURE2D" ) == 0 )
{
@ -82,7 +74,7 @@ Ptr<TrackerFeature> TrackerFeature::create( const String& trackerFeatureType )
if( trackerFeatureType.find( "HAAR" ) == 0 )
{
return Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR() );
return Ptr<TrackerContribFeatureHAAR>( new TrackerContribFeatureHAAR() );
}
if( trackerFeatureType.find( "LBP" ) == 0 )
@ -93,7 +85,7 @@ Ptr<TrackerFeature> TrackerFeature::create( const String& trackerFeatureType )
CV_Error( -1, "Tracker feature type not supported" );
}
String TrackerFeature::getClassName() const
String TrackerContribFeature::getClassName() const
{
return className;
}
@ -145,21 +137,21 @@ void TrackerFeatureHOG::selection( Mat& /*response*/, int /*npoints*/)
}
/**
* TrackerFeatureHAAR
* TrackerContribFeatureHAAR
*/
/**
* Parameters
*/
TrackerFeatureHAAR::Params::Params()
TrackerContribFeatureHAAR::Params::Params()
{
numFeatures = 250;
rectSize = Size( 100, 100 );
isIntegral = false;
}
TrackerFeatureHAAR::TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parameters ) :
TrackerContribFeatureHAAR::TrackerContribFeatureHAAR( const TrackerContribFeatureHAAR::Params &parameters ) :
params( parameters )
{
className = "HAAR";
@ -171,23 +163,23 @@ TrackerFeatureHAAR::TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parame
featureEvaluator->init( &haarParams, 1, params.rectSize );
}
TrackerFeatureHAAR::~TrackerFeatureHAAR()
TrackerContribFeatureHAAR::~TrackerContribFeatureHAAR()
{
}
CvHaarEvaluator::FeatureHaar& TrackerFeatureHAAR::getFeatureAt( int id )
CvHaarEvaluator::FeatureHaar& TrackerContribFeatureHAAR::getFeatureAt( int id )
{
return featureEvaluator->getFeatures( id );
}
bool TrackerFeatureHAAR::swapFeature( int id, CvHaarEvaluator::FeatureHaar& feature )
bool TrackerContribFeatureHAAR::swapFeature( int id, CvHaarEvaluator::FeatureHaar& feature )
{
featureEvaluator->getFeatures( id ) = feature;
return true;
}
bool TrackerFeatureHAAR::swapFeature( int source, int target )
bool TrackerContribFeatureHAAR::swapFeature( int source, int target )
{
CvHaarEvaluator::FeatureHaar feature = featureEvaluator->getFeatures( source );
featureEvaluator->getFeatures( source ) = featureEvaluator->getFeatures( target );
@ -195,7 +187,7 @@ bool TrackerFeatureHAAR::swapFeature( int source, int target )
return true;
}
bool TrackerFeatureHAAR::extractSelected( const std::vector<int> selFeatures, const std::vector<Mat>& images, Mat& response )
bool TrackerContribFeatureHAAR::extractSelected( const std::vector<int> selFeatures, const std::vector<Mat>& images, Mat& response )
{
if( images.empty() )
{
@ -264,7 +256,7 @@ class Parallel_compute : public cv::ParallelLoopBody
}
};
bool TrackerFeatureHAAR::computeImpl( const std::vector<Mat>& images, Mat& response )
bool TrackerContribFeatureHAAR::computeImpl( const std::vector<Mat>& images, Mat& response )
{
if( images.empty() )
{
@ -294,7 +286,7 @@ bool TrackerFeatureHAAR::computeImpl( const std::vector<Mat>& images, Mat& respo
return true;
}
void TrackerFeatureHAAR::selection( Mat& /*response*/, int /*npoints*/)
void TrackerContribFeatureHAAR::selection( Mat& /*response*/, int /*npoints*/)
{
}

@ -46,13 +46,13 @@ namespace detail {
inline namespace tracking {
/*
* TrackerFeatureSet
* TrackerContribFeatureSet
*/
/*
* Constructor
*/
TrackerFeatureSet::TrackerFeatureSet()
TrackerContribFeatureSet::TrackerContribFeatureSet()
{
blockAddTrackerFeature = false;
}
@ -60,12 +60,12 @@ TrackerFeatureSet::TrackerFeatureSet()
/*
* Destructor
*/
TrackerFeatureSet::~TrackerFeatureSet()
TrackerContribFeatureSet::~TrackerContribFeatureSet()
{
}
void TrackerFeatureSet::extraction( const std::vector<Mat>& images )
void TrackerContribFeatureSet::extraction( const std::vector<Mat>& images )
{
clearResponses();
@ -84,23 +84,23 @@ void TrackerFeatureSet::extraction( const std::vector<Mat>& images )
}
}
void TrackerFeatureSet::selection()
void TrackerContribFeatureSet::selection()
{
}
void TrackerFeatureSet::removeOutliers()
void TrackerContribFeatureSet::removeOutliers()
{
}
bool TrackerFeatureSet::addTrackerFeature( String trackerFeatureType )
bool TrackerContribFeatureSet::addTrackerFeature( String trackerFeatureType )
{
if( blockAddTrackerFeature )
{
return false;
}
Ptr<TrackerFeature> feature = TrackerFeature::create( trackerFeatureType );
Ptr<TrackerContribFeature> feature = TrackerContribFeature::create( trackerFeatureType );
if (!feature)
{
@ -112,7 +112,7 @@ bool TrackerFeatureSet::addTrackerFeature( String trackerFeatureType )
return true;
}
bool TrackerFeatureSet::addTrackerFeature( Ptr<TrackerFeature>& feature )
bool TrackerContribFeatureSet::addTrackerFeature( Ptr<TrackerContribFeature>& feature )
{
if( blockAddTrackerFeature )
{
@ -125,17 +125,17 @@ bool TrackerFeatureSet::addTrackerFeature( Ptr<TrackerFeature>& feature )
return true;
}
const std::vector<std::pair<String, Ptr<TrackerFeature> > >& TrackerFeatureSet::getTrackerFeature() const
const std::vector<std::pair<String, Ptr<TrackerContribFeature> > >& TrackerContribFeatureSet::getTrackerFeature() const
{
return features;
}
const std::vector<Mat>& TrackerFeatureSet::getResponses() const
const std::vector<Mat>& TrackerContribFeatureSet::getResponses() const
{
return responses;
}
void TrackerFeatureSet::clearResponses()
void TrackerContribFeatureSet::clearResponses()
{
responses.clear();
}

@ -1,265 +0,0 @@
/*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 "trackerMILModel.hpp"
namespace cv {
inline namespace tracking {
namespace impl {
class TrackerMILImpl CV_FINAL : public TrackerMIL
{
public:
TrackerMILImpl(const TrackerMIL::Params &parameters);
virtual void init(InputArray image, const Rect& boundingBox) CV_OVERRIDE;
virtual bool update(InputArray image, Rect& boundingBox) CV_OVERRIDE;
void compute_integral( const Mat & img, Mat & ii_img );
TrackerMIL::Params params;
Ptr<TrackerMILModel> model;
Ptr<TrackerSampler> sampler;
Ptr<TrackerFeatureSet> featureSet;
};
} // namespace
TrackerMIL::Params::Params()
{
samplerInitInRadius = 3;
samplerSearchWinSize = 25;
samplerInitMaxNegNum = 65;
samplerTrackInRadius = 4;
samplerTrackMaxPosNum = 100000;
samplerTrackMaxNegNum = 65;
featureSetNumFeatures = 250;
}
namespace impl {
TrackerMILImpl::TrackerMILImpl(const TrackerMIL::Params &parameters)
: params(parameters)
{
// nothing
}
void TrackerMILImpl::compute_integral( const Mat & img, Mat & ii_img )
{
Mat ii;
std::vector<Mat> ii_imgs;
integral( img, ii, CV_32F ); // FIXIT split first
split( ii, ii_imgs );
ii_img = ii_imgs[0];
}
void TrackerMILImpl::init(InputArray image, const Rect& boundingBox)
{
sampler = makePtr<TrackerSampler>();
featureSet = makePtr<TrackerFeatureSet>();
Mat intImage;
compute_integral(image.getMat(), intImage);
TrackerSamplerCSC::Params CSCparameters;
CSCparameters.initInRad = params.samplerInitInRadius;
CSCparameters.searchWinSize = params.samplerSearchWinSize;
CSCparameters.initMaxNegNum = params.samplerInitMaxNegNum;
CSCparameters.trackInPosRad = params.samplerTrackInRadius;
CSCparameters.trackMaxPosNum = params.samplerTrackMaxPosNum;
CSCparameters.trackMaxNegNum = params.samplerTrackMaxNegNum;
Ptr<TrackerSamplerAlgorithm> CSCSampler = makePtr<TrackerSamplerCSC>(CSCparameters);
CV_Assert(sampler->addTrackerSamplerAlgorithm(CSCSampler));
//or add CSC sampler with default parameters
//sampler->addTrackerSamplerAlgorithm( "CSC" );
//Positive sampling
CSCSampler.staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_POS );
sampler->sampling( intImage, boundingBox );
std::vector<Mat> posSamples = sampler->getSamples();
//Negative sampling
CSCSampler.staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_NEG );
sampler->sampling( intImage, boundingBox );
std::vector<Mat> negSamples = sampler->getSamples();
CV_Assert(!posSamples.empty());
CV_Assert(!negSamples.empty());
//compute HAAR features
TrackerFeatureHAAR::Params HAARparameters;
HAARparameters.numFeatures = params.featureSetNumFeatures;
HAARparameters.rectSize = Size( (int)boundingBox.width, (int)boundingBox.height );
HAARparameters.isIntegral = true;
Ptr<TrackerFeature> trackerFeature = Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR( HAARparameters ) );
featureSet->addTrackerFeature( trackerFeature );
featureSet->extraction( posSamples );
const std::vector<Mat> posResponse = featureSet->getResponses();
featureSet->extraction( negSamples );
const std::vector<Mat> negResponse = featureSet->getResponses();
model = makePtr<TrackerMILModel>(boundingBox);
Ptr<TrackerStateEstimatorMILBoosting> stateEstimator = Ptr<TrackerStateEstimatorMILBoosting>(
new TrackerStateEstimatorMILBoosting( params.featureSetNumFeatures ) );
model->setTrackerStateEstimator( stateEstimator );
//Run model estimation and update
model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_POSITIVE, posSamples );
model->modelEstimation( posResponse );
model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_NEGATIVE, negSamples );
model->modelEstimation( negResponse );
model->modelUpdate();
}
bool TrackerMILImpl::update(InputArray image, Rect& boundingBox)
{
Mat intImage;
compute_integral(image.getMat(), intImage);
//get the last location [AAM] X(k-1)
Ptr<TrackerTargetState> lastLocation = model->getLastTargetState();
Rect lastBoundingBox( (int)lastLocation->getTargetPosition().x, (int)lastLocation->getTargetPosition().y, lastLocation->getTargetWidth(),
lastLocation->getTargetHeight() );
//sampling new frame based on last location
( sampler->getSamplers().at( 0 ).second ).staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_DETECT );
sampler->sampling( intImage, lastBoundingBox );
std::vector<Mat> detectSamples = sampler->getSamples();
if( detectSamples.empty() )
return false;
/*//TODO debug samples
Mat f;
image.copyTo(f);
for( size_t i = 0; i < detectSamples.size(); i=i+10 )
{
Size sz;
Point off;
detectSamples.at(i).locateROI(sz, off);
rectangle(f, Rect(off.x,off.y,detectSamples.at(i).cols,detectSamples.at(i).rows), Scalar(255,0,0), 1);
}*/
//extract features from new samples
featureSet->extraction( detectSamples );
std::vector<Mat> response = featureSet->getResponses();
//predict new location
ConfidenceMap cmap;
model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_ESTIMATON, detectSamples );
model.staticCast<TrackerMILModel>()->responseToConfidenceMap( response, cmap );
model->getTrackerStateEstimator().staticCast<TrackerStateEstimatorMILBoosting>()->setCurrentConfidenceMap( cmap );
if( !model->runStateEstimator() )
{
return false;
}
Ptr<TrackerTargetState> currentState = model->getLastTargetState();
boundingBox = Rect( (int)currentState->getTargetPosition().x, (int)currentState->getTargetPosition().y, currentState->getTargetWidth(),
currentState->getTargetHeight() );
/*//TODO debug
rectangle(f, lastBoundingBox, Scalar(0,255,0), 1);
rectangle(f, boundingBox, Scalar(0,0,255), 1);
imshow("f", f);
//waitKey( 0 );*/
//sampling new frame based on new location
//Positive sampling
( sampler->getSamplers().at( 0 ).second ).staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_POS );
sampler->sampling( intImage, boundingBox );
std::vector<Mat> posSamples = sampler->getSamples();
//Negative sampling
( sampler->getSamplers().at( 0 ).second ).staticCast<TrackerSamplerCSC>()->setMode( TrackerSamplerCSC::MODE_INIT_NEG );
sampler->sampling( intImage, boundingBox );
std::vector<Mat> negSamples = sampler->getSamples();
if( posSamples.empty() || negSamples.empty() )
return false;
//extract features
featureSet->extraction( posSamples );
std::vector<Mat> posResponse = featureSet->getResponses();
featureSet->extraction( negSamples );
std::vector<Mat> negResponse = featureSet->getResponses();
//model estimate
model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_POSITIVE, posSamples );
model->modelEstimation( posResponse );
model.staticCast<TrackerMILModel>()->setMode( TrackerMILModel::MODE_NEGATIVE, negSamples );
model->modelEstimation( negResponse );
//model update
model->modelUpdate();
return true;
}
} // namespace
TrackerMIL::TrackerMIL()
{
// nothing
}
TrackerMIL::~TrackerMIL()
{
// nothing
}
Ptr<TrackerMIL> TrackerMIL::create(const TrackerMIL::Params &parameters)
{
return makePtr<TrackerMILImpl>(parameters);
}
}} // namespace
#include "legacy/trackerMIL.legacy.hpp"

@ -1,126 +0,0 @@
/*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 "trackerMILModel.hpp"
/**
* TrackerMILModel
*/
namespace cv {
inline namespace tracking {
namespace impl {
TrackerMILModel::TrackerMILModel( const Rect& boundingBox )
{
currentSample.clear();
mode = MODE_POSITIVE;
width = boundingBox.width;
height = boundingBox.height;
Ptr<TrackerStateEstimatorMILBoosting::TrackerMILTargetState> initState = Ptr<TrackerStateEstimatorMILBoosting::TrackerMILTargetState>(
new TrackerStateEstimatorMILBoosting::TrackerMILTargetState( Point2f( (float)boundingBox.x, (float)boundingBox.y ), boundingBox.width, boundingBox.height,
true, Mat() ) );
trajectory.push_back( initState );
}
void TrackerMILModel::responseToConfidenceMap( const std::vector<Mat>& responses, ConfidenceMap& confidenceMap )
{
if( currentSample.empty() )
{
CV_Error( -1, "The samples in Model estimation are empty" );
}
for ( size_t i = 0; i < responses.size(); i++ )
{
//for each column (one sample) there are #num_feature
//get informations from currentSample
for ( int j = 0; j < responses.at( i ).cols; j++ )
{
Size currentSize;
Point currentOfs;
currentSample.at( j ).locateROI( currentSize, currentOfs );
bool foreground = false;
if( mode == MODE_POSITIVE || mode == MODE_ESTIMATON )
{
foreground = true;
}
else if( mode == MODE_NEGATIVE )
{
foreground = false;
}
//get the column of the HAAR responses
Mat singleResponse = responses.at( i ).col( j );
//create the state
Ptr<TrackerStateEstimatorMILBoosting::TrackerMILTargetState> currentState = Ptr<TrackerStateEstimatorMILBoosting::TrackerMILTargetState>(
new TrackerStateEstimatorMILBoosting::TrackerMILTargetState( currentOfs, width, height, foreground, singleResponse ) );
confidenceMap.push_back( std::make_pair( currentState, 0.0f ) );
}
}
}
void TrackerMILModel::modelEstimationImpl( const std::vector<Mat>& responses )
{
responseToConfidenceMap( responses, currentConfidenceMap );
}
void TrackerMILModel::modelUpdateImpl()
{
}
void TrackerMILModel::setMode( int trainingMode, const std::vector<Mat>& samples )
{
currentSample.clear();
currentSample = samples;
mode = trainingMode;
}
}}} // namespace

@ -1,102 +0,0 @@
/*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*/
#ifndef __OPENCV_TRACKER_MIL_MODEL_HPP__
#define __OPENCV_TRACKER_MIL_MODEL_HPP__
namespace cv {
inline namespace tracking {
namespace impl {
/**
* \brief Implementation of TrackerModel for MIL algorithm
*/
class TrackerMILModel : public TrackerModel
{
public:
enum
{
MODE_POSITIVE = 1, // mode for positive features
MODE_NEGATIVE = 2, // mode for negative features
MODE_ESTIMATON = 3 // mode for estimation step
};
/**
* \brief Constructor
* \param boundingBox The first boundingBox
*/
TrackerMILModel( const Rect& boundingBox );
/**
* \brief Destructor
*/
~TrackerMILModel()
{
}
;
/**
* \brief Set the mode
*/
void setMode( int trainingMode, const std::vector<Mat>& samples );
/**
* \brief Create the ConfidenceMap from a list of responses
* \param responses The list of the responses
* \param confidenceMap The output
*/
void responseToConfidenceMap( const std::vector<Mat>& responses, ConfidenceMap& confidenceMap );
protected:
void modelEstimationImpl( const std::vector<Mat>& responses ) CV_OVERRIDE;
void modelUpdateImpl() CV_OVERRIDE;
private:
int mode;
std::vector<Mat> currentSample;
int width; //initial width of the boundingBox
int height; //initial height of the boundingBox
};
}}} // namespace
#endif

@ -39,6 +39,7 @@
//
//M*/
#include "precomp.hpp"
#include "opencv2/tracking/tracking_legacy.hpp"
namespace cv {
@ -49,36 +50,41 @@ namespace impl {
class TrackerMILImpl CV_FINAL : public legacy::TrackerMIL
{
public:
cv::tracking::impl::TrackerMILImpl impl;
Ptr<cv::TrackerMIL> impl;
legacy::TrackerMIL::Params params;
TrackerMILImpl(const legacy::TrackerMIL::Params &parameters)
: impl(parameters)
: impl(cv::TrackerMIL::create(parameters))
, params(parameters)
{
isInit = false;
}
void read(const FileNode& fn) CV_OVERRIDE
{
static_cast<legacy::TrackerMIL::Params&>(impl.params).read(fn);
params.read(fn);
CV_Error(Error::StsNotImplemented, "Can't update legacy tracker wrapper");
}
void write(FileStorage& fs) const CV_OVERRIDE
{
static_cast<const legacy::TrackerMIL::Params&>(impl.params).write(fs);
params.write(fs);
}
bool initImpl(const Mat& image, const Rect2d& boundingBox) CV_OVERRIDE
bool initImpl(const Mat& image, const Rect2d& boundingBox2d) CV_OVERRIDE
{
impl.init(image, boundingBox);
model = impl.model;
featureSet = impl.featureSet;
sampler = impl.sampler;
int x1 = cvRound(boundingBox2d.x);
int y1 = cvRound(boundingBox2d.y);
int x2 = cvRound(boundingBox2d.x + boundingBox2d.width);
int y2 = cvRound(boundingBox2d.y + boundingBox2d.height);
Rect boundingBox = Rect(x1, y1, x2 - x1, y2 - y1) & Rect(Point(0, 0), image.size());
impl->init(image, boundingBox);
isInit = true;
return true;
}
bool updateImpl(const Mat& image, Rect2d& boundingBox) CV_OVERRIDE
{
Rect bb;
bool res = impl.update(image, bb);
bool res = impl->update(image, bb);
boundingBox = bb;
return res;
}

@ -1,178 +0,0 @@
/*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"
namespace cv {
namespace detail {
inline namespace tracking {
/*
* TrackerModel
*/
TrackerModel::TrackerModel()
{
stateEstimator = Ptr<TrackerStateEstimator>();
maxCMLength = 10;
}
TrackerModel::~TrackerModel()
{
}
bool TrackerModel::setTrackerStateEstimator( Ptr<TrackerStateEstimator> trackerStateEstimator )
{
if (stateEstimator.get())
{
return false;
}
stateEstimator = trackerStateEstimator;
return true;
}
Ptr<TrackerStateEstimator> TrackerModel::getTrackerStateEstimator() const
{
return stateEstimator;
}
void TrackerModel::modelEstimation( const std::vector<Mat>& responses )
{
modelEstimationImpl( responses );
}
void TrackerModel::clearCurrentConfidenceMap()
{
currentConfidenceMap.clear();
}
void TrackerModel::modelUpdate()
{
modelUpdateImpl();
if( maxCMLength != -1 && (int) confidenceMaps.size() >= maxCMLength - 1 )
{
int l = maxCMLength / 2;
confidenceMaps.erase( confidenceMaps.begin(), confidenceMaps.begin() + l );
}
if( maxCMLength != -1 && (int) trajectory.size() >= maxCMLength - 1 )
{
int l = maxCMLength / 2;
trajectory.erase( trajectory.begin(), trajectory.begin() + l );
}
confidenceMaps.push_back( currentConfidenceMap );
stateEstimator->update( confidenceMaps );
clearCurrentConfidenceMap();
}
bool TrackerModel::runStateEstimator()
{
if (!stateEstimator)
{
CV_Error( -1, "Tracker state estimator is not setted" );
}
Ptr<TrackerTargetState> targetState = stateEstimator->estimate( confidenceMaps );
if (!targetState)
return false;
setLastTargetState( targetState );
return true;
}
void TrackerModel::setLastTargetState( const Ptr<TrackerTargetState>& lastTargetState )
{
trajectory.push_back( lastTargetState );
}
Ptr<TrackerTargetState> TrackerModel::getLastTargetState() const
{
return trajectory.back();
}
const std::vector<ConfidenceMap>& TrackerModel::getConfidenceMaps() const
{
return confidenceMaps;
}
const ConfidenceMap& TrackerModel::getLastConfidenceMap() const
{
return confidenceMaps.back();
}
/*
* TrackerTargetState
*/
Point2f TrackerTargetState::getTargetPosition() const
{
return targetPosition;
}
void TrackerTargetState::setTargetPosition( const Point2f& position )
{
targetPosition = position;
}
int TrackerTargetState::getTargetWidth() const
{
return targetWidth;
}
void TrackerTargetState::setTargetWidth( int width )
{
targetWidth = width;
}
int TrackerTargetState::getTargetHeight() const
{
return targetHeight;
}
void TrackerTargetState::setTargetHeight( int height )
{
targetHeight = height;
}
}}} // namespace

@ -46,13 +46,13 @@ namespace detail {
inline namespace tracking {
/*
* TrackerSampler
* TrackerContribSampler
*/
/*
* Constructor
*/
TrackerSampler::TrackerSampler()
TrackerContribSampler::TrackerContribSampler()
{
blockAddTrackerSampler = false;
}
@ -60,12 +60,12 @@ TrackerSampler::TrackerSampler()
/*
* Destructor
*/
TrackerSampler::~TrackerSampler()
TrackerContribSampler::~TrackerContribSampler()
{
}
void TrackerSampler::sampling( const Mat& image, Rect boundingBox )
void TrackerContribSampler::sampling( const Mat& image, Rect boundingBox )
{
clearSamples();
@ -89,13 +89,13 @@ void TrackerSampler::sampling( const Mat& image, Rect boundingBox )
}
}
bool TrackerSampler::addTrackerSamplerAlgorithm( String trackerSamplerAlgorithmType )
bool TrackerContribSampler::addTrackerSamplerAlgorithm( String trackerSamplerAlgorithmType )
{
if( blockAddTrackerSampler )
{
return false;
}
Ptr<TrackerSamplerAlgorithm> sampler = TrackerSamplerAlgorithm::create( trackerSamplerAlgorithmType );
Ptr<TrackerContribSamplerAlgorithm> sampler = TrackerContribSamplerAlgorithm::create( trackerSamplerAlgorithmType );
if (!sampler)
{
@ -107,7 +107,7 @@ bool TrackerSampler::addTrackerSamplerAlgorithm( String trackerSamplerAlgorithmT
return true;
}
bool TrackerSampler::addTrackerSamplerAlgorithm( Ptr<TrackerSamplerAlgorithm>& sampler )
bool TrackerContribSampler::addTrackerSamplerAlgorithm( Ptr<TrackerContribSamplerAlgorithm>& sampler )
{
if( blockAddTrackerSampler )
{
@ -125,17 +125,17 @@ bool TrackerSampler::addTrackerSamplerAlgorithm( Ptr<TrackerSamplerAlgorithm>& s
return true;
}
const std::vector<std::pair<String, Ptr<TrackerSamplerAlgorithm> > >& TrackerSampler::getSamplers() const
const std::vector<std::pair<String, Ptr<TrackerContribSamplerAlgorithm> > >& TrackerContribSampler::getSamplers() const
{
return samplers;
}
const std::vector<Mat>& TrackerSampler::getSamples() const
const std::vector<Mat>& TrackerContribSampler::getSamples() const
{
return samples;
}
void TrackerSampler::clearSamples()
void TrackerContribSampler::clearSamples()
{
samples.clear();
}

@ -48,15 +48,15 @@ namespace detail {
inline namespace tracking {
/*
* TrackerSamplerAlgorithm
* TrackerContribSamplerAlgorithm
*/
TrackerSamplerAlgorithm::~TrackerSamplerAlgorithm()
TrackerContribSamplerAlgorithm::~TrackerContribSamplerAlgorithm()
{
}
bool TrackerSamplerAlgorithm::sampling( const Mat& image, Rect boundingBox, std::vector<Mat>& sample )
bool TrackerContribSamplerAlgorithm::sampling(const Mat& image, const Rect& boundingBox, std::vector<Mat>& sample)
{
if( image.empty() )
return false;
@ -64,11 +64,11 @@ bool TrackerSamplerAlgorithm::sampling( const Mat& image, Rect boundingBox, std:
return samplingImpl( image, boundingBox, sample );
}
Ptr<TrackerSamplerAlgorithm> TrackerSamplerAlgorithm::create( const String& trackerSamplerType )
Ptr<TrackerContribSamplerAlgorithm> TrackerContribSamplerAlgorithm::create( const String& trackerSamplerType )
{
if( trackerSamplerType.find( "CSC" ) == 0 )
{
return Ptr<TrackerSamplerCSC>( new TrackerSamplerCSC() );
return Ptr<TrackerContribSamplerCSC>( new TrackerContribSamplerCSC() );
}
if( trackerSamplerType.find( "CS" ) == 0 )
@ -76,23 +76,23 @@ Ptr<TrackerSamplerAlgorithm> TrackerSamplerAlgorithm::create( const String& trac
return Ptr<TrackerSamplerCS>( new TrackerSamplerCS() );
}
CV_Error( -1, "Tracker sampler algorithm type not supported" );
CV_Error(Error::StsNotImplemented, "Tracker sampler algorithm type not supported" );
}
String TrackerSamplerAlgorithm::getClassName() const
String TrackerContribSamplerAlgorithm::getClassName() const
{
return className;
}
/**
* TrackerSamplerCSC
* TrackerContribSamplerCSC
*/
/**
* Parameters
*/
TrackerSamplerCSC::Params::Params()
TrackerContribSamplerCSC::Params::Params()
{
initInRad = 3;
initMaxNegNum = 65;
@ -103,7 +103,7 @@ TrackerSamplerCSC::Params::Params()
}
TrackerSamplerCSC::TrackerSamplerCSC( const TrackerSamplerCSC::Params &parameters ) :
TrackerContribSamplerCSC::TrackerContribSamplerCSC( const TrackerContribSamplerCSC::Params &parameters ) :
params( parameters )
{
className = "CSC";
@ -112,12 +112,12 @@ TrackerSamplerCSC::TrackerSamplerCSC( const TrackerSamplerCSC::Params &parameter
}
TrackerSamplerCSC::~TrackerSamplerCSC()
TrackerContribSamplerCSC::~TrackerContribSamplerCSC()
{
}
bool TrackerSamplerCSC::samplingImpl( const Mat& image, Rect boundingBox, std::vector<Mat>& sample )
bool TrackerContribSamplerCSC::samplingImpl( const Mat& image, Rect boundingBox, std::vector<Mat>& sample )
{
float inrad = 0;
float outrad = 0;
@ -159,12 +159,12 @@ bool TrackerSamplerCSC::samplingImpl( const Mat& image, Rect boundingBox, std::v
return false;
}
void TrackerSamplerCSC::setMode( int samplingMode )
void TrackerContribSamplerCSC::setMode( int samplingMode )
{
mode = samplingMode;
}
std::vector<Mat> TrackerSamplerCSC::sampleImage( const Mat& img, int x, int y, int w, int h, float inrad, float outrad, int maxnum )
std::vector<Mat> TrackerContribSamplerCSC::sampleImage( const Mat& img, int x, int y, int w, int h, float inrad, float outrad, int maxnum )
{
int rowsz = img.rows - h - 1;
int colsz = img.cols - w - 1;

@ -45,33 +45,6 @@ namespace cv {
namespace detail {
inline namespace tracking {
/*
* TrackerStateEstimator
*/
TrackerStateEstimator::~TrackerStateEstimator()
{
}
Ptr<TrackerTargetState> TrackerStateEstimator::estimate( const std::vector<ConfidenceMap>& confidenceMaps )
{
if( confidenceMaps.empty() )
return Ptr<TrackerTargetState>();
return estimateImpl( confidenceMaps );
}
void TrackerStateEstimator::update( std::vector<ConfidenceMap>& confidenceMaps )
{
if( confidenceMaps.empty() )
return;
return updateImpl( confidenceMaps );
}
Ptr<TrackerStateEstimator> TrackerStateEstimator::create( const String& trackeStateEstimatorType )
{
@ -82,164 +55,14 @@ Ptr<TrackerStateEstimator> TrackerStateEstimator::create( const String& trackeSt
if( trackeStateEstimatorType.find( "BOOSTING" ) == 0 )
{
return Ptr<TrackerStateEstimatorMILBoosting>( new TrackerStateEstimatorMILBoosting() );
CV_Error(Error::StsNotImplemented, "TrackerStateEstimatorMILBoosting API is not available");
//return Ptr<TrackerStateEstimatorMILBoosting>( new TrackerStateEstimatorMILBoosting() );
}
CV_Error( -1, "Tracker state estimator type not supported" );
}
String TrackerStateEstimator::getClassName() const
{
return className;
}
/**
* TrackerStateEstimatorMILBoosting::TrackerMILTargetState
*/
TrackerStateEstimatorMILBoosting::TrackerMILTargetState::TrackerMILTargetState( const Point2f& position, int width, int height, bool foreground,
const Mat& features )
{
setTargetPosition( position );
setTargetWidth( width );
setTargetHeight( height );
setTargetFg( foreground );
setFeatures( features );
}
void TrackerStateEstimatorMILBoosting::TrackerMILTargetState::setTargetFg( bool foreground )
{
isTarget = foreground;
}
void TrackerStateEstimatorMILBoosting::TrackerMILTargetState::setFeatures( const Mat& features )
{
targetFeatures = features;
}
bool TrackerStateEstimatorMILBoosting::TrackerMILTargetState::isTargetFg() const
{
return isTarget;
}
Mat TrackerStateEstimatorMILBoosting::TrackerMILTargetState::getFeatures() const
{
return targetFeatures;
}
TrackerStateEstimatorMILBoosting::TrackerStateEstimatorMILBoosting( int nFeatures )
{
className = "BOOSTING";
trained = false;
numFeatures = nFeatures;
}
TrackerStateEstimatorMILBoosting::~TrackerStateEstimatorMILBoosting()
{
}
void TrackerStateEstimatorMILBoosting::setCurrentConfidenceMap( ConfidenceMap& confidenceMap )
{
currentConfidenceMap.clear();
currentConfidenceMap = confidenceMap;
}
uint TrackerStateEstimatorMILBoosting::max_idx( const std::vector<float> &v )
{
const float* findPtr = & ( *std::max_element( v.begin(), v.end() ) );
const float* beginPtr = & ( *v.begin() );
return (uint) ( findPtr - beginPtr );
}
Ptr<TrackerTargetState> TrackerStateEstimatorMILBoosting::estimateImpl( const std::vector<ConfidenceMap>& /*confidenceMaps*/)
{
//run ClfMilBoost classify in order to compute next location
if( currentConfidenceMap.empty() )
return Ptr<TrackerTargetState>();
Mat positiveStates;
Mat negativeStates;
prepareData( currentConfidenceMap, positiveStates, negativeStates );
std::vector<float> prob = boostMILModel.classify( positiveStates );
int bestind = max_idx( prob );
//float resp = prob[bestind];
return currentConfidenceMap.at( bestind ).first;
}
void TrackerStateEstimatorMILBoosting::prepareData( const ConfidenceMap& confidenceMap, Mat& positive, Mat& negative )
{
int posCounter = 0;
int negCounter = 0;
for ( size_t i = 0; i < confidenceMap.size(); i++ )
{
Ptr<TrackerMILTargetState> currentTargetState = confidenceMap.at( i ).first.staticCast<TrackerMILTargetState>();
if( currentTargetState->isTargetFg() )
posCounter++;
else
negCounter++;
}
positive.create( posCounter, numFeatures, CV_32FC1 );
negative.create( negCounter, numFeatures, CV_32FC1 );
//TODO change with mat fast access
//initialize trainData (positive and negative)
int pc = 0;
int nc = 0;
for ( size_t i = 0; i < confidenceMap.size(); i++ )
{
Ptr<TrackerMILTargetState> currentTargetState = confidenceMap.at( i ).first.staticCast<TrackerMILTargetState>();
Mat stateFeatures = currentTargetState->getFeatures();
if( currentTargetState->isTargetFg() )
{
for ( int j = 0; j < stateFeatures.rows; j++ )
{
//fill the positive trainData with the value of the feature j for sample i
positive.at<float>( pc, j ) = stateFeatures.at<float>( j, 0 );
}
pc++;
}
else
{
for ( int j = 0; j < stateFeatures.rows; j++ )
{
//fill the negative trainData with the value of the feature j for sample i
negative.at<float>( nc, j ) = stateFeatures.at<float>( j, 0 );
}
nc++;
}
}
}
void TrackerStateEstimatorMILBoosting::updateImpl( std::vector<ConfidenceMap>& confidenceMaps )
{
if( !trained )
{
//this is the first time that the classifier is built
//init MIL
boostMILModel.init();
trained = true;
}
ConfidenceMap lastConfidenceMap = confidenceMaps.back();
Mat positiveStates;
Mat negativeStates;
prepareData( lastConfidenceMap, positiveStates, negativeStates );
//update MIL
boostMILModel.update( positiveStates, negativeStates );
}
/**
* TrackerStateEstimatorAdaBoosting

@ -58,379 +58,10 @@ const string TRACKING_DIR = "tracking";
const string FOLDER_IMG = "data";
const string FOLDER_OMIT_INIT = "initOmit";
/*
* The Evaluation Methodologies are partially based on:
* ====================================================================================================================
* [OTB] Y. Wu, J. Lim, and M.-H. Yang, "Online object tracking: A benchmark," in Computer Vision and Pattern Recognition (CVPR), 2013
*
*/
// Check used "cmake" version in case of errors
// Check compiler command line options for <opencv>/modules include
#include "video/test/test_trackers.impl.hpp"
enum BBTransformations
{
NoTransform = 0,
CenterShiftLeft = 1,
CenterShiftRight = 2,
CenterShiftUp = 3,
CenterShiftDown = 4,
CornerShiftTopLeft = 5,
CornerShiftTopRight = 6,
CornerShiftBottomLeft = 7,
CornerShiftBottomRight = 8,
Scale_0_8 = 9,
Scale_0_9 = 10,
Scale_1_1 = 11,
Scale_1_2 = 12
};
namespace {
std::vector<std::string> splitString(const std::string& s_, const std::string& delimiter)
{
std::string s = s_;
std::vector<string> token;
size_t pos = 0;
while ( ( pos = s.find( delimiter ) ) != std::string::npos )
{
token.push_back( s.substr( 0, pos ) );
s.erase( 0, pos + delimiter.length() );
}
token.push_back( s );
return token;
}
float calcDistance(const Rect& a, const Rect& b)
{
Point2f p_a( (float)(a.x + a.width / 2), (float)(a.y + a.height / 2) );
Point2f p_b( (float)(b.x + b.width / 2), (float)(b.y + b.height / 2) );
return sqrt( pow( p_a.x - p_b.x, 2 ) + pow( p_a.y - p_b.y, 2 ) );
}
float calcOverlap(const Rect& a, const Rect& b)
{
float rectIntersectionArea = (float)(a & b).area();
return rectIntersectionArea / (a.area() + b.area() - rectIntersectionArea);
}
} // namespace
template<typename Tracker, typename ROI_t = Rect2d>
class TrackerTest
{
public:
TrackerTest(const Ptr<Tracker>& tracker, const string& video, float distanceThreshold,
float overlapThreshold, int shift = NoTransform, int segmentIdx = 1, int numSegments = 10);
~TrackerTest() {}
void run();
protected:
void checkDataTest();
void distanceAndOverlapTest();
Ptr<Tracker> tracker;
string video;
std::vector<Rect> bbs;
int startFrame;
string suffix;
string prefix;
float overlapThreshold;
float distanceThreshold;
int segmentIdx;
int shift;
int numSegments;
int gtStartFrame;
int endFrame;
vector<int> validSequence;
private:
Rect applyShift(const Rect& bb);
};
template<typename Tracker, typename ROI_t>
TrackerTest<Tracker, ROI_t>::TrackerTest(const Ptr<Tracker>& _tracker, const string& _video, float _distanceThreshold,
float _overlapThreshold, int _shift, int _segmentIdx, int _numSegments ) :
tracker( _tracker ),
video( _video ),
overlapThreshold( _overlapThreshold ),
distanceThreshold( _distanceThreshold ),
segmentIdx(_segmentIdx),
shift(_shift),
numSegments(_numSegments)
{
// nothing
}
template<typename Tracker, typename ROI_t>
Rect TrackerTest<Tracker, ROI_t>::applyShift(const Rect& bb_)
{
Rect bb = bb_;
Point center( bb.x + ( bb.width / 2 ), bb.y + ( bb.height / 2 ) );
int xLimit = bb.x + bb.width - 1;
int yLimit = bb.y + bb.height - 1;
int h = 0;
int w = 0;
float ratio = 1.0;
switch ( shift )
{
case CenterShiftLeft:
bb.x = bb.x - (int)ceil( 0.1 * bb.width );
break;
case CenterShiftRight:
bb.x = bb.x + (int)ceil( 0.1 * bb.width );
break;
case CenterShiftUp:
bb.y = bb.y - (int)ceil( 0.1 * bb.height );
break;
case CenterShiftDown:
bb.y = bb.y + (int)ceil( 0.1 * bb.height );
break;
case CornerShiftTopLeft:
bb.x = (int)cvRound( bb.x - 0.1 * bb.width );
bb.y = (int)cvRound( bb.y - 0.1 * bb.height );
bb.width = xLimit - bb.x + 1;
bb.height = yLimit - bb.y + 1;
break;
case CornerShiftTopRight:
xLimit = (int)cvRound( xLimit + 0.1 * bb.width );
bb.y = (int)cvRound( bb.y - 0.1 * bb.height );
bb.width = xLimit - bb.x + 1;
bb.height = yLimit - bb.y + 1;
break;
case CornerShiftBottomLeft:
bb.x = (int)cvRound( bb.x - 0.1 * bb.width );
yLimit = (int)cvRound( yLimit + 0.1 * bb.height );
bb.width = xLimit - bb.x + 1;
bb.height = yLimit - bb.y + 1;
break;
case CornerShiftBottomRight:
xLimit = (int)cvRound( xLimit + 0.1 * bb.width );
yLimit = (int)cvRound( yLimit + 0.1 * bb.height );
bb.width = xLimit - bb.x + 1;
bb.height = yLimit - bb.y + 1;
break;
case Scale_0_8:
ratio = 0.8f;
w = (int)(ratio * bb.width);
h = (int)(ratio * bb.height);
bb = Rect( center.x - ( w / 2 ), center.y - ( h / 2 ), w, h );
break;
case Scale_0_9:
ratio = 0.9f;
w = (int)(ratio * bb.width);
h = (int)(ratio * bb.height);
bb = Rect( center.x - ( w / 2 ), center.y - ( h / 2 ), w, h );
break;
case 11:
//scale 1.1
ratio = 1.1f;
w = (int)(ratio * bb.width);
h = (int)(ratio * bb.height);
bb = Rect( center.x - ( w / 2 ), center.y - ( h / 2 ), w, h );
break;
case 12:
//scale 1.2
ratio = 1.2f;
w = (int)(ratio * bb.width);
h = (int)(ratio * bb.height);
bb = Rect( center.x - ( w / 2 ), center.y - ( h / 2 ), w, h );
break;
default:
break;
}
return bb;
}
template<typename Tracker, typename ROI_t>
void TrackerTest<Tracker, ROI_t>::distanceAndOverlapTest()
{
bool initialized = false;
int fc = ( startFrame - gtStartFrame );
bbs.at( fc ) = applyShift(bbs.at( fc ));
Rect currentBBi = bbs.at( fc );
ROI_t currentBB(currentBBi);
float sumDistance = 0;
float sumOverlap = 0;
string folder = cvtest::TS::ptr()->get_data_path() + "/" + TRACKING_DIR + "/" + video + "/" + FOLDER_IMG;
string videoPath = folder + "/" + video + ".webm";
VideoCapture c;
c.open(videoPath);
ASSERT_TRUE(c.isOpened()) << videoPath;
#if 0
c.set(CAP_PROP_POS_FRAMES, startFrame);
#else
if (startFrame)
std::cout << "startFrame = " << startFrame << std::endl;
for (int i = 0; i < startFrame; i++)
{
Mat dummy_frame;
c >> dummy_frame;
ASSERT_FALSE(dummy_frame.empty()) << i << ": " << videoPath;
}
#endif
for ( int frameCounter = startFrame; frameCounter < endFrame; frameCounter++ )
{
Mat frame;
c >> frame;
ASSERT_FALSE(frame.empty()) << "frameCounter=" << frameCounter << " video=" << videoPath;
if( !initialized )
{
#if 0
if( !tracker->init( frame, currentBB ) )
{
FAIL()<< "Could not initialize tracker" << endl;
return;
}
#else
tracker->init(frame, currentBB);
#endif
std::cout << "frame size = " << frame.size() << std::endl;
initialized = true;
}
else if( initialized )
{
if( frameCounter >= (int) bbs.size() )
break;
tracker->update( frame, currentBB );
}
float curDistance = calcDistance( currentBB, bbs.at( fc ) );
float curOverlap = calcOverlap( currentBB, bbs.at( fc ) );
#ifdef DEBUG_TEST
Mat result;
repeat(frame, 1, 2, result);
rectangle(result, currentBB, Scalar(0, 255, 0), 1);
Rect roi2(frame.cols, 0, frame.cols, frame.rows);
rectangle(result(roi2), bbs.at(fc), Scalar(0, 0, 255), 1);
imshow("result", result);
waitKey(1);
#endif
sumDistance += curDistance;
sumOverlap += curOverlap;
fc++;
}
float meanDistance = sumDistance / (endFrame - startFrame);
float meanOverlap = sumOverlap / (endFrame - startFrame);
EXPECT_LE(meanDistance, distanceThreshold);
EXPECT_GE(meanOverlap, overlapThreshold);
}
template<typename Tracker, typename ROI_t>
void TrackerTest<Tracker, ROI_t>::checkDataTest()
{
FileStorage fs;
fs.open( cvtest::TS::ptr()->get_data_path() + TRACKING_DIR + "/" + video + "/" + video + ".yml", FileStorage::READ );
fs["start"] >> startFrame;
fs["prefix"] >> prefix;
fs["suffix"] >> suffix;
fs.release();
string gtFile = cvtest::TS::ptr()->get_data_path() + TRACKING_DIR + "/" + video + "/gt.txt";
std::ifstream gt;
//open the ground truth
gt.open( gtFile.c_str() );
ASSERT_TRUE(gt.is_open()) << gtFile;
string line;
int bbCounter = 0;
while ( getline( gt, line ) )
{
bbCounter++;
}
gt.close();
int seqLength = bbCounter;
for ( int i = startFrame; i < seqLength; i++ )
{
validSequence.push_back( i );
}
//exclude from the images sequence, the frames where the target is occluded or out of view
string omitFile = cvtest::TS::ptr()->get_data_path() + TRACKING_DIR + "/" + video + "/" + FOLDER_OMIT_INIT + "/" + video + ".txt";
std::ifstream omit;
omit.open( omitFile.c_str() );
if( omit.is_open() )
{
string omitLine;
while ( getline( omit, omitLine ) )
{
vector<string> tokens = splitString( omitLine, " " );
int s_start = atoi( tokens.at( 0 ).c_str() );
int s_end = atoi( tokens.at( 1 ).c_str() );
for ( int k = s_start; k <= s_end; k++ )
{
std::vector<int>::iterator position = std::find( validSequence.begin(), validSequence.end(), k );
if( position != validSequence.end() )
validSequence.erase( position );
}
}
}
omit.close();
gtStartFrame = startFrame;
//compute the start and the and for each segment
int numFrame = (int)(validSequence.size() / numSegments);
startFrame += ( segmentIdx - 1 ) * numFrame;
endFrame = startFrame + numFrame;
std::ifstream gt2;
//open the ground truth
gt2.open( gtFile.c_str() );
ASSERT_TRUE(gt2.is_open()) << gtFile;
string line2;
int bbCounter2 = 0;
while ( getline( gt2, line2 ) )
{
vector<string> tokens = splitString( line2, "," );
Rect bb( atoi( tokens.at( 0 ).c_str() ), atoi( tokens.at( 1 ).c_str() ), atoi( tokens.at( 2 ).c_str() ), atoi( tokens.at( 3 ).c_str() ) );
ASSERT_EQ((size_t)4, tokens.size()) << "Incorrect ground truth file " << gtFile;
bbs.push_back( bb );
bbCounter2++;
}
gt2.close();
if( segmentIdx == numSegments )
endFrame = (int)bbs.size();
}
template<typename Tracker, typename ROI_t>
void TrackerTest<Tracker, ROI_t>::run()
{
srand( 1 ); // FIXIT remove that, ensure that there is no "rand()" in implementation
ASSERT_TRUE(tracker);
checkDataTest();
//check for failure
if( ::testing::Test::HasFatalFailure() )
return;
distanceAndOverlapTest();
}
/****************************************************************************************\
* Tests registrations *
@ -452,19 +83,6 @@ TEST_P(DistanceAndOverlap, MedianFlow)
test.run();
}
TEST_P(DistanceAndOverlap, MIL)
{
TrackerTest<Tracker, Rect> test(TrackerMIL::create(), dataset, 30, .65f, NoTransform);
test.run();
}
#ifdef TEST_LEGACY
TEST_P(DistanceAndOverlap, MIL_legacy)
{
TrackerTest<legacy::Tracker> test(legacy::TrackerMIL::create(), dataset, 30, .65f, NoTransform);
test.run();
}
#endif
TEST_P(DistanceAndOverlap, Boosting)
{
TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 70, .7f, NoTransform);
@ -517,19 +135,6 @@ TEST_P(DistanceAndOverlap, Shifted_Data_MedianFlow)
test.run();
}
TEST_P(DistanceAndOverlap, Shifted_Data_MIL)
{
TrackerTest<Tracker, Rect> test(TrackerMIL::create(), dataset, 30, .6f, CenterShiftLeft);
test.run();
}
#ifdef TEST_LEGACY
TEST_P(DistanceAndOverlap, Shifted_Data_MIL_legacy)
{
TrackerTest<legacy::Tracker> test(legacy::TrackerMIL::create(), dataset, 30, .6f, CenterShiftLeft);
test.run();
}
#endif
TEST_P(DistanceAndOverlap, Shifted_Data_Boosting)
{
TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 80, .65f, CenterShiftLeft);
@ -582,19 +187,6 @@ TEST_P(DistanceAndOverlap, Scaled_Data_MedianFlow)
test.run();
}
TEST_P(DistanceAndOverlap, Scaled_Data_MIL)
{
TrackerTest<Tracker, Rect> test(TrackerMIL::create(), dataset, 30, .7f, Scale_1_1);
test.run();
}
#ifdef TEST_LEGACY
TEST_P(DistanceAndOverlap, Scaled_Data_MIL_legacy)
{
TrackerTest<legacy::Tracker> test(legacy::TrackerMIL::create(), dataset, 30, .7f, Scale_1_1);
test.run();
}
#endif
TEST_P(DistanceAndOverlap, Scaled_Data_Boosting)
{
TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 80, .7f, Scale_1_1);
@ -639,49 +231,6 @@ TEST_P(DistanceAndOverlap, Scaled_Data_CSRT_legacy)
}
#endif
TEST_P(DistanceAndOverlap, GOTURN)
{
std::string model = cvtest::findDataFile("dnn/gsoc2016-goturn/goturn.prototxt");
std::string weights = cvtest::findDataFile("dnn/gsoc2016-goturn/goturn.caffemodel", false);
cv::TrackerGOTURN::Params params;
params.modelTxt = model;
params.modelBin = weights;
TrackerTest<Tracker, Rect> test(TrackerGOTURN::create(params), dataset, 35, .35f, NoTransform);
test.run();
}
INSTANTIATE_TEST_CASE_P(Tracking, DistanceAndOverlap, TESTSET_NAMES);
TEST(GOTURN, memory_usage)
{
cv::Rect roi(145, 70, 85, 85);
std::string model = cvtest::findDataFile("dnn/gsoc2016-goturn/goturn.prototxt");
std::string weights = cvtest::findDataFile("dnn/gsoc2016-goturn/goturn.caffemodel", false);
cv::TrackerGOTURN::Params params;
params.modelTxt = model;
params.modelBin = weights;
cv::Ptr<Tracker> tracker = TrackerGOTURN::create(params);
string inputVideo = cvtest::findDataFile("tracking/david/data/david.webm");
cv::VideoCapture video(inputVideo);
ASSERT_TRUE(video.isOpened()) << inputVideo;
cv::Mat frame;
video >> frame;
ASSERT_FALSE(frame.empty()) << inputVideo;
tracker->init(frame, roi);
string ground_truth_bb;
for (int nframes = 0; nframes < 15; ++nframes)
{
std::cout << "Frame: " << nframes << std::endl;
video >> frame;
bool res = tracker->update(frame, roi);
ASSERT_TRUE(res);
std::cout << "Predicted ROI: " << roi << std::endl;
}
}
}} // namespace

Loading…
Cancel
Save