Commit 660174e8 authored by Kurnianggoro's avatar Kurnianggoro

Remove whitespaces

parent 261086b1
...@@ -83,13 +83,13 @@ ...@@ -83,13 +83,13 @@
year = {2012}, year = {2012},
} }
@INPROCEEDINGS{KCF_CN, @INPROCEEDINGS{KCF_CN,
author={Danelljan, M. and Khan, F.S. and Felsberg, M. and van de Weijer, J.}, author={Danelljan, M. and Khan, F.S. and Felsberg, M. and van de Weijer, J.},
booktitle={Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Conference on}, booktitle={Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Conference on},
title={Adaptive Color Attributes for Real-Time Visual Tracking}, title={Adaptive Color Attributes for Real-Time Visual Tracking},
year={2014}, year={2014},
month={June}, month={June},
pages={1090-1097}, pages={1090-1097},
keywords={computer vision;feature extraction;image colour analysis;image representation;image sequences;adaptive color attributes;benchmark color sequences;color features;color representations;computer vision;image description;real-time visual tracking;tracking-by-detection framework;Color;Computational modeling;Covariance matrices;Image color analysis;Kernel;Target tracking;Visualization;Adaptive Dimensionality Reduction;Appearance Model;Color Features;Visual Tracking}, keywords={computer vision;feature extraction;image colour analysis;image representation;image sequences;adaptive color attributes;benchmark color sequences;color features;color representations;computer vision;image description;real-time visual tracking;tracking-by-detection framework;Color;Computational modeling;Covariance matrices;Image color analysis;Kernel;Target tracking;Visualization;Adaptive Dimensionality Reduction;Appearance Model;Color Features;Visual Tracking},
doi={10.1109/CVPR.2014.143}, doi={10.1109/CVPR.2014.143},
} }
...@@ -1191,8 +1191,8 @@ class CV_EXPORTS_W TrackerTLD : public Tracker ...@@ -1191,8 +1191,8 @@ class CV_EXPORTS_W TrackerTLD : public Tracker
/** @brief KCF is a novel tracking framework that utilizes properties of circulant matrix to enhance the processing speed. /** @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). * 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> * 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 * 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>. * <http://www.cvl.isy.liu.se/research/objrec/visualtracking/colvistrack/index.html>.
*/ */
class CV_EXPORTS_W TrackerKCF : public Tracker class CV_EXPORTS_W TrackerKCF : public Tracker
...@@ -1202,21 +1202,21 @@ class CV_EXPORTS_W TrackerKCF : public Tracker ...@@ -1202,21 +1202,21 @@ class CV_EXPORTS_W TrackerKCF : public Tracker
struct CV_EXPORTS Params struct CV_EXPORTS Params
{ {
Params(); Params();
/** /**
* \brief Read parameters from file, currently unused * \brief Read parameters from file, currently unused
*/ */
void read( const FileNode& /*fn*/ ); void read( const FileNode& /*fn*/ );
/** /**
* \brief Read parameters from file, currently unused * \brief Read parameters from file, currently unused
*/ */
void write( FileStorage& /*fs*/ ) const; void write( FileStorage& /*fs*/ ) const;
double sigma; //!< gaussian kernel bandwidth double sigma; //!< gaussian kernel bandwidth
double lambda; //!< regularization double lambda; //!< regularization
double interp_factor; //!< linear interpolation factor for adaptation double interp_factor; //!< linear interpolation factor for adaptation
double output_sigma_factor; //!< spatial bandwidth (proportional to target) double output_sigma_factor; //!< spatial bandwidth (proportional to target)
double pca_learning_rate; //!< compression learning rate double pca_learning_rate; //!< compression learning rate
bool resize; //!< activate the resize feature to improve the processing speed bool resize; //!< activate the resize feature to improve the processing speed
bool splitCoeff; //!< split the training coefficients into two matrices bool splitCoeff; //!< split the training coefficients into two matrices
......
...@@ -65,7 +65,7 @@ namespace cv{ ...@@ -65,7 +65,7 @@ namespace cv{
| TrackerKCF | TrackerKCF
|---------------------------*/ |---------------------------*/
namespace cv{ namespace cv{
/* /*
* Prototype * Prototype
*/ */
...@@ -74,23 +74,23 @@ namespace cv{ ...@@ -74,23 +74,23 @@ namespace cv{
TrackerKCFImpl( const TrackerKCF::Params &parameters = TrackerKCF::Params() ); TrackerKCFImpl( const TrackerKCF::Params &parameters = TrackerKCF::Params() );
void read( const FileNode& /*fn*/ ); void read( const FileNode& /*fn*/ );
void write( FileStorage& /*fs*/ ) const; void write( FileStorage& /*fs*/ ) const;
protected: protected:
/* /*
* basic functions and vars * basic functions and vars
*/ */
bool initImpl( const Mat& /*image*/, const Rect2d& boundingBox ); bool initImpl( const Mat& /*image*/, const Rect2d& boundingBox );
bool updateImpl( const Mat& image, Rect2d& boundingBox ); bool updateImpl( const Mat& image, Rect2d& boundingBox );
TrackerKCF::Params params; TrackerKCF::Params params;
/* /*
* KCF functions and vars * KCF functions and vars
*/ */
void createHanningWindow(OutputArray _dst, const cv::Size winSize, const int type) const; void createHanningWindow(OutputArray _dst, const cv::Size winSize, const int type) const;
void inline fft2(const Mat src, std::vector<Mat> & dest) const; void inline fft2(const Mat src, std::vector<Mat> & dest) const;
void inline fft2(const Mat src, Mat & dest) const; void inline fft2(const Mat src, Mat & dest) const;
void inline ifft2(const Mat src, Mat & dest) const ; void inline ifft2(const Mat src, Mat & dest) const;
void inline pixelWiseMult(const std::vector<Mat> src1, const std::vector<Mat> src2, std::vector<Mat> & dest, const int flags, const bool conjB=false) const; void inline pixelWiseMult(const std::vector<Mat> src1, const std::vector<Mat> src2, std::vector<Mat> & dest, const int flags, const bool conjB=false) const;
void inline sumChannels(std::vector<Mat> src, Mat & dest) const; void inline sumChannels(std::vector<Mat> src, Mat & dest) const;
void inline updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & _proj_mtx,double pca_rate, int compressed_sz) const; void inline updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & _proj_mtx,double pca_rate, int compressed_sz) const;
...@@ -100,16 +100,16 @@ namespace cv{ ...@@ -100,16 +100,16 @@ namespace cv{
void denseGaussKernel(const double sigma, const Mat _x, const Mat _y, Mat & _k) const; void denseGaussKernel(const double sigma, const Mat _x, const Mat _y, Mat & _k) const;
void calcResponse(const Mat _alphaf, const Mat _k, Mat & _response) const; void calcResponse(const Mat _alphaf, const Mat _k, Mat & _response) const;
void calcResponse(const Mat _alphaf, const Mat _alphaf_den, const Mat _k, Mat & _response) const; void calcResponse(const Mat _alphaf, const Mat _alphaf_den, const Mat _k, Mat & _response) const;
void shiftRows(Mat& mat) const; void shiftRows(Mat& mat) const;
void shiftRows(Mat& mat, int n) const; void shiftRows(Mat& mat, int n) const;
void shiftCols(Mat& mat, int n) const; void shiftCols(Mat& mat, int n) const;
private: private:
double output_sigma; double output_sigma;
Rect2d roi; Rect2d roi;
Mat hann; //hann window filter Mat hann; //hann window filter
Mat y,yf; // training response and its FFT Mat y,yf; // training response and its FFT
Mat x,xf; // observation and its FFT Mat x,xf; // observation and its FFT
Mat k,kf; // dense gaussian kernel and its FFT Mat k,kf; // dense gaussian kernel and its FFT
...@@ -119,12 +119,12 @@ namespace cv{ ...@@ -119,12 +119,12 @@ namespace cv{
Mat z, new_z; // model Mat z, new_z; // model
Mat response; // detection result Mat response; // detection result
Mat old_cov_mtx, proj_mtx; // for feature compression Mat old_cov_mtx, proj_mtx; // for feature compression
bool resizeImage; // resize the image whenever needed and the patch size is large bool resizeImage; // resize the image whenever needed and the patch size is large
int frame; int frame;
}; };
/* /*
* Constructor * Constructor
*/ */
...@@ -136,10 +136,10 @@ namespace cv{ ...@@ -136,10 +136,10 @@ namespace cv{
{ {
isInit = false; isInit = false;
resizeImage = false; resizeImage = false;
CV_Assert(params.descriptor == GRAY || params.descriptor == CN /*|| params.descriptor == CN2*/); CV_Assert(params.descriptor == GRAY || params.descriptor == CN /*|| params.descriptor == CN2*/);
} }
void TrackerKCFImpl::read( const cv::FileNode& fn ){ void TrackerKCFImpl::read( const cv::FileNode& fn ){
params.read( fn ); params.read( fn );
} }
...@@ -147,9 +147,9 @@ namespace cv{ ...@@ -147,9 +147,9 @@ namespace cv{
void TrackerKCFImpl::write( cv::FileStorage& fs ) const { void TrackerKCFImpl::write( cv::FileStorage& fs ) const {
params.write( fs ); params.write( fs );
} }
/* /*
* Initialization: * Initialization:
* - creating hann window filter * - creating hann window filter
* - ROI padding * - ROI padding
* - creating a gaussian response for the training ground-truth * - creating a gaussian response for the training ground-truth
...@@ -158,11 +158,11 @@ namespace cv{ ...@@ -158,11 +158,11 @@ namespace cv{
bool TrackerKCFImpl::initImpl( const Mat& /*image*/, const Rect2d& boundingBox ){ bool TrackerKCFImpl::initImpl( const Mat& /*image*/, const Rect2d& boundingBox ){
frame=0; frame=0;
roi = boundingBox; roi = boundingBox;
//calclulate output sigma //calclulate output sigma
output_sigma=sqrt(roi.width*roi.height)*params.output_sigma_factor; output_sigma=sqrt(roi.width*roi.height)*params.output_sigma_factor;
output_sigma=-0.5/(output_sigma*output_sigma); output_sigma=-0.5/(output_sigma*output_sigma);
//resize the ROI whenever needed //resize the ROI whenever needed
if(params.resize && roi.width*roi.height>params.max_patch_size){ if(params.resize && roi.width*roi.height>params.max_patch_size){
resizeImage=true; resizeImage=true;
...@@ -170,21 +170,21 @@ namespace cv{ ...@@ -170,21 +170,21 @@ namespace cv{
roi.y/=2.0; roi.y/=2.0;
roi.width/=2.0; roi.width/=2.0;
roi.height/=2.0; roi.height/=2.0;
} }
// add padding to the roi // add padding to the roi
roi.x-=roi.width/2; roi.x-=roi.width/2;
roi.y-=roi.height/2; roi.y-=roi.height/2;
roi.width*=2; roi.width*=2;
roi.height*=2; roi.height*=2;
// initialize the hann window filter // initialize the hann window filter
createHanningWindow(hann, roi.size(), CV_64F); createHanningWindow(hann, roi.size(), CV_64F);
if(params.descriptor==CN){ if(params.descriptor==CN){
Mat layers[] = {hann, hann, hann, hann, hann, hann, hann, hann, hann, hann}; Mat layers[] = {hann, hann, hann, hann, hann, hann, hann, hann, hann, hann};
merge(layers, 10, hann); merge(layers, 10, hann);
} }
// create gaussian response // create gaussian response
y=Mat::zeros((int)roi.height,(int)roi.width,CV_64F); y=Mat::zeros((int)roi.height,(int)roi.width,CV_64F);
for(unsigned i=0;i<roi.height;i++){ for(unsigned i=0;i<roi.height;i++){
...@@ -192,19 +192,19 @@ namespace cv{ ...@@ -192,19 +192,19 @@ namespace cv{
y.at<double>(i,j)=(i-roi.height/2+1)*(i-roi.height/2+1)+(j-roi.width/2+1)*(j-roi.width/2+1); y.at<double>(i,j)=(i-roi.height/2+1)*(i-roi.height/2+1)+(j-roi.width/2+1)*(j-roi.width/2+1);
} }
} }
y*=(double)output_sigma; y*=(double)output_sigma;
cv::exp(y,y); cv::exp(y,y);
// perform fourier transfor to the gaussian response // perform fourier transfor to the gaussian response
fft2(y,yf); fft2(y,yf);
model=Ptr<TrackerKCFModel>(new TrackerKCFModel(params)); model=Ptr<TrackerKCFModel>(new TrackerKCFModel(params));
// TODO: return true only if roi inside the image // TODO: return true only if roi inside the image
return true; return true;
} }
/* /*
* Main part of the KCF algorithm * Main part of the KCF algorithm
*/ */
...@@ -212,17 +212,17 @@ namespace cv{ ...@@ -212,17 +212,17 @@ namespace cv{
double minVal, maxVal; // min-max response double minVal, maxVal; // min-max response
Point minLoc,maxLoc; // min-max location Point minLoc,maxLoc; // min-max location
Mat zc; Mat zc;
Mat img=image.clone(); Mat img=image.clone();
// check the channels of the input image, grayscale is preferred // check the channels of the input image, grayscale is preferred
CV_Assert(image.channels() == 1 || image.channels() == 3); CV_Assert(image.channels() == 1 || image.channels() == 3);
// resize the image whenever needed // resize the image whenever needed
if(resizeImage)resize(img,img,Size(img.cols/2,img.rows/2)); if(resizeImage)resize(img,img,Size(img.cols/2,img.rows/2));
// extract and pre-process the patch // extract and pre-process the patch
if(!getSubWindow(img,roi, x))return false; if(!getSubWindow(img,roi, x))return false;
// detection part // detection part
if(frame>0){ if(frame>0){
//compute the gaussian kernel //compute the gaussian kernel
...@@ -232,52 +232,52 @@ namespace cv{ ...@@ -232,52 +232,52 @@ namespace cv{
denseGaussKernel(params.sigma,x,zc,k); denseGaussKernel(params.sigma,x,zc,k);
}else }else
denseGaussKernel(params.sigma,x,z,k); denseGaussKernel(params.sigma,x,z,k);
// calculate filter response // calculate filter response
if(params.splitCoeff) if(params.splitCoeff)
calcResponse(alphaf,alphaf_den,k,response); calcResponse(alphaf,alphaf_den,k,response);
else else
calcResponse(alphaf,k,response); calcResponse(alphaf,k,response);
// extract the maximum response // extract the maximum response
minMaxLoc( response, &minVal, &maxVal, &minLoc, &maxLoc ); minMaxLoc( response, &minVal, &maxVal, &minLoc, &maxLoc );
roi.x+=(maxLoc.x-roi.width/2+1); roi.x+=(maxLoc.x-roi.width/2+1);
roi.y+=(maxLoc.y-roi.height/2+1); roi.y+=(maxLoc.y-roi.height/2+1);
// update the bounding box // update the bounding box
boundingBox.x=(resizeImage?roi.x*2:roi.x)+boundingBox.width/2; boundingBox.x=(resizeImage?roi.x*2:roi.x)+boundingBox.width/2;
boundingBox.y=(resizeImage?roi.y*2:roi.y)+boundingBox.height/2; boundingBox.y=(resizeImage?roi.y*2:roi.y)+boundingBox.height/2;
} }
// extract the patch for learning purpose // extract the patch for learning purpose
if(!getSubWindow(img,roi, x))return false; if(!getSubWindow(img,roi, x))return false;
//update the training data //update the training data
new_z=x.clone(); new_z=x.clone();
if(frame==0) if(frame==0)
z=x.clone(); z=x.clone();
else else
z=(1.0-params.interp_factor)*z+params.interp_factor*new_z; z=(1.0-params.interp_factor)*z+params.interp_factor*new_z;
if(params.compressFeature){ if(params.compressFeature){
// feature compression // feature compression
updateProjectionMatrix(z,old_cov_mtx,proj_mtx,params.pca_learning_rate,params.compressed_size); updateProjectionMatrix(z,old_cov_mtx,proj_mtx,params.pca_learning_rate,params.compressed_size);
compress(proj_mtx,x,x); compress(proj_mtx,x,x);
} }
// Kernel Regularized Least-Squares, calculate alphas // Kernel Regularized Least-Squares, calculate alphas
denseGaussKernel(params.sigma,x,x,k); denseGaussKernel(params.sigma,x,x,k);
fft2(k,kf); fft2(k,kf);
kf_lambda=kf+params.lambda; kf_lambda=kf+params.lambda;
/* TODO: optimize this element-wise division /* TODO: optimize this element-wise division
* new_alphaf=yf./kf * new_alphaf=yf./kf
* z=(a+bi)/(c+di)[(ac+bd)+i(bc-ad)]/(c^2+d^2) * z=(a+bi)/(c+di)[(ac+bd)+i(bc-ad)]/(c^2+d^2)
*/ */
new_alphaf=Mat_<Vec2d >(yf.rows, yf.cols); new_alphaf=Mat_<Vec2d >(yf.rows, yf.cols);
std::complex<double> temp; std::complex<double> temp;
if(params.splitCoeff){ if(params.splitCoeff){
mulSpectrums(yf,kf,new_alphaf,0); mulSpectrums(yf,kf,new_alphaf,0);
mulSpectrums(kf,kf_lambda,new_alphaf_den,0); mulSpectrums(kf,kf_lambda,new_alphaf_den,0);
...@@ -290,7 +290,7 @@ namespace cv{ ...@@ -290,7 +290,7 @@ namespace cv{
} }
} }
} }
// update the RLS model // update the RLS model
if(frame==0){ if(frame==0){
alphaf=new_alphaf.clone(); alphaf=new_alphaf.clone();
...@@ -299,17 +299,17 @@ namespace cv{ ...@@ -299,17 +299,17 @@ namespace cv{
alphaf=(1.0-params.interp_factor)*alphaf+params.interp_factor*new_alphaf; alphaf=(1.0-params.interp_factor)*alphaf+params.interp_factor*new_alphaf;
if(params.splitCoeff)alphaf_den=(1.0-params.interp_factor)*alphaf_den+params.interp_factor*new_alphaf_den; if(params.splitCoeff)alphaf_den=(1.0-params.interp_factor)*alphaf_den+params.interp_factor*new_alphaf_den;
} }
frame++; frame++;
return true; return true;
} }
/*------------------------------------- /*-------------------------------------
| implementation of the KCF functions | implementation of the KCF functions
|-------------------------------------*/ |-------------------------------------*/
/* /*
* hann window filter * hann window filter
*/ */
void TrackerKCFImpl::createHanningWindow(OutputArray _dst, const cv::Size winSize, const int type) const { void TrackerKCFImpl::createHanningWindow(OutputArray _dst, const cv::Size winSize, const int type) const {
...@@ -346,30 +346,30 @@ namespace cv{ ...@@ -346,30 +346,30 @@ namespace cv{
// perform batch sqrt for SSE performance gains // perform batch sqrt for SSE performance gains
//cv::sqrt(dst, dst); //matlab do not use the square rooted version //cv::sqrt(dst, dst); //matlab do not use the square rooted version
} }
/* /*
* simplification of fourier transform function in opencv * simplification of fourier transform function in opencv
*/ */
void inline TrackerKCFImpl::fft2(const Mat src, Mat & dest) const { void inline TrackerKCFImpl::fft2(const Mat src, Mat & dest) const {
std::vector<Mat> layers(src.channels()); std::vector<Mat> layers(src.channels());
std::vector<Mat> outputs(src.channels()); std::vector<Mat> outputs(src.channels());
split(src, layers); split(src, layers);
for(int i=0;i<src.channels();i++){ for(int i=0;i<src.channels();i++){
dft(layers[i],outputs[i],DFT_COMPLEX_OUTPUT); dft(layers[i],outputs[i],DFT_COMPLEX_OUTPUT);
} }
merge(outputs,dest); merge(outputs,dest);
} }
void inline TrackerKCFImpl::fft2(const Mat src, std::vector<Mat> & dest) const { void inline TrackerKCFImpl::fft2(const Mat src, std::vector<Mat> & dest) const {
std::vector<Mat> layers(src.channels()); std::vector<Mat> layers(src.channels());
dest.clear(); dest.clear();
dest.resize(src.channels()); dest.resize(src.channels());
split(src, layers); split(src, layers);
for(int i=0;i<src.channels();i++){ for(int i=0;i<src.channels();i++){
dft(layers[i],dest[i],DFT_COMPLEX_OUTPUT); dft(layers[i],dest[i],DFT_COMPLEX_OUTPUT);
} }
...@@ -381,19 +381,19 @@ namespace cv{ ...@@ -381,19 +381,19 @@ namespace cv{
void inline TrackerKCFImpl::ifft2(const Mat src, Mat & dest) const { void inline TrackerKCFImpl::ifft2(const Mat src, Mat & dest) const {
idft(src,dest,DFT_SCALE+DFT_REAL_OUTPUT); idft(src,dest,DFT_SCALE+DFT_REAL_OUTPUT);
} }
/* /*
* Point-wise multiplication of two Multichannel Mat data * Point-wise multiplication of two Multichannel Mat data
*/ */
void inline TrackerKCFImpl::pixelWiseMult(const std::vector<Mat> src1, const std::vector<Mat> src2, std::vector<Mat> & dest, const int flags, const bool conjB) const { void inline TrackerKCFImpl::pixelWiseMult(const std::vector<Mat> src1, const std::vector<Mat> src2, std::vector<Mat> & dest, const int flags, const bool conjB) const {
dest.clear(); dest.clear();
dest.resize(src1.size()); dest.resize(src1.size());
for(unsigned i=0;i<src1.size();i++){ for(unsigned i=0;i<src1.size();i++){
mulSpectrums(src1[i], src2[i], dest[i],flags,conjB); mulSpectrums(src1[i], src2[i], dest[i],flags,conjB);
} }
} }
/* /*
* Combines all channels in a multi-channels Mat data into a single channel * Combines all channels in a multi-channels Mat data into a single channel
*/ */
...@@ -403,18 +403,18 @@ namespace cv{ ...@@ -403,18 +403,18 @@ namespace cv{
dest+=src[i]; dest+=src[i];
} }
} }
/* /*
* obtains the projection matrix using PCA * obtains the projection matrix using PCA
*/ */
void inline TrackerKCFImpl::updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & _proj_mtx, double pca_rate, int compressed_sz) const { void inline TrackerKCFImpl::updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & _proj_mtx, double pca_rate, int compressed_sz) const {
CV_Assert(compressed_sz<=src.channels()); CV_Assert(compressed_sz<=src.channels());
// compute average // compute average
std::vector<Mat> layers(src.channels()); std::vector<Mat> layers(src.channels());
std::vector<Scalar> average(src.channels()); std::vector<Scalar> average(src.channels());
split(src,layers); split(src,layers);
for (int i=0;i<src.channels();i++){ for (int i=0;i<src.channels();i++){
average[i]=mean(layers[i]); average[i]=mean(layers[i]);
layers[i]-=average[i]; layers[i]-=average[i];
...@@ -424,25 +424,25 @@ namespace cv{ ...@@ -424,25 +424,25 @@ namespace cv{
Mat data,new_cov; Mat data,new_cov;
merge(layers,data); merge(layers,data);
data=data.reshape(1,src.rows*src.cols); data=data.reshape(1,src.rows*src.cols);
new_cov=1.0/(double)(src.rows*src.cols-1)*(data.t()*data); new_cov=1.0/(double)(src.rows*src.cols-1)*(data.t()*data);
if(old_cov.rows==0)old_cov=new_cov.clone(); if(old_cov.rows==0)old_cov=new_cov.clone();
// calc PCA // calc PCA
Mat w, u, vt; Mat w, u, vt;
SVD::compute((1.0-pca_rate)*old_cov+pca_rate*new_cov, w, u, vt); SVD::compute((1.0-pca_rate)*old_cov+pca_rate*new_cov, w, u, vt);
// extract the projection matrix // extract the projection matrix
_proj_mtx=u(Rect(0,0,compressed_sz,src.channels())).clone(); _proj_mtx=u(Rect(0,0,compressed_sz,src.channels())).clone();
Mat proj_vars=Mat::eye(compressed_sz,compressed_sz,_proj_mtx.type()); Mat proj_vars=Mat::eye(compressed_sz,compressed_sz,_proj_mtx.type());
for(int i=0;i<compressed_sz;i++){ for(int i=0;i<compressed_sz;i++){
proj_vars.at<double>(i,i)=w.at<double>(i); proj_vars.at<double>(i,i)=w.at<double>(i);
} }
// update the covariance matrix // update the covariance matrix
old_cov=(1.0-pca_rate)*old_cov+pca_rate*_proj_mtx*proj_vars*_proj_mtx.t(); old_cov=(1.0-pca_rate)*old_cov+pca_rate*_proj_mtx*proj_vars*_proj_mtx.t();
} }
/* /*
* compress the features * compress the features
*/ */
...@@ -451,22 +451,22 @@ namespace cv{ ...@@ -451,22 +451,22 @@ namespace cv{
Mat compressed=data*_proj_mtx; Mat compressed=data*_proj_mtx;
dest=compressed.reshape(_proj_mtx.cols,src.rows).clone(); dest=compressed.reshape(_proj_mtx.cols,src.rows).clone();
} }
/* /*
* obtain the patch and apply hann window filter to it * obtain the patch and apply hann window filter to it
*/ */
bool TrackerKCFImpl::getSubWindow(const Mat img, const Rect _roi, Mat& patch) const { bool TrackerKCFImpl::getSubWindow(const Mat img, const Rect _roi, Mat& patch) const {
Rect region=_roi; Rect region=_roi;
// return false if roi is outside the image // return false if roi is outside the image
if((_roi.x+_roi.width<0) if((_roi.x+_roi.width<0)
||(_roi.y+_roi.height<0) ||(_roi.y+_roi.height<0)
||(_roi.x>=img.cols) ||(_roi.x>=img.cols)
||(_roi.y>=img.rows) ||(_roi.y>=img.rows)
)return false; )return false;
// extract patch inside the image // extract patch inside the image
if(_roi.x<0){region.x=0;region.width+=_roi.x;} if(_roi.x<0){region.x=0;region.width+=_roi.x;}
if(_roi.y<0){region.y=0;region.height+=_roi.y;} if(_roi.y<0){region.y=0;region.height+=_roi.y;}
if(_roi.x+_roi.width>img.cols)region.width=img.cols-_roi.x; if(_roi.x+_roi.width>img.cols)region.width=img.cols-_roi.x;
...@@ -475,7 +475,7 @@ namespace cv{ ...@@ -475,7 +475,7 @@ namespace cv{
if(region.height>img.rows)region.height=img.rows; if(region.height>img.rows)region.height=img.rows;
patch=img(region).clone(); patch=img(region).clone();
// add some padding to compensate when the patch is outside image border // add some padding to compensate when the patch is outside image border
int addTop,addBottom, addLeft, addRight; int addTop,addBottom, addLeft, addRight;
addTop=region.y-_roi.y; addTop=region.y-_roi.y;
...@@ -485,7 +485,7 @@ namespace cv{ ...@@ -485,7 +485,7 @@ namespace cv{
copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE); copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
if(patch.rows==0 || patch.cols==0)return false; if(patch.rows==0 || patch.cols==0)return false;
// extract the desired descriptors // extract the desired descriptors
switch(params.descriptor){ switch(params.descriptor){
case GRAY: case GRAY:
...@@ -501,21 +501,21 @@ namespace cv{ ...@@ -501,21 +501,21 @@ namespace cv{
if(patch.channels()>1)cvtColor(patch,patch, CV_BGR2GRAY); if(patch.channels()>1)cvtColor(patch,patch, CV_BGR2GRAY);
break; break;
} }
patch=patch.mul(hann); // hann window filter patch=patch.mul(hann); // hann window filter
return true; return true;
} }
/* Convert BGR to ColorNames /* Convert BGR to ColorNames
*/ */
void TrackerKCFImpl::extractCN(Mat _patch, Mat & cnFeatures) const { void TrackerKCFImpl::extractCN(Mat _patch, Mat & cnFeatures) const {
Vec3b & pixel = _patch.at<Vec3b>(0,0); Vec3b & pixel = _patch.at<Vec3b>(0,0);
unsigned index; unsigned index;
Mat temp = Mat::zeros(_patch.rows,_patch.cols,CV_64FC(10)); Mat temp = Mat::zeros(_patch.rows,_patch.cols,CV_64FC(10));
for(int i=0;i<_patch.rows;i++){ for(int i=0;i<_patch.rows;i++){
for(int j=0;j<_patch.cols;j++){ for(int j=0;j<_patch.cols;j++){
pixel=_patch.at<Vec3b>(i,j); pixel=_patch.at<Vec3b>(i,j);
...@@ -527,10 +527,10 @@ namespace cv{ ...@@ -527,10 +527,10 @@ namespace cv{
} }
} }
} }
cnFeatures=temp.clone(); cnFeatures=temp.clone();
} }
/* /*
* dense gauss kernel function * dense gauss kernel function
*/ */
...@@ -538,24 +538,24 @@ namespace cv{ ...@@ -538,24 +538,24 @@ namespace cv{
std::vector<Mat> _xf,_yf,xyf_v; std::vector<Mat> _xf,_yf,xyf_v;
Mat xy,xyf; Mat xy,xyf;
double normX, normY; double normX, normY;
fft2(_x,_xf); fft2(_x,_xf);
fft2(_y,_yf); fft2(_y,_yf);
normX=norm(_x); normX=norm(_x);
normX*=normX; normX*=normX;
normY=norm(_y); normY=norm(_y);
normY*=normY; normY*=normY;
pixelWiseMult(_xf,_yf,xyf_v,0,true); pixelWiseMult(_xf,_yf,xyf_v,0,true);
sumChannels(xyf_v,xyf); sumChannels(xyf_v,xyf);
ifft2(xyf,xyf); ifft2(xyf,xyf);
if(params.wrapKernel){ if(params.wrapKernel){
shiftRows(xyf, _x.rows/2); shiftRows(xyf, _x.rows/2);
shiftCols(xyf, _x.cols/2); shiftCols(xyf, _x.cols/2);
} }
//(xx + yy - 2 * xy) / numel(x) //(xx + yy - 2 * xy) / numel(x)
xy=(normX+normY-2*xyf)/(_x.rows*_x.cols*_x.channels()); xy=(normX+normY-2*xyf)/(_x.rows*_x.cols*_x.channels());
...@@ -566,13 +566,13 @@ namespace cv{ ...@@ -566,13 +566,13 @@ namespace cv{
if(xy.at<double>(i,j)<0.0)xy.at<double>(i,j)=0.0; if(xy.at<double>(i,j)<0.0)xy.at<double>(i,j)=0.0;
} }
} }
double sig=-1.0/(sigma*sigma); double sig=-1.0/(sigma*sigma);
xy=sig*xy; xy=sig*xy;
exp(xy,_k); exp(xy,_k);
} }
/* CIRCULAR SHIFT Function /* CIRCULAR SHIFT Function
* http://stackoverflow.com/questions/10420454/shift-like-matlab-function-rows-or-columns-of-a-matrix-in-opencv * http://stackoverflow.com/questions/10420454/shift-like-matlab-function-rows-or-columns-of-a-matrix-in-opencv
*/ */
...@@ -601,7 +601,7 @@ namespace cv{ ...@@ -601,7 +601,7 @@ namespace cv{
shiftRows(mat); shiftRows(mat);
} }
flip(mat,mat,0); flip(mat,mat,0);
}else{ }else{
for(int _k=0; _k < n;_k++) { for(int _k=0; _k < n;_k++) {
shiftRows(mat); shiftRows(mat);
} }
...@@ -628,14 +628,14 @@ namespace cv{ ...@@ -628,14 +628,14 @@ namespace cv{
* calculate the detection response * calculate the detection response
*/ */
void TrackerKCFImpl::calcResponse(const Mat _alphaf, const Mat _k, Mat & _response) const { void TrackerKCFImpl::calcResponse(const Mat _alphaf, const Mat _k, Mat & _response) const {
//alpha f--> 2channels ; k --> 1 channel; //alpha f--> 2channels ; k --> 1 channel;
Mat _kf; Mat _kf;
fft2(_k,_kf); fft2(_k,_kf);
Mat spec; Mat spec;
mulSpectrums(_alphaf,_kf,spec,0,false); mulSpectrums(_alphaf,_kf,spec,0,false);
ifft2(spec,_response); ifft2(spec,_response);
} }
/* /*
* calculate the detection response for splitted form * calculate the detection response for splitted form
*/ */
...@@ -643,11 +643,11 @@ namespace cv{ ...@@ -643,11 +643,11 @@ namespace cv{
Mat _kf; Mat _kf;
fft2(_k,_kf); fft2(_k,_kf);
Mat spec; Mat spec;
Mat spec2=Mat_<Vec2d >(_k.rows, _k.cols); Mat spec2=Mat_<Vec2d >(_k.rows, _k.cols);
std::complex<double> temp; std::complex<double> temp;
mulSpectrums(_alphaf,_kf,spec,0,false); mulSpectrums(_alphaf,_kf,spec,0,false);
for(int i=0;i<_k.rows;i++){ for(int i=0;i<_k.rows;i++){
for(int j=0;j<_k.cols;j++){ for(int j=0;j<_k.cols;j++){
temp=std::complex<double>(spec.at<Vec2d>(i,j)[0],spec.at<Vec2d>(i,j)[1])/(std::complex<double>(_alphaf_den.at<Vec2d>(i,j)[0],_alphaf_den.at<Vec2d>(i,j)[1])/*+std::complex<double>(0.0000000001,0.0000000001)*/); temp=std::complex<double>(spec.at<Vec2d>(i,j)[0],spec.at<Vec2d>(i,j)[1])/(std::complex<double>(_alphaf_den.at<Vec2d>(i,j)[0],_alphaf_den.at<Vec2d>(i,j)[1])/*+std::complex<double>(0.0000000001,0.0000000001)*/);
...@@ -655,11 +655,11 @@ namespace cv{ ...@@ -655,11 +655,11 @@ namespace cv{
spec2.at<Vec2d >(i,j)[1]=temp.imag(); spec2.at<Vec2d >(i,j)[1]=temp.imag();
} }
} }
ifft2(spec2,_response); ifft2(spec2,_response);
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* /*
* Parameters * Parameters
*/ */
...@@ -673,7 +673,7 @@ namespace cv{ ...@@ -673,7 +673,7 @@ namespace cv{
descriptor=CN; descriptor=CN;
splitCoeff=true; splitCoeff=true;
wrapKernel=false; wrapKernel=false;
//feature compression //feature compression
compressFeature=true; compressFeature=true;
compressed_size=2; compressed_size=2;
...@@ -683,5 +683,5 @@ namespace cv{ ...@@ -683,5 +683,5 @@ namespace cv{
void TrackerKCF::Params::read( const cv::FileNode& /*fn*/ ){} void TrackerKCF::Params::read( const cv::FileNode& /*fn*/ ){}
void TrackerKCF::Params::write( cv::FileStorage& /*fs*/ ) const{} void TrackerKCF::Params::write( cv::FileStorage& /*fs*/ ) const{}
} /* namespace cv */ } /* namespace cv */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment