2014新跟蹤演算法KCF筆記 --續(程式碼部分)
阿新 • • 發佈:2019-02-11
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可)
然後再來看看/modules/tracking/include/opencv2/tracking/tracker.hpp中關於kcf的定義,多說兩句,這裡面定義了很多跟蹤的方法,包括線上跟蹤的MILtracker,OBAtracker,還有,particle filtering tracker,TLD tracker,KCF tracker,他們的基類叫做Tracker,這個Tracker的宣告如下:/*---------------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 */
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;
}