1. 程式人生 > >2014新跟蹤演算法KCF筆記 --續(程式碼部分)

2014新跟蹤演算法KCF筆記 --續(程式碼部分)

KCF跟蹤在opencv3.1中集成了,在opencv_contrib/tracking中有,opencv_contrib這個需要重新編譯一下opencv3.1才能get.windows下的編譯方法如下網址

http://blog.csdn.net/yomo127/article/details/50474955

可以在git上直接下載也可,地址如下

https://github.com/Itseez/opencv_contrib

如果你是直接從git下載的,可以看到關於KCF部分新增的內容如下(git log可)

/*---------------STEP 1---------------------*/
/* modify this file
*  opencv2/tracking/tracker.hpp
*  and put several lines of snippet similar to 
*  the following:
*/ 
/*------------------------------------------*/

class CV_EXPORTS_W TrackerKCF : public Tracker
{
 public:
  struct CV_EXPORTS Params
  {
    Params();
    void read( const FileNode& /*fn*/ );
    void write( FileStorage& /*fs*/ ) const;
  };

  /** @brief Constructor
    @param parameters KCF parameters TrackerKCF::Params
     */
  BOILERPLATE_CODE("KCF",TrackerKCF);
};


/*---------------STEP 2---------------------*/
/* modify this file
*  src/tracker.cpp
*  add one line in function  
*  Ptr<Tracker> Tracker::create( const String& trackerType )
*/ 
/*------------------------------------------*/

Ptr<Tracker> Tracker::create( const String& trackerType )
{
  BOILERPLATE_CODE("MIL",TrackerMIL);
  BOILERPLATE_CODE("BOOSTING",TrackerBoosting);
  BOILERPLATE_CODE("MEDIANFLOW",TrackerMedianFlow);
  BOILERPLATE_CODE("TLD",TrackerTLD);
  BOILERPLATE_CODE("KCF",TrackerKCF); // add this line!
  return Ptr<Tracker>();
}


/*---------------STEP 3---------------------*/
/* make a new file and paste the snippet below
*  and modify it according to your needs.
*  also make sure to put the LICENSE part.
*  src/trackerKCF.cpp
*/
/*------------------------------------------*/

/*---------------------------
|  TrackerKCFModel
|---------------------------*/
namespace cv{
   /**
  * \brief Implementation of TrackerModel for MIL algorithm
  */
  class TrackerKCFModel : public TrackerModel{
  public:
    TrackerKCFModel(TrackerKCF::Params /*params*/){}
    ~TrackerKCFModel(){}
  protected:
    void modelEstimationImpl( const std::vector<Mat>& responses ){}
    void modelUpdateImpl(){}
  };
} /* namespace cv */


/*---------------------------
|  TrackerKCF
|---------------------------*/
namespace cv{
  
  /*
 * Prototype
 */
  class TrackerKCFImpl : public TrackerKCF{
  public:
    TrackerKCFImpl( const TrackerKCF::Params ¶meters = TrackerKCF::Params() );
    void read( const FileNode& fn );
    void write( FileStorage& fs ) const;
  
  protected:
    bool initImpl( const Mat& image, const Rect2d& boundingBox );
    bool updateImpl( const Mat& image, Rect2d& boundingBox );
    
    TrackerKCF::Params params;
  };
    
  /*
 * Constructor
 */
  Ptr<TrackerKCF> TrackerKCF::createTracker(const TrackerKCF::Params ¶meters){
      return Ptr<TrackerKCFImpl>(new TrackerKCFImpl(parameters));
  }
  TrackerKCFImpl::TrackerKCFImpl( const TrackerKCF::Params ¶meters ) :
      params( parameters )
  {
    isInit = false;
  }
  
  void TrackerKCFImpl::read( const cv::FileNode& fn ){
    params.read( fn );
  }

  void TrackerKCFImpl::write( cv::FileStorage& fs ) const{
    params.write( fs );
  }
  
  
  bool TrackerKCFImpl::initImpl( const Mat& image, const Rect2d& boundingBox ){
    model=Ptr<TrackerKCFModel>(new TrackerKCFModel(params));
    return true;
  }
  bool TrackerKCFImpl::updateImpl( const Mat& image, Rect2d& boundingBox ){return true;}
  
  /*
 * Parameters
 */
  TrackerKCF::Params::Params(){
      
  }

  void TrackerKCF::Params::read( const cv::FileNode& fn ){
    
  }

  void TrackerKCF::Params::write( cv::FileStorage& fs ) const{
    
  }
  
} /* namespace cv */
然後再來看看/modules/tracking/include/opencv2/tracking/tracker.hpp中關於kcf的定義,多說兩句,這裡面定義了很多跟蹤的方法,包括線上跟蹤的MILtracker,OBAtracker,還有,particle filtering tracker,TLD tracker,KCF tracker,他們的基類叫做Tracker,這個Tracker的宣告如下:
class CV_EXPORTS_W Tracker : public virtual Algorithm
{
 public:

  virtual ~Tracker();

  /** @brief Initialize the tracker with a know bounding box that surrounding the target
    @param image The initial frame
    @param boundingBox The initial boundig box

    @return True if initialization went succesfully, false otherwise
     */
  CV_WRAP bool init( const Mat& image, const Rect2d& boundingBox );

