tracking: move Tracking API to the main repository

pull/2753/head
Alexander Alekhin 5 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) 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, @inproceedings{OLB,
title={Real-Time Tracking via On-line Boosting.}, title={Real-Time Tracking via On-line Boosting.},
author={Grabner, Helmut and Grabner, Michael and Bischof, Horst}, author={Grabner, Helmut and Grabner, Michael and Bischof, Horst},
@ -37,28 +28,6 @@
publisher={IEEE} 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, @inproceedings{OOT,
title={Online object tracking: A benchmark}, title={Online object tracking: A benchmark},
author={Wu, Yi and Lim, Jongwoo and Yang, Ming-Hsuan}, author={Wu, Yi and Lim, Jongwoo and Yang, Ming-Hsuan},
@ -94,13 +63,6 @@
doi={10.1109/CVPR.2014.143}, 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, @inproceedings{MOSSE,
title={Visual Object Tracking using Adaptive Correlation Filters}, title={Visual Object Tracking using Adaptive Correlation Filters},
author={Bolme, David S. and Beveridge, J. Ross and Draper, Bruce A. and Lui Yui, Man}, 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 #define OPENCV_CONTRIB_TRACKING_HPP
#include "opencv2/core.hpp" #include "opencv2/core.hpp"
#include "opencv2/video/tracking.hpp"
namespace cv { namespace cv {
#ifndef CV_DOXYGEN #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 /** @brief the CSRT tracker
The implementation is based on @cite Lukezic_IJCV2018 Discriminative Correlation Filter with Channel and Spatial Reliability 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 /** @brief the KCF (Kernelized Correlation Filter) tracker
* KCF is a novel tracking framework that utilizes properties of circulant matrix to enhance the processing speed. * 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 #ifndef CV_DOXYGEN

@ -60,7 +60,7 @@ inline namespace tracking {
//! @addtogroup tracking_detail //! @addtogroup tracking_detail
//! @{ //! @{
inline namespace feature { inline namespace contrib_feature {
#define FEATURES "features" #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/////////////////////////////////////////////////////////////////////////////////////// // This file is part of OpenCV project.
// // It is subject to the license terms in the LICENSE file found in the top-level directory
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // of this distribution and at http://opencv.org/license.html.
//
// 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_TRACKING_DETAIL_HPP #ifndef OPENCV_TRACKING_DETAIL_HPP
#define 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 "feature.hpp" // CvHaarEvaluator
#include "onlineBoosting.hpp" // StrongClassifierDirectSelection #include "onlineBoosting.hpp" // StrongClassifierDirectSelection
#include "onlineMIL.hpp" // ClfMilBoost
namespace cv { namespace cv {
namespace detail { 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 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. 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 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 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 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. 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. the TrackerModel is the statistical model.
A recent benchmark between these algorithms can be found in @cite OOT 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", That function can (and probably will) return a pointer to some derived class of "classname",
which will probably have a real constructor. 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 are instantiated from Tracker base class, instead the last component is abstract, so you must
implement your TrackerModel. implement your TrackerModel.
### TrackerSampler ### TrackerContribSampler
TrackerSampler is already instantiated, but you should define the sampling algorithm and add the TrackerContribSampler 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 classes (or single class) to TrackerContribSampler. You can choose one of the ready implementation as
TrackerSamplerCSC or you can implement your sampling method, in this case the class must inherit TrackerContribSamplerCSC 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 TrackerContribSamplerAlgorithm. Fill the samplingImpl method that writes the result in "sample" output
argument. argument.
Example of creating specialized TrackerSamplerAlgorithm TrackerSamplerCSC : : Example of creating specialized TrackerContribSamplerAlgorithm TrackerContribSamplerCSC : :
@code @code
class CV_EXPORTS_W TrackerSamplerCSC : public TrackerSamplerAlgorithm class CV_EXPORTS_W TrackerContribSamplerCSC : public TrackerContribSamplerAlgorithm
{ {
public: public:
TrackerSamplerCSC( const TrackerSamplerCSC::Params &parameters = TrackerSamplerCSC::Params() ); TrackerContribSamplerCSC( const TrackerContribSamplerCSC::Params &parameters = TrackerContribSamplerCSC::Params() );
~TrackerSamplerCSC(); ~TrackerContribSamplerCSC();
... ...
protected: protected:
@ -159,10 +121,10 @@ Example of creating specialized TrackerSamplerAlgorithm TrackerSamplerCSC : :
}; };
@endcode @endcode
Example of adding TrackerSamplerAlgorithm to TrackerSampler : : Example of adding TrackerContribSamplerAlgorithm to TrackerContribSampler : :
@code @code
//sampler is the TrackerSampler //sampler is the TrackerContribSampler
Ptr<TrackerSamplerAlgorithm> CSCSampler = new TrackerSamplerCSC( CSCparameters ); Ptr<TrackerContribSamplerAlgorithm> CSCSampler = new TrackerContribSamplerCSC( CSCparameters );
if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) ) if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) )
return false; return false;
@ -170,23 +132,23 @@ Example of adding TrackerSamplerAlgorithm to TrackerSampler : :
//sampler->addTrackerSamplerAlgorithm( "CSC" ); //sampler->addTrackerSamplerAlgorithm( "CSC" );
@endcode @endcode
@sa @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 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 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. 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 @code
class CV_EXPORTS_W TrackerFeatureHAAR : public TrackerFeature class CV_EXPORTS_W TrackerContribFeatureHAAR : public TrackerFeature
{ {
public: public:
TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parameters = TrackerFeatureHAAR::Params() ); TrackerContribFeatureHAAR( const TrackerContribFeatureHAAR::Params &parameters = TrackerContribFeatureHAAR::Params() );
~TrackerFeatureHAAR(); ~TrackerContribFeatureHAAR();
void selection( Mat& response, int npoints ); void selection( Mat& response, int npoints );
... ...
@ -196,14 +158,14 @@ Example of creating specialized TrackerFeature TrackerFeatureHAAR : :
}; };
@endcode @endcode
Example of adding TrackerFeature to TrackerFeatureSet : : Example of adding TrackerFeature to TrackerContribFeatureSet : :
@code @code
//featureSet is the TrackerFeatureSet //featureSet is the TrackerContribFeatureSet
Ptr<TrackerFeature> trackerFeature = new TrackerFeatureHAAR( HAARparameters ); Ptr<TrackerFeature> trackerFeature = new TrackerContribFeatureHAAR( HAARparameters );
featureSet->addTrackerFeature( trackerFeature ); featureSet->addTrackerFeature( trackerFeature );
@endcode @endcode
@sa @sa
TrackerFeatureHAAR, TrackerFeatureSet TrackerContribFeatureHAAR, TrackerContribFeatureSet
### TrackerModel ### 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: public:
virtual ~TrackerFeature(); virtual ~TrackerContribFeature();
/** @brief Compute the features in the images collection /** @brief Create TrackerContribFeature by tracker feature type
@param images The images @param trackerFeatureType The TrackerContribFeature name
@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
The modes available now: The modes available now:
@ -325,25 +281,22 @@ class CV_EXPORTS TrackerFeature
- "HOG" -- Histogram of Oriented Gradients features - "HOG" -- Histogram of Oriented Gradients features
- "LBP" -- Local Binary Pattern features - "LBP" -- Local Binary Pattern features
- "FEATURE2D" -- All types of Feature2D - "FEATURE2D" -- All types of Feature2D
*/ */
static Ptr<TrackerFeature> create( const String& trackerFeatureType ); static Ptr<TrackerContribFeature> create( const String& trackerFeatureType );
/** @brief Identify most effective features /** @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 @param npoints Max number of features
@note This method modifies the response parameter @note This method modifies the response parameter
*/ */
virtual void selection( Mat& response, int npoints ) = 0; 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; String getClassName() const;
protected: protected:
virtual bool computeImpl( const std::vector<Mat>& images, Mat& response ) = 0;
String className; 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, See table I and section III C @cite AMVOT Appearance modelling -\> Visual representation (Table II,
section 3.1 - 3.2) section 3.1 - 3.2)
TrackerFeatureSet is an aggregation of TrackerFeature TrackerContribFeatureSet is an aggregation of TrackerContribFeature
@sa @sa
TrackerFeature TrackerContribFeature
*/ */
class CV_EXPORTS TrackerFeatureSet class CV_EXPORTS TrackerContribFeatureSet
{ {
public: public:
TrackerFeatureSet(); TrackerContribFeatureSet();
~TrackerFeatureSet(); ~TrackerContribFeatureSet();
/** @brief Extract features from the images collection /** @brief Extract features from the images collection
@param images The input images @param images The input images
@ -380,8 +333,8 @@ class CV_EXPORTS TrackerFeatureSet
*/ */
void removeOutliers(); void removeOutliers();
/** @brief Add TrackerFeature in the collection. Return true if TrackerFeature is added, false otherwise /** @brief Add TrackerContribFeature in the collection. Return true if TrackerContribFeature is added, false otherwise
@param trackerFeatureType The TrackerFeature name @param trackerFeatureType The TrackerContribFeature name
The modes available now: The modes available now:
@ -393,32 +346,32 @@ class CV_EXPORTS TrackerFeatureSet
- "LBP" -- Local Binary Pattern features - "LBP" -- Local Binary Pattern features
- "FEATURE2D" -- All types of Feature2D - "FEATURE2D" -- All types of Feature2D
Example TrackerFeatureSet::addTrackerFeature : : Example TrackerContribFeatureSet::addTrackerFeature : :
@code @code
//sample usage: //sample usage:
Ptr<TrackerFeature> trackerFeature = new TrackerFeatureHAAR( HAARparameters ); Ptr<TrackerContribFeature> trackerFeature = ...;
featureSet->addTrackerFeature( trackerFeature ); featureSet->addTrackerFeature( trackerFeature );
//or add CSC sampler with default parameters //or add CSC sampler with default parameters
//featureSet->addTrackerFeature( "HAAR" ); //featureSet->addTrackerFeature( "HAAR" );
@endcode @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 ); bool addTrackerFeature( String trackerFeatureType );
/** @overload /** @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 /** @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; const std::vector<Mat>& getResponses() const;
@ -427,25 +380,26 @@ class CV_EXPORTS TrackerFeatureSet
void clearResponses(); void clearResponses();
bool blockAddTrackerFeature; 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 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. sampler.
*/ */
class CV_EXPORTS TrackerSamplerAlgorithm class CV_EXPORTS TrackerContribSamplerAlgorithm : public TrackerSamplerAlgorithm
{ {
public: public:
/** /**
* \brief Destructor * \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 @param trackerSamplerType The trackerSamplerType name
The modes available now: The modes available now:
@ -453,7 +407,7 @@ class CV_EXPORTS TrackerSamplerAlgorithm
- "CSC" -- Current State Center - "CSC" -- Current State Center
- "CS" -- Current State - "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. /** @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 @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; String getClassName() const;
@ -485,23 +439,23 @@ class CV_EXPORTS TrackerSamplerAlgorithm
@cite AAM Sampling e Labeling. See table I and section III B @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 @sa
TrackerSamplerAlgorithm TrackerContribSamplerAlgorithm
*/ */
class CV_EXPORTS TrackerSampler class CV_EXPORTS TrackerContribSampler
{ {
public: public:
/** /**
* \brief Constructor * \brief Constructor
*/ */
TrackerSampler(); TrackerContribSampler();
/** /**
* \brief Destructor * \brief Destructor
*/ */
~TrackerSampler(); ~TrackerContribSampler();
/** @brief Computes the regions starting from a position in an image /** @brief Computes the regions starting from a position in an image
@param image The current frame @param image The current frame
@ -509,26 +463,26 @@ class CV_EXPORTS TrackerSampler
*/ */
void sampling( const Mat& image, Rect boundingBox ); 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; const std::vector<Mat>& getSamples() const;
/** @brief Add TrackerSamplerAlgorithm in the collection. Return true if sampler is added, false otherwise /** @brief Add TrackerContribSamplerAlgorithm in the collection. Return true if sampler is added, false otherwise
@param trackerSamplerAlgorithmType The TrackerSamplerAlgorithm name @param trackerSamplerAlgorithmType The TrackerContribSamplerAlgorithm name
The modes available now: The modes available now:
- "CSC" -- Current State Center - "CSC" -- Current State Center
- "CS" -- Current State - "CS" -- Current State
- "PF" -- Particle Filtering - "PF" -- Particle Filtering
Example TrackerSamplerAlgorithm::addTrackerSamplerAlgorithm : : Example TrackerContribSamplerAlgorithm::addTrackerContribSamplerAlgorithm : :
@code @code
TrackerSamplerCSC::Params CSCparameters; TrackerContribSamplerCSC::Params CSCparameters;
Ptr<TrackerSamplerAlgorithm> CSCSampler = new TrackerSamplerCSC( CSCparameters ); Ptr<TrackerContribSamplerAlgorithm> CSCSampler = new TrackerContribSamplerCSC( CSCparameters );
if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) ) if( !sampler->addTrackerSamplerAlgorithm( CSCSampler ) )
return false; return false;
@ -536,300 +490,23 @@ class CV_EXPORTS TrackerSampler
//or add CSC sampler with default parameters //or add CSC sampler with default parameters
//sampler->addTrackerSamplerAlgorithm( "CSC" ); //sampler->addTrackerSamplerAlgorithm( "CSC" );
@endcode @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 ); bool addTrackerSamplerAlgorithm( String trackerSamplerAlgorithmType );
/** @overload /** @overload
@param sampler The TrackerSamplerAlgorithm @param sampler The TrackerContribSamplerAlgorithm
*/ */
bool addTrackerSamplerAlgorithm( Ptr<TrackerSamplerAlgorithm>& sampler ); bool addTrackerSamplerAlgorithm( Ptr<TrackerContribSamplerAlgorithm>& sampler );
private: private:
std::vector<std::pair<String, Ptr<TrackerSamplerAlgorithm> > > samplers; std::vector<std::pair<String, Ptr<TrackerContribSamplerAlgorithm> > > samplers;
std::vector<Mat> samples; std::vector<Mat> samples;
bool blockAddTrackerSampler; bool blockAddTrackerSampler;
void clearSamples(); 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 /** @brief TrackerStateEstimatorAdaBoosting based on ADA-Boosting
*/ */
@ -838,7 +515,7 @@ class CV_EXPORTS TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator
public: public:
/** @brief Implementation of the target state for TrackerAdaBoostingTargetState /** @brief Implementation of the target state for TrackerAdaBoostingTargetState
*/ */
class TrackerAdaBoostingTargetState : public TrackerTargetState class CV_EXPORTS TrackerAdaBoostingTargetState : public TrackerTargetState
{ {
public: 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 @param responses The features extracted
*/ */
void setTargetResponses( const Mat& responses ); void setTargetResponses( const Mat& responses );
@ -940,6 +617,7 @@ class CV_EXPORTS TrackerStateEstimatorAdaBoosting : public TrackerStateEstimator
ConfidenceMap currentConfidenceMap; ConfidenceMap currentConfidenceMap;
}; };
/** /**
* \brief TrackerStateEstimator based on SVM * \brief TrackerStateEstimator based on SVM
*/ */
@ -954,11 +632,13 @@ class CV_EXPORTS TrackerStateEstimatorSVM : public TrackerStateEstimator
void updateImpl( std::vector<ConfidenceMap>& confidenceMaps ) CV_OVERRIDE; void updateImpl( std::vector<ConfidenceMap>& confidenceMaps ) CV_OVERRIDE;
}; };
/************************************ Specific TrackerSamplerAlgorithm Classes ************************************/ /************************************ Specific TrackerSamplerAlgorithm Classes ************************************/
/** @brief TrackerSampler based on CSC (current state centered), used by MIL algorithm TrackerMIL /** @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: public:
enum enum
@ -982,11 +662,11 @@ class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm
}; };
/** @brief Constructor /** @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 @param samplingMode The sampling mode
The modes are: The modes are:
@ -999,11 +679,11 @@ class CV_EXPORTS TrackerSamplerCSC : public TrackerSamplerAlgorithm
*/ */
void setMode( int samplingMode ); void setMode( int samplingMode );
~TrackerSamplerCSC(); ~TrackerContribSamplerCSC();
protected: 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: 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 ); 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: public:
enum 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 their histograms. As experiments show, tracker is *not* very succesfull if target is assumed to
strongly change its dimensions. strongly change its dimensions.
*/ */
class CV_EXPORTS TrackerSamplerPF : public TrackerSamplerAlgorithm class CV_EXPORTS TrackerSamplerPF : public TrackerContribSamplerAlgorithm
{ {
public: public:
/** @brief This structure contains all the parameters that can be varied during the course of sampling /** @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; 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: 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: 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 @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: public:
struct CV_EXPORTS Params struct CV_EXPORTS Params
@ -1176,21 +859,21 @@ class CV_EXPORTS TrackerFeatureHAAR : public TrackerFeature
}; };
/** @brief Constructor /** @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 /** @brief Compute the features only for the selected indices in the images collection
@param selFeatures indices of selected features @param selFeatures indices of selected features
@param images The images @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 ); bool extractSelected( const std::vector<int> selFeatures, const std::vector<Mat>& images, Mat& response );
/** @brief Identify most effective features /** @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 @param npoints Max number of features
@note This method modifies the response parameter @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: public:

@ -104,8 +104,8 @@ class CV_EXPORTS_W Tracker : public virtual Algorithm
bool isInit; bool isInit;
Ptr<TrackerFeatureSet> featureSet; Ptr<TrackerContribFeatureSet> featureSet;
Ptr<TrackerSampler> sampler; Ptr<TrackerContribSampler> sampler;
Ptr<TrackerModel> model; 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 class CV_EXPORTS_W TrackerMIL : public cv::legacy::Tracker
{ {
public: public:
struct CV_EXPORTS Params : cv::tracking::TrackerMIL::Params struct CV_EXPORTS Params : cv::TrackerMIL::Params
{ {
void read( const FileNode& fn ); void read( const FileNode& fn );
void write( FileStorage& fs ) const; 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.core.CvException;
import org.opencv.test.OpenCVTestCase; import org.opencv.test.OpenCVTestCase;
import org.opencv.tracking.Tracking; import org.opencv.video.Tracker;
import org.opencv.tracking.Tracker; import org.opencv.video.TrackerGOTURN;
import org.opencv.tracking.TrackerGOTURN;
import org.opencv.tracking.TrackerKCF; import org.opencv.tracking.TrackerKCF;
import org.opencv.tracking.TrackerMIL; import org.opencv.video.TrackerMIL;
public class TrackerCreateTest extends OpenCVTestCase { public class TrackerCreateTest extends OpenCVTestCase {

@ -1,6 +1,4 @@
#ifdef HAVE_OPENCV_TRACKING #ifdef HAVE_OPENCV_TRACKING
typedef TrackerCSRT::Params TrackerCSRT_Params; typedef TrackerCSRT::Params TrackerCSRT_Params;
typedef TrackerKCF::Params TrackerKCF_Params; typedef TrackerKCF::Params TrackerKCF_Params;
typedef TrackerMIL::Params TrackerMIL_Params;
typedef TrackerGOTURN::Params TrackerGOTURN_Params;
#endif #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())) PERF_TEST_P(Tracking, Boosting, testing::ValuesIn(getTrackingParams()))
{ {
auto tracker = legacy::TrackerBoosting::create(); auto tracker = legacy::TrackerBoosting::create();
@ -105,15 +99,4 @@ PERF_TEST_P(Tracking, TLD, testing::ValuesIn(getTrackingParams()))
runTrackingTest(tracker, GetParam()); 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 }} // 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() ) if( image.empty() )
return false; return false;
sampler = Ptr<TrackerSampler>( new TrackerSampler() ); sampler = Ptr<TrackerContribSampler>( new TrackerContribSampler() );
featureSet = Ptr<TrackerFeatureSet>( new TrackerFeatureSet() ); featureSet = Ptr<TrackerContribFeatureSet>( new TrackerContribFeatureSet() );
model = Ptr<TrackerModel>(); model = Ptr<TrackerModel>();
bool initTracker = initImpl( image.getMat(), boundingBox ); bool initTracker = initImpl( image.getMat(), boundingBox );
//check if the model component is initialized if (initTracker)
if (!model)
{
CV_Error( -1, "The model is not initialized" );
}
if( initTracker )
{ {
isInit = true; 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_; const Ptr<legacy::Tracker> legacy_tracker_;
public: 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); return makePtr<LegacyTrackerWrapper>(legacy_tracker);
} }

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

@ -72,8 +72,8 @@ public:
{ {
impl.init(image, boundingBox); impl.init(image, boundingBox);
model = impl.model; model = impl.model;
sampler = makePtr<TrackerSampler>(); sampler = makePtr<TrackerContribSampler>();
featureSet = makePtr<TrackerFeatureSet>(); featureSet = makePtr<TrackerContribFeatureSet>();
isInit = true; isInit = true;
return 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" #include "precomp.hpp"
namespace cv { // see modules/video/src/tracking/tracker.cpp
inline namespace tracking {
Tracker::Tracker()
{
// nothing
}
Tracker::~Tracker()
{
// nothing
}
}} // namespace
#include "legacy/tracker.legacy.hpp" #include "legacy/tracker.legacy.hpp"

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

@ -46,23 +46,15 @@ namespace detail {
inline namespace tracking { inline namespace tracking {
/* /*
* TrackerFeature * TrackerContribFeature
*/ */
TrackerFeature::~TrackerFeature() TrackerContribFeature::~TrackerContribFeature()
{ {
} }
void TrackerFeature::compute( const std::vector<Mat>& images, Mat& response ) Ptr<TrackerContribFeature> TrackerContribFeature::create( const String& trackerFeatureType )
{
if( images.empty() )
return;
computeImpl( images, response );
}
Ptr<TrackerFeature> TrackerFeature::create( const String& trackerFeatureType )
{ {
if( trackerFeatureType.find( "FEATURE2D" ) == 0 ) if( trackerFeatureType.find( "FEATURE2D" ) == 0 )
{ {
@ -82,7 +74,7 @@ Ptr<TrackerFeature> TrackerFeature::create( const String& trackerFeatureType )
if( trackerFeatureType.find( "HAAR" ) == 0 ) if( trackerFeatureType.find( "HAAR" ) == 0 )
{ {
return Ptr<TrackerFeatureHAAR>( new TrackerFeatureHAAR() ); return Ptr<TrackerContribFeatureHAAR>( new TrackerContribFeatureHAAR() );
} }
if( trackerFeatureType.find( "LBP" ) == 0 ) if( trackerFeatureType.find( "LBP" ) == 0 )
@ -93,7 +85,7 @@ Ptr<TrackerFeature> TrackerFeature::create( const String& trackerFeatureType )
CV_Error( -1, "Tracker feature type not supported" ); CV_Error( -1, "Tracker feature type not supported" );
} }
String TrackerFeature::getClassName() const String TrackerContribFeature::getClassName() const
{ {
return className; return className;
} }
@ -145,21 +137,21 @@ void TrackerFeatureHOG::selection( Mat& /*response*/, int /*npoints*/)
} }
/** /**
* TrackerFeatureHAAR * TrackerContribFeatureHAAR
*/ */
/** /**
* Parameters * Parameters
*/ */
TrackerFeatureHAAR::Params::Params() TrackerContribFeatureHAAR::Params::Params()
{ {
numFeatures = 250; numFeatures = 250;
rectSize = Size( 100, 100 ); rectSize = Size( 100, 100 );
isIntegral = false; isIntegral = false;
} }
TrackerFeatureHAAR::TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parameters ) : TrackerContribFeatureHAAR::TrackerContribFeatureHAAR( const TrackerContribFeatureHAAR::Params &parameters ) :
params( parameters ) params( parameters )
{ {
className = "HAAR"; className = "HAAR";
@ -171,23 +163,23 @@ TrackerFeatureHAAR::TrackerFeatureHAAR( const TrackerFeatureHAAR::Params &parame
featureEvaluator->init( &haarParams, 1, params.rectSize ); 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 ); return featureEvaluator->getFeatures( id );
} }
bool TrackerFeatureHAAR::swapFeature( int id, CvHaarEvaluator::FeatureHaar& feature ) bool TrackerContribFeatureHAAR::swapFeature( int id, CvHaarEvaluator::FeatureHaar& feature )
{ {
featureEvaluator->getFeatures( id ) = feature; featureEvaluator->getFeatures( id ) = feature;
return true; return true;
} }
bool TrackerFeatureHAAR::swapFeature( int source, int target ) bool TrackerContribFeatureHAAR::swapFeature( int source, int target )
{ {
CvHaarEvaluator::FeatureHaar feature = featureEvaluator->getFeatures( source ); CvHaarEvaluator::FeatureHaar feature = featureEvaluator->getFeatures( source );
featureEvaluator->getFeatures( source ) = featureEvaluator->getFeatures( target ); featureEvaluator->getFeatures( source ) = featureEvaluator->getFeatures( target );
@ -195,7 +187,7 @@ bool TrackerFeatureHAAR::swapFeature( int source, int target )
return true; 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() ) 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() ) if( images.empty() )
{ {
@ -294,7 +286,7 @@ bool TrackerFeatureHAAR::computeImpl( const std::vector<Mat>& images, Mat& respo
return true; 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 { inline namespace tracking {
/* /*
* TrackerFeatureSet * TrackerContribFeatureSet
*/ */
/* /*
* Constructor * Constructor
*/ */
TrackerFeatureSet::TrackerFeatureSet() TrackerContribFeatureSet::TrackerContribFeatureSet()
{ {
blockAddTrackerFeature = false; blockAddTrackerFeature = false;
} }
@ -60,12 +60,12 @@ TrackerFeatureSet::TrackerFeatureSet()
/* /*
* Destructor * Destructor
*/ */
TrackerFeatureSet::~TrackerFeatureSet() TrackerContribFeatureSet::~TrackerContribFeatureSet()
{ {
} }
void TrackerFeatureSet::extraction( const std::vector<Mat>& images ) void TrackerContribFeatureSet::extraction( const std::vector<Mat>& images )
{ {
clearResponses(); 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 ) if( blockAddTrackerFeature )
{ {
return false; return false;
} }
Ptr<TrackerFeature> feature = TrackerFeature::create( trackerFeatureType ); Ptr<TrackerContribFeature> feature = TrackerContribFeature::create( trackerFeatureType );
if (!feature) if (!feature)
{ {
@ -112,7 +112,7 @@ bool TrackerFeatureSet::addTrackerFeature( String trackerFeatureType )
return true; return true;
} }
bool TrackerFeatureSet::addTrackerFeature( Ptr<TrackerFeature>& feature ) bool TrackerContribFeatureSet::addTrackerFeature( Ptr<TrackerContribFeature>& feature )
{ {
if( blockAddTrackerFeature ) if( blockAddTrackerFeature )
{ {
@ -125,17 +125,17 @@ bool TrackerFeatureSet::addTrackerFeature( Ptr<TrackerFeature>& feature )
return true; 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; return features;
} }
const std::vector<Mat>& TrackerFeatureSet::getResponses() const const std::vector<Mat>& TrackerContribFeatureSet::getResponses() const
{ {
return responses; return responses;
} }
void TrackerFeatureSet::clearResponses() void TrackerContribFeatureSet::clearResponses()
{ {
responses.clear(); 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*/ //M*/
#include "precomp.hpp"
#include "opencv2/tracking/tracking_legacy.hpp" #include "opencv2/tracking/tracking_legacy.hpp"
namespace cv { namespace cv {
@ -49,36 +50,41 @@ namespace impl {
class TrackerMILImpl CV_FINAL : public legacy::TrackerMIL class TrackerMILImpl CV_FINAL : public legacy::TrackerMIL
{ {
public: public:
cv::tracking::impl::TrackerMILImpl impl; Ptr<cv::TrackerMIL> impl;
legacy::TrackerMIL::Params params;
TrackerMILImpl(const legacy::TrackerMIL::Params &parameters) TrackerMILImpl(const legacy::TrackerMIL::Params &parameters)
: impl(parameters) : impl(cv::TrackerMIL::create(parameters))
, params(parameters)
{ {
isInit = false; isInit = false;
} }
void read(const FileNode& fn) CV_OVERRIDE 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 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); int x1 = cvRound(boundingBox2d.x);
model = impl.model; int y1 = cvRound(boundingBox2d.y);
featureSet = impl.featureSet; int x2 = cvRound(boundingBox2d.x + boundingBox2d.width);
sampler = impl.sampler; 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; isInit = true;
return true; return true;
} }
bool updateImpl(const Mat& image, Rect2d& boundingBox) CV_OVERRIDE bool updateImpl(const Mat& image, Rect2d& boundingBox) CV_OVERRIDE
{ {
Rect bb; Rect bb;
bool res = impl.update(image, bb); bool res = impl->update(image, bb);
boundingBox = bb; boundingBox = bb;
return res; 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 { inline namespace tracking {
/* /*
* TrackerSampler * TrackerContribSampler
*/ */
/* /*
* Constructor * Constructor
*/ */
TrackerSampler::TrackerSampler() TrackerContribSampler::TrackerContribSampler()
{ {
blockAddTrackerSampler = false; blockAddTrackerSampler = false;
} }
@ -60,12 +60,12 @@ TrackerSampler::TrackerSampler()
/* /*
* Destructor * Destructor
*/ */
TrackerSampler::~TrackerSampler() TrackerContribSampler::~TrackerContribSampler()
{ {
} }
void TrackerSampler::sampling( const Mat& image, Rect boundingBox ) void TrackerContribSampler::sampling( const Mat& image, Rect boundingBox )
{ {
clearSamples(); 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 ) if( blockAddTrackerSampler )
{ {
return false; return false;
} }
Ptr<TrackerSamplerAlgorithm> sampler = TrackerSamplerAlgorithm::create( trackerSamplerAlgorithmType ); Ptr<TrackerContribSamplerAlgorithm> sampler = TrackerContribSamplerAlgorithm::create( trackerSamplerAlgorithmType );
if (!sampler) if (!sampler)
{ {
@ -107,7 +107,7 @@ bool TrackerSampler::addTrackerSamplerAlgorithm( String trackerSamplerAlgorithmT
return true; return true;
} }
bool TrackerSampler::addTrackerSamplerAlgorithm( Ptr<TrackerSamplerAlgorithm>& sampler ) bool TrackerContribSampler::addTrackerSamplerAlgorithm( Ptr<TrackerContribSamplerAlgorithm>& sampler )
{ {
if( blockAddTrackerSampler ) if( blockAddTrackerSampler )
{ {
@ -125,17 +125,17 @@ bool TrackerSampler::addTrackerSamplerAlgorithm( Ptr<TrackerSamplerAlgorithm>& s
return true; 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; return samplers;
} }
const std::vector<Mat>& TrackerSampler::getSamples() const const std::vector<Mat>& TrackerContribSampler::getSamples() const
{ {
return samples; return samples;
} }
void TrackerSampler::clearSamples() void TrackerContribSampler::clearSamples()
{ {
samples.clear(); samples.clear();
} }

@ -48,15 +48,15 @@ namespace detail {
inline namespace tracking { 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() ) if( image.empty() )
return false; return false;
@ -64,11 +64,11 @@ bool TrackerSamplerAlgorithm::sampling( const Mat& image, Rect boundingBox, std:
return samplingImpl( image, boundingBox, sample ); return samplingImpl( image, boundingBox, sample );
} }
Ptr<TrackerSamplerAlgorithm> TrackerSamplerAlgorithm::create( const String& trackerSamplerType ) Ptr<TrackerContribSamplerAlgorithm> TrackerContribSamplerAlgorithm::create( const String& trackerSamplerType )
{ {
if( trackerSamplerType.find( "CSC" ) == 0 ) if( trackerSamplerType.find( "CSC" ) == 0 )
{ {
return Ptr<TrackerSamplerCSC>( new TrackerSamplerCSC() ); return Ptr<TrackerContribSamplerCSC>( new TrackerContribSamplerCSC() );
} }
if( trackerSamplerType.find( "CS" ) == 0 ) if( trackerSamplerType.find( "CS" ) == 0 )
@ -76,23 +76,23 @@ Ptr<TrackerSamplerAlgorithm> TrackerSamplerAlgorithm::create( const String& trac
return Ptr<TrackerSamplerCS>( new TrackerSamplerCS() ); 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; return className;
} }
/** /**
* TrackerSamplerCSC * TrackerContribSamplerCSC
*/ */
/** /**
* Parameters * Parameters
*/ */
TrackerSamplerCSC::Params::Params() TrackerContribSamplerCSC::Params::Params()
{ {
initInRad = 3; initInRad = 3;
initMaxNegNum = 65; initMaxNegNum = 65;
@ -103,7 +103,7 @@ TrackerSamplerCSC::Params::Params()
} }
TrackerSamplerCSC::TrackerSamplerCSC( const TrackerSamplerCSC::Params &parameters ) : TrackerContribSamplerCSC::TrackerContribSamplerCSC( const TrackerContribSamplerCSC::Params &parameters ) :
params( parameters ) params( parameters )
{ {
className = "CSC"; 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 inrad = 0;
float outrad = 0; float outrad = 0;
@ -159,12 +159,12 @@ bool TrackerSamplerCSC::samplingImpl( const Mat& image, Rect boundingBox, std::v
return false; return false;
} }
void TrackerSamplerCSC::setMode( int samplingMode ) void TrackerContribSamplerCSC::setMode( int samplingMode )
{ {
mode = 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 rowsz = img.rows - h - 1;
int colsz = img.cols - w - 1; int colsz = img.cols - w - 1;

@ -45,33 +45,6 @@ namespace cv {
namespace detail { namespace detail {
inline namespace tracking { 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 ) Ptr<TrackerStateEstimator> TrackerStateEstimator::create( const String& trackeStateEstimatorType )
{ {
@ -82,164 +55,14 @@ Ptr<TrackerStateEstimator> TrackerStateEstimator::create( const String& trackeSt
if( trackeStateEstimatorType.find( "BOOSTING" ) == 0 ) 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" ); 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 * TrackerStateEstimatorAdaBoosting

@ -58,379 +58,10 @@ const string TRACKING_DIR = "tracking";
const string FOLDER_IMG = "data"; const string FOLDER_IMG = "data";
const string FOLDER_OMIT_INIT = "initOmit"; const string FOLDER_OMIT_INIT = "initOmit";
/* // Check used "cmake" version in case of errors
* The Evaluation Methodologies are partially based on: // Check compiler command line options for <opencv>/modules include
* ==================================================================================================================== #include "video/test/test_trackers.impl.hpp"
* [OTB] Y. Wu, J. Lim, and M.-H. Yang, "Online object tracking: A benchmark," in Computer Vision and Pattern Recognition (CVPR), 2013
*
*/
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 * * Tests registrations *
@ -452,19 +83,6 @@ TEST_P(DistanceAndOverlap, MedianFlow)
test.run(); 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) TEST_P(DistanceAndOverlap, Boosting)
{ {
TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 70, .7f, NoTransform); TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 70, .7f, NoTransform);
@ -517,19 +135,6 @@ TEST_P(DistanceAndOverlap, Shifted_Data_MedianFlow)
test.run(); 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) TEST_P(DistanceAndOverlap, Shifted_Data_Boosting)
{ {
TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 80, .65f, CenterShiftLeft); TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 80, .65f, CenterShiftLeft);
@ -582,19 +187,6 @@ TEST_P(DistanceAndOverlap, Scaled_Data_MedianFlow)
test.run(); 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) TEST_P(DistanceAndOverlap, Scaled_Data_Boosting)
{ {
TrackerTest<legacy::Tracker> test(legacy::TrackerBoosting::create(), dataset, 80, .7f, Scale_1_1); 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 #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); 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 }} // namespace

Loading…
Cancel
Save