Fast Compressive Tracking(快速压缩跟踪)算法的C++代码实现

来源:互联网 发布:天然子结构知乎 编辑:程序博客网 时间:2024/06/06 02:07

                                      本文系原创,转载请注明。

                               有问题请留言或发邮箱:johnnycons@163.com

           因为实验室项目工程的需要,最近在研究目标跟踪算法。这里提的Fast Compressive Tracking (快速压缩跟踪)算法是张开华教授在其之前的Compressive Tracking 算法(网站看这里)上做了一些简单的优化,本人测试的结果是FCT算法的处理速度在59帧/s左右(windows下),而之前的CT算法大概是29帧/s,修改后的速度还是不错的(这里的工程都是读图片帧序列,后面给出的工程资源有自带资源)。因为FCT的网站上没有给出代码的C++实现(只有MATLAB的代码,网站看这里),这里就贴出我按照其论文的意思给出C++的代码实现,这里的C++代码也是从其CT算法的c++代码上修改而来的,修改的地方我会在代码中说明。另外为了将代码能够移植到linux上,我对代码的初始运行的地方也做了修改,所以这里贴出的代码是可以运行在linux上的。代码中的注释参考了zouxy09大神的博客,最后为了方便大家运行,我会将FCT C++工程以及linux下运行的代码分别打包供大家下载。因为我也是初学者,能力有限,所以若文中有纰漏请读者指正,有问题请留言或者发我邮箱,thanks。

---------------------------------------------------------------------------------------------------

2015/1/24 补充:该版本C++代码没有实现多尺度的情况。我在看论文的时候没有仔细阅读论文(细看了CT,而没细看FCT),以为FCT论文中没有给出尺度变换的设计。后来有网友指出论文中有尺度变换,罪过罪过,很久之前的东西了,所以暂时没办法更新代码。