  /** @brief Update the tracker, find the new most likely bounding box for the target
    @param image The current frame
    @param boundingBox The boundig 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 bool update( const Mat& image, CV_OUT Rect2d& boundingBox );

  /** @brief Creates a tracker by its name.
    @param trackerType Tracker type

    The following detector types are supported:

    -   "MIL" -- TrackerMIL
    -   "BOOSTING" -- TrackerBoosting
     */
  CV_WRAP static Ptr<Tracker> create( const String& trackerType );

  virtual void read( const FileNode& fn )=0;
  virtual void write( FileStorage& fs ) const=0;

  Ptr<TrackerModel> getModel()
  {
	  return model;
  }

 protected:

  virtual bool initImpl( const Mat& image, const Rect2d& boundingBox ) = 0;
  virtual bool updateImpl( const Mat& image, Rect2d& boundingBox ) = 0;

  bool isInit;

  Ptr<TrackerFeatureSet> featureSet;
  Ptr<TrackerSampler> sampler;
  Ptr<TrackerModel> model;
};

下面看一下繼承了Tracker這個KCF tracker,這個演算法的論文連結在上一篇部落格裡
/** @brief KCF is a novel tracking framework that utilizes properties of circulant matrix to enhance the processing speed.
 * This tracking method is an implementation of @cite KCF_ECCV which is extended to KFC with color-names features (@cite KCF_CN).
 * The original paper of KCF is available at <http://home.isr.uc.pt/~henriques/circulant/index.html>
 * as well as the matlab implementation. For more information about KCF with color-names features, please refer to
 * <http://www.cvl.isy.liu.se/research/objrec/visualtracking/colvistrack/index.html>.
 */
class CV_EXPORTS TrackerKCF : public Tracker
{
public:
	/**
	* \brief Feature type to be used in the tracking grayscale, colornames, compressed color-names
	* The modes available now:
	-   "GRAY" -- Use grayscale values as the feature
	-   "CN" -- Color-names feature
	*/
	enum MODE {
		GRAY = (1u << 0),
		CN = (1u << 1),
		CUSTOM = (1u << 2)
	};

	struct CV_EXPORTS Params
	{
		/**
		* \brief Constructor
		*/
		Params();

		/**
		* \brief Read parameters from file, currently unused
		*/
		void read(const FileNode& /*fn*/);

		/**
		* \brief Read parameters from file, currently unused
		*/
		void write(FileStorage& /*fs*/) const;

		double sigma;                 //!<  gaussian kernel bandwidth
		double lambda;                //!<  regularization
		double interp_factor;         //!<  linear interpolation factor for adaptation
		double output_sigma_factor;   //!<  spatial bandwidth (proportional to target)
		double pca_learning_rate;     //!<  compression learning rate
		bool resize;                  //!<  activate the resize feature to improve the processing speed
		bool split_coeff;             //!<  split the training coefficients into two matrices
		bool wrap_kernel;             //!<  wrap around the kernel values
		bool compress_feature;        //!<  activate the pca method to compress the features
		int max_patch_size;           //!<  threshold for the ROI size
		int compressed_size;          //!<  feature size after compression
		unsigned int desc_pca;        //!<  compressed descriptors of TrackerKCF::MODE
		unsigned int desc_npca;       //!<  non-compressed descriptors of TrackerKCF::MODE
	};

	virtual void setFeatureExtractor(void(*)(const Mat, const Rect, Mat&), bool pca_func = false);

	/** @brief Constructor
	@param parameters KCF parameters TrackerKCF::Params
	*/
	BOILERPLATE_CODE("KCF", TrackerKCF);
};

好,上面這些只是介紹了在opencv中 KCF的介面,下面舉一個例子來看看怎麼呼叫
//安裝配置好opencv3.1
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>

using namespace std;
using namespace cv;

int main( ){
  // declares all required variables
  //! [vars]
  Rect2d roi;
  Mat frame;
  //! [vars]

  // create a tracker object
  //! create這個函式的引數也可以是-   "MIL" -- TrackerMIL
   //! -   "BOOSTING" -- TrackerBoosting ,還可以是 "TLD","MEDIANFLOW"
  Ptr<Tracker> tracker = Tracker::create( "KCF" );
  //! [create]

  // set input video
  //! [setvideo]
  std::string video = "test.avi";
  VideoCapture cap(video);
  //! [setvideo]

  // get bounding box
  //! [getframe]
  cap >> frame;
  //! [getframe]
  //! [selectroi]選擇目標roi以GUI的形式
  roi=selectROI("tracker",frame);
  //! [selectroi]

  //quit if ROI was not selected
  if(roi.width==0 || roi.height==0)
    return 0;

  // initialize the tracker
  //! [init]
  tracker->init(frame,roi);
  //! [init]

  // perform the tracking process
  printf("Start the tracking process\n");
  for ( ;; ){
    // get frame from the video
    cap >> frame;

    // stop the program if no more images
    if(frame.rows==0 || frame.cols==0)
      break;

    // update the tracking result
    //! [update]
    tracker->update(frame,roi);
    //! [update]

    //! [visualization]
    // draw the tracked object
    rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );

    // show image with the tracked object
    imshow("tracker",frame);
    //! [visualization]
    //quit on ESC button
    if(waitKey(1)==27)
  break;
  }

  return 0;
}