/************************************************************************* File:CompressiveTracker.h* Brief: C++ demo for paper: Kaihua Zhang, Lei Zhang, Ming-Hsuan Yang,"Real-Time Compressive Tracking," ECCV 2012.* Version: 1.0* Author: Yang Xian* Email: yang_xian521@163.com* Date:2012/08/03* History:* Revised by Kaihua Zhang on 14/8/2012, 23/8/2012* Email: zhkhua@gmail.com* Homepage: http://www4.comp.polyu.edu.hk/~cskhzhang/* Project Website: http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm************************************************************************/#pragma once#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <vector>using std::vector;using namespace cv;//---------------------------------------------------class CompressiveTracker{public:CompressiveTracker(void);~CompressiveTracker(void);private:int featureMinNumRect;int featureMaxNumRect;int featureNum;//每个box的harr特征个数(也就是弱分类器个数)  vector<vector<Rect>> features;vector<vector<float>> featuresWeight;int rOuterPositive;//在离上一帧跟踪到的目标位置的距离小于rOuterPositive的范围内采集 正样本  vector<Rect> samplePositiveBox;//采集的正样本box集  vector<Rect> sampleNegativeBox;//采集的负样本box集  int rSearchWindow;//扫描窗口的大小,或者说检测box的大小  Mat imageIntegral; //图像的积分图 Mat samplePositiveFeatureValue;//采集的正样本的harr特征值 ???特征值是矩阵??Mat sampleNegativeFeatureValue;//采集的负样本的harr特征值  //对每个样本z(m维向量),它的低维表示是v(n维向量,n远小于m)。假定v中的各元素是独立分布的。      //假定在分类器H(v)中的条件概率p(vi|y=1)和p(vi|y=0)属于高斯分布,并且可以用以下四个参数来描述:      //分别是描述正负样本的高斯分布的均值u和方差sigma  vector<float> muPositive;vector<float> sigmaPositive;vector<float> muNegative;vector<float> sigmaNegative;float learnRate;//学习速率,控制分类器参数更新的步长 vector<Rect> detectBox; //需要检测的box Mat detectFeatureValue;RNG rng; //随机数 private:void HaarFeature(Rect& _objectBox, int _numFeature);void sampleRect(Mat& _image, Rect& _objectBox, float _rInner, float _rOuter, int _maxSampleNum, vector<Rect>& _sampleBox);
<span style="font-family: Arial, Helvetica, sans-serif;">//这里sampleRect函数和CT算法稍微不同,增加了step参数用来表示不同的步长。</span>
void sampleRect(Mat& _image, Rect& _objectBox, float _srw, vector<Rect>& _sampleBox,int step);void getFeatureValue(Mat& _imageIntegral, vector<Rect>& _sampleBox, Mat& _sampleFeatureValue);void classifierUpdate(Mat& _sampleFeatureValue, vector<float>& _mu, vector<float>& _sigma, float _learnRate);void radioClassifier(vector<float>& _muPos, vector<float>& _sigmaPos, vector<float>& _muNeg, vector<float>& _sigmaNeg,Mat& _sampleFeatureValue, float& _radioMax, int& _radioMaxIndex);public:void processFrame(Mat& _frame, Rect& _objectBox);void init(Mat& _frame, Rect& _objectBox);};
/************************************************************************* File:RunTracker.cpp* Brief: C++ demo for paper: Kaihua Zhang, Lei Zhang, Ming-Hsuan Yang,"Real-Time Compressive Tracking," ECCV 2012.* Version: 1.0* Author: Yang Xian* Email: yang_xian521@163.com* Date:2012/08/03* History:* Revised by Kaihua Zhang on 14/8/2012, 23/8/2012* Email: zhkhua@gmail.com* Homepage: http://www4.comp.polyu.edu.hk/~cskhzhang/* Project Website: http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm************************************************************************/#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <iostream>#include <fstream>#include <sstream>#include <stdio.h>#include <string.h>//#include <Windows.h>#include <time.h>#include "FastCompressiveTracker.h"using namespace cv;using namespace std;void readConfig(char* configFileName, char* imgFilePath, Rect &box,int &num);/*  Description: read the tracking information from file "config.txt"    Arguments:-configFileName: config file name-ImgFilePath:    Path of the storing image sequences-box:            [x y width height] intial tracking positionHistory: Created by Kaihua Zhang on 15/8/2012*/void readImageSequenceFiles(char* ImgFilePath,vector <string> &imgNames,int &num);/*  Description: search the image names in the image sequences     Arguments:-ImgFilePath: path of the image sequence-imgNames:  vector that stores image nameHistory: Created by Kaihua Zhang on 15/8/2012*/int main(int argc, char * argv[]){time_t start,stop;start = time(NULL);//获取程序开始运行的时间char imgFilePath[100];    char  conf[100];strcpy(conf,"./config.txt");//char tmpDirPath[MAX_PATH+1];//MAX_PATH在windows下是260char tmpDirPath[261];//this is a test for chengxin Rect box; // [x y width height] tracking positionint num;vector <string> imgNames;    readConfig(conf,imgFilePath,box,num);//读取视频帧的配置信息readImageSequenceFiles(imgFilePath,imgNames,num);//将每一帧的名称放入数组imgNames// CT frameworkCompressiveTracker ct;Mat frame;Mat grayImg;sprintf(tmpDirPath, "%s/", imgFilePath);imgNames[0].insert(0,tmpDirPath);cout<<imgNames[0]<<endl;frame = imread(imgNames[0]);//读取第一帧图片    cvtColor(frame, grayImg, CV_RGB2GRAY);    //转换成灰度图ct.init(grayImg, box);    //通过第一帧初始化分类器等参数    //imshow("CT", frame);//just for test 2014/12/14//waitKey(330);char strFrame[20];    FILE* resultStream;resultStream = fopen("TrackingResults.txt", "w");fprintf (resultStream,"%i %i %i %i\n",(int)box.x,(int)box.y,(int)box.width,(int)box.height);for(int i = 1; i < imgNames.size()-1; i ++)//处理之后的每一帧图片{sprintf(tmpDirPath, "%s/", imgFilePath);        imgNames[i].insert(0,tmpDirPath);        frame = imread(imgNames[i]);// get framecvtColor(frame, grayImg, CV_RGB2GRAY);ct.processFrame(grayImg, box);// Process frame//处理图片帧rectangle(frame, box, Scalar(200,0,0),2);// Draw rectangle//矩形绘制fprintf (resultStream,"%i %i %i %i\n",(int)box.x,(int)box.y,(int)box.width,(int)box.height);sprintf(strFrame, "#%d ",i) ;putText(frame,strFrame,cvPoint(0,20),2,1,CV_RGB(25,200,25));imshow("CT", frame);// DisplaywaitKey(1);}stop =time(NULL);//获取程序结束运行的时间int FPS = imgNames.size()/(stop-start);cout<< "The FPS of CT is : "<<FPS<<endl;cout<<endl;fclose(resultStream);return 0;}void readConfig(char* configFileName, char* imgFilePath, Rect &box,int &num){int x;int y;int w;int h;int nums;fstream f;char cstring[1000];int readS=0;f.open(configFileName, fstream::in);char param1[200]; strcpy(param1,"");char param2[200]; strcpy(param2,"");char param3[200]; strcpy(param3,"");//初始化为空串f.getline(cstring, sizeof(cstring));readS=sscanf (cstring, "%s %s %s", param1,param2, param3);strcpy(imgFilePath,param3);f.getline(cstring, sizeof(cstring)); f.getline(cstring, sizeof(cstring)); f.getline(cstring, sizeof(cstring));readS=sscanf (cstring, "%s %s %i %i %i %i %i", param1,param2, &x, &y, &w, &h,&nums);box = Rect(x, y, w, h);num = nums;}void readImageSequenceFiles(char* imgFilePath,vector <string> &imgNames,int &num){imgNames.clear();/*char tmpDirSpec[MAX_PATH+1];sprintf (tmpDirSpec, "%s/*", imgFilePath);WIN32_FIND_DATA f;HANDLE h = FindFirstFile(tmpDirSpec , &f);if(h != INVALID_HANDLE_VALUE){FindNextFile(h, &f);//read ..FindNextFile(h, &f);//read .do{imgNames.push_back(f.cFileName);} while(FindNextFile(h, &f));}FindClose(h);*/String sequencesName = "%05d.jpg";for(int i=1;i<=num;i++){char imgName[256];sprintf(imgName,sequencesName.c_str(),i);String name = imgName;imgNames.push_back(name);//cout<<"the name of this frame is "<<name<<endl;}}
#include "FastCompressiveTracker.h"#include <math.h>#include <iostream>using namespace cv;using namespace std;//------------------------------------------------CompressiveTracker::CompressiveTracker(void){featureMinNumRect = 2;featureMaxNumRect = 4;// number of rectangle from 2 to 4featureNum = 50;// number of all weaker classifiers, i.e,feature poolrOuterPositive = 4;// radical scope of positive samples//scope是范围的意思rSearchWindow = 25; // size of search windowmuPositive = vector<float>(featureNum, 0.0f);//50个muNegative = vector<float>(featureNum, 0.0f);//50个sigmaPositive = vector<float>(featureNum, 1.0f);//50个sigmaNegative = vector<float>(featureNum, 1.0f);//50个learnRate = 0.85f;// Learning rate parameter}CompressiveTracker::~CompressiveTracker(void){}/*通过积分图来计算采集到的每一个样本的harr特征,这个特征通过与featuresWeight来相乘  就相当于投影到随机测量矩阵中了,也就是进行稀疏表达了。这里不明白的话,可以看下  论文中的图二,就比较直观了。  还有一点:实际上这里采用的不属于真正的harr特征,我博客中翻译有误。这里计算的是  在box中采样得到的不同矩形框的灰度加权求和(当权重是负数的时候就是灰度差)  当为了表述方便,我下面都用harr特征来描述。  每一个样本有50个harr特征,每一个harr特征是由2到3个随机选择的矩形框来构成的,  对这些矩形框的灰度加权求和作为这一个harr特征的特征值。 */void CompressiveTracker::HaarFeature(Rect& _objectBox, int _numFeature)/*Description: compute Haar features  Arguments:  -_objectBox: [x y width height] object rectangle  -_numFeature: total number of features.The default is 50.每一个样本有50个harr特征,每一个harr特征是由2到3个随机选择的矩形框来构成的,*/{    //_numFeature是一个样本box的harr特征个数,共50个。而上面说到,      //每一个harr特征是由2到3个随机选择的矩形框(vector<Rect>()类型)来构成的。 features = vector<vector<Rect>>(_numFeature, vector<Rect>());//每一个反应特征的矩形框对应于一个权重,实际上就是随机测量矩阵中相应的元素,用它来与对应的特征      //相乘,表示以权重的程度来感知这个特征。换句话说,featuresWeight就是随机测量矩阵。featuresWeight = vector<vector<float>>(_numFeature, vector<float>());int numRect;Rect rectTemp;float weightTemp;      for (int i=0; i<_numFeature; i++)//_numFeature是50{    //numRect是 2或者 3 //那么下面的功能就是得到[2,4)范围的随机数,然后用cvFloor返回不大于参数的最大整数值,那要么是2,要么是3。numRect = cvFloor(rng.uniform((double)featureMinNumRect, (double)featureMaxNumRect));//这两个值是2和4for (int j=0; j<numRect; j++){ //我在一个box中随机生成一个矩形框,那和你这个box的x和y坐标就无关了,但我必须保证我选择              //的这个矩形框不会超出你这个box的范围啊,是吧              //但这里的3和下面的2是啥意思呢?我就不懂了,个人理解是为了避免这个矩形框太靠近box的边缘了              //要离边缘最小2个像素,不知道这样理解对不对,恳请指导 rectTemp.x = cvFloor(rng.uniform(0.0, (double)(_objectBox.width - 3)));rectTemp.y = cvFloor(rng.uniform(0.0, (double)(_objectBox.height - 3)));//cvCeil 返回不小于参数的最小整数值 rectTemp.width = cvCeil(rng.uniform(0.0, (double)(_objectBox.width - rectTemp.x - 2)));rectTemp.height = cvCeil(rng.uniform(0.0, (double)(_objectBox.height - rectTemp.y - 2)));features[i].push_back(rectTemp);//保存得到的特征模板。注意哦,这里的矩形框是相对于box的相对位置哦,不是针对整幅图像的哦 weightTemp = (float)pow(-1.0, cvFloor(rng.uniform(0.0, 2.0))) / sqrt(float(numRect));//weightTemp = (float)pow(-1.0, c);              //pow(-1.0, c)也就是-1的c次方,而c随机地取0或者1,也就是说weightTemp是随机的正或者负。              //随机测量矩阵中,矩阵元素有三种,sqrt(s)、-sqrt(s)和零。为正和为负的概率是相等的,              //这就是为什么是[2,4)均匀采样的原因,就是取0或者1概率一样。              //但是这里为什么是sqrt(s)分之一呢?还有什么时候是0呢?论文中是0的概率不是挺大的吗?              //没有0元素,哪来的稀疏表达和压缩呢?不懂,恳请指导!(当然稀疏表达的另一个好处              //就是只需保存非零元素。但这里和这个有关系吗?)  featuresWeight[i].push_back(weightTemp);           }}}////在上一帧跟踪的目标box的周围采集若干正样本和负样本,来初始化或者更新分类器的 void CompressiveTracker::sampleRect(Mat& _image, Rect& _objectBox, float _rInner, float _rOuter, int _maxSampleNum, vector<Rect>& _sampleBox)/* Description: compute the coordinate of positive and negative sample image templates   Arguments:   -_image:        processing frame   -_objectBox:    recent object position    -_rInner:       inner sampling radius   -_rOuter:       Outer sampling radius   -_maxSampleNum: maximal number of sampled images   -_sampleBox:    Storing the rectangle coordinates of the sampled images.*/{int rowsz = _image.rows - _objectBox.height - 1;int colsz = _image.cols - _objectBox.width - 1;float inradsq = _rInner*_rInner;float outradsq = _rOuter*_rOuter;      //我们是在上一帧跟踪的目标box的周围采集正样本和负样本的,而这个周围是通过以      //这个目标为中心的两个圆来表示,这两个圆的半径是_rInner和_rOuter。      //我们在离上一帧跟踪的目标box的小于_rInner距离的范围内采集正样本,      //在大于_rOuter距离的范围内采集负样本(论文中还有一个上界,但好像      //这里没有,其实好像也没什么必要噢)int dist; //这四个是为了防止采集的框超出图像范围的,对采集的box的x和y坐标做限制 int minrow = max(0,(int)_objectBox.y-(int)_rInner);int maxrow = min((int)rowsz-1,(int)_objectBox.y+(int)_rInner);int mincol = max(0,(int)_objectBox.x-(int)_rInner);int maxcol = min((int)colsz-1,(int)_objectBox.x+(int)_rInner);   int i = 0;float prob = ((float)(_maxSampleNum))/(maxrow-minrow+1)/(maxcol-mincol+1);int r;int c;        _sampleBox.clear();//important    Rect rec(0,0,0,0);for( r=minrow; r<=(int)maxrow; r++ )for( c=mincol; c<=(int)maxcol; c++ ){dist = (_objectBox.y-r)*(_objectBox.y-r) + (_objectBox.x-c)*(_objectBox.x-c);//后两个条件是保证距离需要在_rInner和_rOuter的范围内              //那么rng.uniform(0.,1.) < prob 这个是干嘛的呢?              //连着上面看,如果_maxSampleNum大于那个最大个数,prob就大于1,这样,              //rng.uniform(0.,1.) < prob这个条件就总能满足,表示在这个范围产生的              //所以box我都要了(因为我本身想要更多的,但是你给不了我那么多,那么你能给的,我肯定全要了)。              //那如果你给的太多了,我不要那么多,也就是prob<1,那我就随机地跳几个走好了  if( rng.uniform(0.,1.)<prob && dist < inradsq && dist >= outradsq ){                rec.x = c;rec.y = r;rec.width = _objectBox.width;rec.height= _objectBox.height;                _sampleBox.push_back(rec);i++;}}_sampleBox.resize(i);}//这个sampleRect的重载函数是用来在上一帧跟踪的目标box的周围(距离小于_srw)采集若干box来待检测。  //与上面的那个不一样,上面那个是在这一帧已经检测出目标的基础上,采集正负样本来更新分类器的。  //上面那个属于论文中提到的算法的第四个步骤,这个是第一个步骤。然后过程差不多,没什么好说的了//void CompressiveTracker::sampleRect(Mat& _image, Rect& _objectBox, float _srw, vector<Rect>& _sampleBox,int step)/* Description: Compute the coordinate of samples when detecting the object.*/{int rowsz = _image.rows - _objectBox.height - 1;int colsz = _image.cols - _objectBox.width - 1;float inradsq = _srw*_srw;int dist;int minrow = max(0,(int)_objectBox.y-(int)_srw);int maxrow = min((int)rowsz-1,(int)_objectBox.y+(int)_srw);int mincol = max(0,(int)_objectBox.x-(int)_srw);int maxcol = min((int)colsz-1,(int)_objectBox.x+(int)_srw);int i = 0;int r;int c;Rect rec(0,0,0,0);    _sampleBox.clear();//important//step表示步长for( r=minrow; r<=(int)maxrow; r=r+step )for( c=mincol; c<=(int)maxcol; c=c+step ){dist = (_objectBox.y-r)*(_objectBox.y-r) + (_objectBox.x-c)*(_objectBox.x-c);if( dist < inradsq ){rec.x = c;rec.y = r;rec.width = _objectBox.width;rec.height= _objectBox.height;_sampleBox.push_back(rec);i++;}}_sampleBox.resize(i);}// Compute the features of samples  //通过积分图来计算采集到的每一个样本的harr特征,这个特征通过与featuresWeight来相乘  //就相当于投影到随机测量矩阵中了,也就是进行稀疏表达了。这里不明白的话,可以看下  //论文中的图二,就比较直观了。所以这里得到的是:每个样本的稀疏表达后的harr特征。  //还有一点:实际上这里采用的不属于真正的harr特征,我博客中翻译有误。这里计算的是  //在box中采样得到的不同矩形框的灰度加权求和void CompressiveTracker::getFeatureValue(Mat& _imageIntegral, vector<Rect>& _sampleBox, Mat& _sampleFeatureValue){int sampleBoxSize = _sampleBox.size();_sampleFeatureValue.create(featureNum, sampleBoxSize, CV_32F);//featureNum是50,参数分别是行、列、类型float tempValue;int xMin;int xMax;int yMin;int yMax;for (int i=0; i<featureNum; i++){for (int j=0; j<sampleBoxSize; j++){tempValue = 0.0f;for (size_t k=0; k<features[i].size(); k++){//features中保存的特征模板(矩形框)是相对于box的相对位置的,                  //所以需要加上box的坐标才是其在整幅图像中的坐标 xMin = _sampleBox[j].x + features[i][k].x;xMax = _sampleBox[j].x + features[i][k].x + features[i][k].width;yMin = _sampleBox[j].y + features[i][k].y;yMax = _sampleBox[j].y + features[i][k].y + features[i][k].height;tempValue += featuresWeight[i][k] * (_imageIntegral.at<float>(yMin, xMin) +_imageIntegral.at<float>(yMax, xMax) -_imageIntegral.at<float>(yMin, xMax) -_imageIntegral.at<float>(yMax, xMin));}_sampleFeatureValue.at<float>(i,j) = tempValue;}}}// Update the mean and variance of the gaussian classifier  //论文中是通过用高斯分布去描述样本的每一个harr特征的概率分布的。高斯分布就可以通过期望和方差  //两个参数来表征。然后通过正负样本的每一个harr特征高斯概率分布的对数比值,来构建分类器决策  //该box属于目标还是背景。这里计算新采集到的正负样本的特征的期望和标准差,并用其来更新分类器 void CompressiveTracker::classifierUpdate(Mat& _sampleFeatureValue, vector<float>& _mu, vector<float>& _sigma, float _learnRate){//后面默认的参数个数是50个50个和0.85Scalar muTemp;Scalar sigmaTemp;    for (int i=0; i<featureNum; i++){meanStdDev(_sampleFeatureValue.row(i), muTemp, sigmaTemp);   _sigma[i] = (float)sqrt( _learnRate*_sigma[i]*_sigma[i]+ (1.0f-_learnRate)*sigmaTemp.val[0]*sigmaTemp.val[0] + _learnRate*(1.0f-_learnRate)*(_mu[i]-muTemp.val[0])*(_mu[i]-muTemp.val[0]));// equation 6 in paper_mu[i] = _mu[i]*_learnRate + (1.0f-_learnRate)*muTemp.val[0];// equation 6 in paper}}// Compute the ratio classifier void CompressiveTracker::radioClassifier(vector<float>& _muPos, vector<float>& _sigmaPos, vector<float>& _muNeg, vector<float>& _sigmaNeg, Mat& _sampleFeatureValue, float& _radioMax, int& _radioMaxIndex){float sumRadio;_radioMax = -FLT_MAX;_radioMaxIndex = 0;float pPos;float pNeg;int sampleBoxNum = _sampleFeatureValue.cols;for (int j=0; j<sampleBoxNum; j++){sumRadio = 0.0f;for (int i=0; i<featureNum; i++){pPos = exp( (_sampleFeatureValue.at<float>(i,j)-_muPos[i])*(_sampleFeatureValue.at<float>(i,j)-_muPos[i]) / -(2.0f*_sigmaPos[i]*_sigmaPos[i]+1e-30) ) / (_sigmaPos[i]+1e-30);pNeg = exp( (_sampleFeatureValue.at<float>(i,j)-_muNeg[i])*(_sampleFeatureValue.at<float>(i,j)-_muNeg[i]) / -(2.0f*_sigmaNeg[i]*_sigmaNeg[i]+1e-30) ) / (_sigmaNeg[i]+1e-30);sumRadio += log(pPos+1e-30) - log(pNeg+1e-30);// equation 4}if (_radioMax < sumRadio){_radioMax = sumRadio;_radioMaxIndex = j;}}}//传入第一帧和要跟踪的目标box(由文件读入或用户鼠标框选),初始化处理void CompressiveTracker::init(Mat& _frame, Rect& _objectBox){// compute feature template//计算box的harr特征模板,先存着HaarFeature(_objectBox, featureNum);//因为这是第一帧,目标box是由由文件读入或者用户鼠标框选的,是已知的,      //所以我们通过在这个目标box周围,采集正样本和负样本来初始化我们的分类器  // compute sample templatessampleRect(_frame, _objectBox, rOuterPositive, 0, 1000000, samplePositiveBox);//rOuterPositive 默认是4sampleRect(_frame, _objectBox, rSearchWindow*1.5, rOuterPositive+4.0, 100, sampleNegativeBox);//rSearchWindow是25//计算积分图,用以快速的计算harr特征integral(_frame, imageIntegral, CV_32F);//通过上面的积分图,计算我们采样到的正负样本的box的harr特征  getFeatureValue(imageIntegral, samplePositiveBox, samplePositiveFeatureValue);getFeatureValue(imageIntegral, sampleNegativeBox, sampleNegativeFeatureValue);//通过上面的正负样本的特征来初始化分类器  classifierUpdate(samplePositiveFeatureValue, muPositive, sigmaPositive, learnRate);classifierUpdate(sampleNegativeFeatureValue, muNegative, sigmaNegative, learnRate);}void CompressiveTracker::processFrame(Mat& _frame, Rect& _objectBox){// predict//第一次采样,半径为25,步长为4(跟CT算法不同地方,这里分了两次采样,将采样的数量减少)sampleRect(_frame, _objectBox, rSearchWindow,detectBox,4);integral(_frame, imageIntegral, CV_32F);getFeatureValue(imageIntegral, detectBox, detectFeatureValue);int radioMaxIndex;float radioMax;radioClassifier(muPositive, sigmaPositive, muNegative, sigmaNegative, detectFeatureValue, radioMax, radioMaxIndex);_objectBox = detectBox[radioMaxIndex];//第二次采样,半径为10,步长为1sampleRect(_frame, _objectBox, 10,detectBox,1);integral(_frame, imageIntegral, CV_32F);getFeatureValue(imageIntegral, detectBox, detectFeatureValue);radioClassifier(muPositive, sigmaPositive, muNegative, sigmaNegative, detectFeatureValue, radioMax, radioMaxIndex);_objectBox = detectBox[radioMaxIndex];// updatesampleRect(_frame, _objectBox, rOuterPositive, 0.0, 1000000, samplePositiveBox);sampleRect(_frame, _objectBox, rSearchWindow*1.5, rOuterPositive+4.0, 100, sampleNegativeBox);getFeatureValue(imageIntegral, samplePositiveBox, samplePositiveFeatureValue);getFeatureValue(imageIntegral, sampleNegativeBox, sampleNegativeFeatureValue);classifierUpdate(samplePositiveFeatureValue, muPositive, sigmaPositive, learnRate);classifierUpdate(sampleNegativeFeatureValue, muNegative, sigmaNegative, learnRate);}

项目下载链接:

linux下:点击打开链接 linux下通过make编译

windows下:点击打开链接 openCV2.4.9 vs2012的工程

1 0
原创粉丝点击