压缩感知跟踪(一)

  闲着也是闲着,不如看看代码吧,最近开始接触压缩感知跟踪,是从朋友那里看到的,所以想找了一些代码跑跑看看,算是体验一下吧!!

  论文:Real-Time Compressive Tracking

  作者:Kaihua Zhang

  单位:香港理工大学

  作者主页:http://www4.comp.polyu.edu.hk/~cskhzhang/

  CT主页:http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm

   作者提供了这篇论文matlab和C++的代码(见CT主页)



     

    运行平台: matlab2010a


下面我直接贴代码了。

     mexCompile.m文件,这里利用matlab和C++的混合,这个文件将integral.cpp和FtrVal.cpp文件进行编译为.mex文件

mex integral.cpp;
mex FtrVal.cpp;


     Runtracker.m这是主文件,首先对初始帧进行处理,之后运行时从第二针开始进行跟踪

% Demo for paper "Real-Time Compressive Tracking,"Kaihua Zhang, Lei Zhang, and Ming-Hsuan Yang
% To appear in European Conference on Computer Vision (ECCV 2012), Florence, Italy, October, 2012 
% Implemented by Kaihua Zhang, Dept.of Computing, HK PolyU.
% Email: zhkhua@gmail.com
% Date: 11/12/2011
% Revised by Kaihua Zhang, 15/12/2011
% Revised by Kaihua Zhang, 11/7/2012

clc;clear all;close all;
%----------------------------------
rand('state',0);
%----------------------------------
%添加路径
addpath('./data');
%----------------------------------
%加载文件
load init.txt;
%[x y width height]
initstate = init;%initial tracker
%----------------------------Set path
img_dir = dir('./data/*.png');
%---------------------------
%读取初始帧
img = imread(img_dir(1).name);
%将uint8转化为double类型
img = double(img(:,:,1));
%----------------------------------------------------------------
%负样本训练数目
trparams.init_negnumtrain = 50;%number of trained negative samples
%正样本搜索半径,设置为4~8
trparams.init_postrainrad = 4.0;%radical scope of positive samples
%目标初始状态[x,y,w,h]
trparams.initstate = initstate;% object position [x y width height]
%新的一帧中的搜索窗口的半径,通常设置为15~35
trparams.srchwinsz = 20;% size of search window
% Sometimes, it affects the results.
%-------------------------
% classifier parameters
%宽
clfparams.width = trparams.initstate(3);
%高
clfparams.height= trparams.initstate(4);
%-------------------------
% feature parameters
% number of rectangle from 2 to 4.
ftrparams.minNumRect = 2;
%随机矩阵的每一行中的非零入口最大值,设置为4-6
ftrparams.maxNumRect = 4;
%-------------------------
%弱分类器个数
M = 50;% number of all weaker classifiers, i.e,feature pool
%-------------------------
%均值
posx.mu = zeros(M,1);% mean of positive features
negx.mu = zeros(M,1);
%方差
posx.sig= ones(M,1);% variance of positive features
negx.sig= ones(M,1);
%-------------------------Learning rate parameter
%学习速率,通常设置为0.7~0.95
lRate = 0.85;
%-------------------------
%compute feature template
%@clfparams: 分类器参数(宽和高)
%@ftrparams:特征参数
%@M: 弱分类器个数=50
[ftr.px,ftr.py,ftr.pw,ftr.ph,ftr.pwt] = HaarFtr(clfparams,ftrparams,M);
%-------------------------
%compute sample templates
%@para: img: 图像
%@para: initstate:初始状态[x,y,w,h]
%@para: trparams.init_postrainrad正样本搜索半径,设置为4~8
%10000: 样本的最大数量
posx.sampleImage = sampleImg(img,initstate,trparams.init_postrainrad,0,100000);
negx.sampleImage = sampleImg(img,initstate,1.5*trparams.srchwinsz,4+trparams.init_postrainrad,50);
%-----------------------------------
%--------Feature extraction
%计算积分图,函数integral.mexw32
iH = integral(img);%Compute integral image
posx.feature = getFtrVal(iH,posx.sampleImage,ftr);
negx.feature = getFtrVal(iH,negx.sampleImage,ftr);
%--------------------------------------------------
[posx.mu,posx.sig,negx.mu,negx.sig] = classiferUpdate(posx,negx,posx.mu,posx.sig,negx.mu,negx.sig,lRate);% update distribution parameters
%-------------------------------------------------
num = length(img_dir);% number of frames
%--------------------------------------------------------
x = initstate(1);% x axis at the Top left corner
y = initstate(2);
w = initstate(3);% width of the rectangle
h = initstate(4);% height of the rectangle
%--------------------------------------------------------
%--------------运行时------------------------------------
%--------------------------------------------------------
for i = 2:num
    %读取视频帧
    img = imread(img_dir(i).name);
    imgSr = img;% imgSr is used for showing tracking results.
    img = double(img(:,:,1));
    %计算新帧的特征模板
    detectx.sampleImage = sampleImg(img,initstate,trparams.srchwinsz,0,100000);   
    %计算新帧的积分图
    iH = integral(img);%Compute integral image
    %对新帧进行计算其特征值
    detectx.feature = getFtrVal(iH,detectx.sampleImage,ftr);
    %------------------------------------
    r = ratioClassifier(posx,negx,detectx);% compute the classifier for all samples
    clf = sum(r);% linearly combine the ratio classifiers in r to the final classifier
    %-------------------------------------
    [c,index] = max(clf);
    %--------------------------------
    %更新模板状态[x,y,w,h]
    x = detectx.sampleImage.sx(index);
    y = detectx.sampleImage.sy(index);
    w = detectx.sampleImage.sw(index);
    h = detectx.sampleImage.sh(index);
    initstate = [x y w h];
    %-------------------------------Show the tracking results
    %-----显示跟踪结果----
    imshow(uint8(imgSr));
    rectangle('Position',initstate,'LineWidth',4,'EdgeColor','r');
    hold on;
    %在视频帧中添加文字
    text(5, 18, strcat('#',num2str(i)), 'Color','y', 'FontWeight','bold', 'FontSize',20);
    %设置位置
    set(gca,'position',[0 0 1 1]); 
    pause(0.00001); 
    hold off;
    %------------------------------Extract samples  
    %提取样本,为下一帧做准备!!
    posx.sampleImage = sampleImg(img,initstate,trparams.init_postrainrad,0,100000);
    negx.sampleImage = sampleImg(img,initstate,1.5*trparams.srchwinsz,4+trparams.init_postrainrad,trparams.init_negnumtrain);
    %--------------------------------------------------Update all the features 
    %更新特征
    posx.feature = getFtrVal(iH,posx.sampleImage,ftr);
    negx.feature = getFtrVal(iH,negx.sampleImage,ftr);
    %--------------------------------------------------
    [posx.mu,posx.sig,negx.mu,negx.sig] = classiferUpdate(posx,negx,posx.mu,posx.sig,negx.mu,negx.sig,lRate);% update distribution parameters
end

HaarFtr.m文件

function [px,py,pw,ph,pwt] = HaarFtr(clfparams,ftrparams,M)

% $Description:
%    -Compute harr feature
% $Agruments
% Input;
%    -clfparams: classifier parameters
%    -clfparams.width: width of search window   窗口的宽
%    -clfparams.height:height of search window  窗口的高
%    -ftrparams: feature parameters
%    -ftrparams.minNumRect: minimal number of feature rectangles
%    -ftrparams.maxNumRect: maximal ....
%    -M: totle number of features 特征个数
% Output:
%    -px: x coordinate, size: M x ftrparms.maxNumRect
%    -py: y ...
%    -pw: corresponding width,size:...
%    -ph: corresponding height,size:...
%    -pwt:corresponding weight,size:....Range:[-1 1]
% $ History $
%   - Created by Kaihua Zhang, on April 22th, 2011
%

width = clfparams.width;
height = clfparams.height;

px = zeros(M,ftrparams.maxNumRect);
py = zeros(M,ftrparams.maxNumRect);
pw = zeros(M,ftrparams.maxNumRect);
ph = zeros(M,ftrparams.maxNumRect);
pwt= zeros(M,ftrparams.maxNumRect);

%函数randi产生一个均匀分布的整数
for i=1:M
     numrects = ftrparams.minNumRect + randi(ftrparams.maxNumRect-ftrparams.minNumRect)-1;
     for j = 1:numrects
        px(i,j) = randi(width-3);          %x坐标
        py(i,j) = randi(height-3);         %y坐标
        pw(i,j) = randi(width-px(i,j)-2);  %宽
        ph(i,j) = randi(height-py(i,j)-2); %高       

        pwt(i,j)= (-1)^(randi(2));         %权重
        pwt(i,j)=pwt(i,j)/sqrt(numrects);
     end      
end
 


sampleImg.m文件


function samples = sampleImg(img,initstate,inrad,outrad,maxnum)
% $Description:
%    -Compute the coordinate of sample image templates
% $Agruments
% Input;
%    -img: inpute image
%    -initistate: [x y width height] object position 
%    -inrad: outside radius of region
%    -outrad: inside radius of region
%    -maxnum: maximal number of samples
% Output:
%    -samples.sx: x coordinate vector,[x1 x2 ...xn]
%    -samples.sy: y ...
%    -samples.sw: width ...
%    -samples.sh: height...
% $ History $
%   - Created by Kaihua Zhang, on April 22th, 2011
%   - Revised by Kaihua Zhang, on May 25th, 2011

% rand('state',0);%important

inrad = ceil(inrad);
outrad= ceil(outrad);

[row,col] = size(img);
x = initstate(1);
y = initstate(2);
w = initstate(3);
h = initstate(4);

rowsz = row - h - 1;
colsz = col - w - 1;

inradsq  = inrad^2;
outradsq = outrad^2;

minrow = max(1, y - inrad+1);
maxrow = min(rowsz-1, y+inrad);
mincol = max(1, x-inrad+1);
maxcol = min(colsz-1, x+inrad);

prob = maxnum/((maxrow-minrow+1)*(maxcol-mincol+1));
i = 1;
%--------------------------------------------------
%--------------------------------------------------
[r,c] = meshgrid(minrow:maxrow,mincol:maxcol);
dist  = (y-r).^2+(x-c).^2;
rd = rand(size(r));

ind = (rd<prob)&(dist<inradsq)&(dist>=outradsq);
c = c(ind==1);
r = r(ind==1);

samples.sx = c';
samples.sy = r';
samples.sw = w*ones(1,length(r(:)));
samples.sh = h*ones(1,length(r(:)));
%--------------------------------------------------
% for r = minrow:maxrow
%     for c = mincol:maxcol
%         dist = (y-r)^2 + (x-c)^2;         
%         if (rand<prob)&(dist<inradsq)&(dist>=outradsq)
%             samples.sx(i) = c;
%             samples.sy(i) = r;
%             samples.sw(i) = w;
%             samples.sh(i) = h;
%             i=i+1;
%         end
%     end    
% end


integral.cpp文件,积分图像

#include <math.h>
#include "mex.h"
// compute integral img
// s(i,j) = s(i-1,j)+i(i,j)
// ii(i,j) = ii(i,j-1)+s(i,j)
// s(i,j) = s(i+j*M);
// s(0,j) = i(0,j);ii(i,0)=s(i,0)
/* Input Arguments */

#define	img_IN	prhs[0]

/* Output Arguments */

#define	ii_OUT	plhs[0]


static void integral(
				   double	ii[],
				   double	*img,
				   int M,
				   int N)
{
	int i;
	int j;
	double *s = new double[M*N];

	for(j=0; j<N; j++)
	{
		s[j*M] = img[j*M];
		for(i=1; i<M; i++)
		{
			s[i+j*M] = s[i-1+j*M] + img[i+j*M];
		}

	}
	

	for(i=0; i<M; i++)
	{
		ii[i] = s[i];
		for(j=1; j<N; j++)
		{
			
			ii[i+j*M] = ii[i+(j-1)*M] + s[i+j*M];

		}
	}

		
	delete []s;
	return;
}

void mexFunction( int nlhs, mxArray *plhs[], 
				 int nrhs, const mxArray*prhs[] )

{ 
	double *ii; 
	double *img; 
	mwSize M,N; 


	/* Check the dimensions of Y.  Y can be 4 X 1 or 1 X 4. */ 

	M = mxGetM(img_IN); 
	N = mxGetN(img_IN);
	

	/* Create a matrix for the return argument */ 
	ii_OUT = mxCreateDoubleMatrix(M, N, mxREAL); 

	/* Assign pointers to the various parameters */ 
	ii = mxGetPr(ii_OUT);

	img = mxGetPr(img_IN); 
	
	/* Do the actual computations in a subroutine */
	integral(ii,img, M, N); 
	return;

}

getFtrVal.m函数

function samplesFtrVal = getFtrVal(iH,samples,ftr)
% $Description:
%    -Compute the features of samples
% $Agruments
% Input;
%    -iH: inpute integral image
%    -samples: sample templates.samples.sx:x coordinate vector, samples.sy:
%    y coordinate vector
%    -ftr: feature template. ftr.px,ftr.py,ftr.pw,ftr.ph,ftr.pwt
% Output:
%    -samplesFtrVal: size: M x N, where M is the number of features, N is
%    the number of samples
% $ History $
%   - Created by Kaihua Zhang, on April 22th, 2011
%   - Revised by Kaihua Zhang, 10/12/2011
sx = samples.sx;
sy = samples.sy;
px = ftr.px;
py = ftr.py;
pw = ftr.pw;
ph = ftr.ph;
pwt= ftr.pwt;
%调用函数FtrVal.mexw32,提取特征
samplesFtrVal = FtrVal(iH,sx,sy,px,py,pw,ph,pwt); %feature without preprocessing

FtrVal.cpp函数

#include <math.h>
#include "mex.h"
// compute integral img
// s(i,j) = s(i-1,j)+i(i,j)
// ii(i,j) = ii(i,j-1)+s(i,j)
// s(i,j) = s(i+j*M);
// s(0,j) = i(0,j);ii(i,0)=s(i,0)
/* Input Arguments */

/* Output Arguments */

static void getFtrVal(double samplesFtrVal[],double*iH,double *sx,double * sy,double *px, double *py, double *pw,
					  double *ph, double *pwt, int len_F,int len_S,int len_R,int M,int N)

{
   	int i,j,minJ,maxJ,minI,maxI;
    int m,k;
	int x,y;
    int *temp = new int[len_F];
	for(i=0;i<len_F; i++)
	{
	   m=0;
       for(j=0;j<len_R;j++)
	   {
		   if(px[i+j*len_F]!=0)
		   {
			   m = m+1;
		   }
		   else
		   {
			   break;
		   }

	   }
	   temp[i] = m;
	}

    for(i=0;i<len_F;i++)
       for(j=0;j<len_S;j++)
	   {
	     m = 0;
		 x = sx[j];
		 y = sy[j];

		 for(k=0;k<temp[i];k++)
		 {
			 minJ = x-1+px[i+k*len_F];
             maxJ = x-1+px[i+k*len_F]+pw[i+k*len_F]-1;
             minI = y-1+py[i+k*len_F];
             maxI = y-1+py[i+k*len_F]+ph[i+k*len_F]-1;

			 m = m+pwt[i+k*len_F]*(iH[minI+minJ*M]+iH[maxI+maxJ*M]
			 -iH[maxI+minJ*M]-iH[minI+maxJ*M]);

		 }
		 samplesFtrVal[i+j*len_F]=m;
	   }
   delete []temp;
       
}          
void mexFunction( int nlhs, mxArray *plhs[], 
				 int nrhs, const mxArray*prhs[] )

{ 
	double *iH,*sx,*sy,*px,*py,*pw,*ph,*pwt; 
	 		
    double *samplesFtrVal;

	mwSize len_F,len_S,len_R,M,N;

    int i,j,k,m1,n1,c;

	iH = mxGetPr(prhs[0]);
	sx = mxGetPr(prhs[1]);
	sy = mxGetPr(prhs[2]);
	px = mxGetPr(prhs[3]);//s.rect.x
	py = mxGetPr(prhs[4]);//s.rect.y
	pw = mxGetPr(prhs[5]);//s.rect.width
	ph = mxGetPr(prhs[6]);//s.rect.height
	pwt = mxGetPr(prhs[7]);//s.weight

	len_F = mxGetM(prhs[3]);
	len_S = mxGetN(prhs[1]);
	len_R = mxGetN(prhs[3]);


	M = mxGetM(prhs[0]); 
	N = mxGetN(prhs[0]);
	
    plhs[0] = mxCreateDoubleMatrix(len_F,len_S, mxREAL);



	samplesFtrVal = mxGetPr(plhs[0]);


	getFtrVal(samplesFtrVal,iH,sx,sy,px,py,pw,ph,pwt,len_F,len_S,len_R,M,N);
	    
	return;

}

classiferUpdate.m函数

function [mu1,sig1,mu0,sig0] = classiferUpdate(posx,negx,mu1,sig1,mu0,sig0,lRate)
% $Description:
%    -Update the mean and variance of the gaussian classifier
% $Agruments
% Input;
%    -posx: positive sample set. We utilize the posx.feature
%    -negx: negative ....                   ... negx.feature
%    -mu1: mean of positive.feature M x 1 vector
%    -sig1:standard deviation of positive.feature M x 1 vector 
%    -mu0 : ...    negative
%    -sig0: ...    negative
%    -lRate: constant rate
% Output:
%    -mu1: updated mean of positive.feature
%    -sig1:...     standard deviation ....
%    -mu0: updated mean of negative.feature
%    -sig0:....    standard variance ...
% $ History $
%   - Created by Kaihua Zhang, on April 22th, 2011
%   - Changed by Kaihua Zhang, on May 18th, 2011
%--------------------------------------------------
[prow,pcol] = size(posx.feature);
pmu = mean(posx.feature,2);
posmu = repmat(pmu,1,pcol);
sigm1 = mean((posx.feature-posmu).^2,2);

nmu = mean(negx.feature,2);
[nrow,ncol] = size(negx.feature);
negmu = repmat(nmu,1,ncol);
sigm0 = mean((negx.feature-negmu).^2,2);
%------------------------------------------Online MIL update method
% sig1= lRate*sig1+ (1-lRate)*sqrt(sigm1);
% mu1 = lRate*mu1 + (1-lRate)*pmu;
% 
% sig0= lRate*sig0+ (1-lRate)*sqrt(sigm0);
% mu0 = lRate*mu0 + (1-lRate)*nmu;
%---------------------------------------------
%------------------------------------------Our update method
sig1= sqrt(lRate*sig1.^2+ (1-lRate)*sigm1+lRate*(1-lRate)*(mu1-pmu).^2);
mu1 = lRate*mu1 + (1-lRate)*pmu;

sig0= sqrt(lRate*sig0.^2+ (1-lRate)*sigm0+lRate*(1-lRate)*(mu0-nmu).^2);
mu0 = lRate*mu0 + (1-lRate)*nmu;

ratioClassifier.m函数

function r = ratioClassifier(posx,negx,samples,M)
% $Description:
%    -Compute the ratio classifier 
% $Agruments
% Input;
%    -posx: trained positive sample set. We utilize the posx.mu,posx.sig
%    -negx: trained negative ....                   ... negx.mu,negx.sig
%    -samples: tested samples. We utilize samples.feature
% Output:
%    -r: the computed classifier with respect to samples.feature
% $ History $
%   - Created by Kaihua Zhang, on April 22th, 2011

[row,col] = size(samples.feature);
mu1 = posx.mu;
sig1= posx.sig;
mu0 = negx.mu;
sig0= negx.sig;

mu1  = repmat(mu1,1,col);
sig1 = repmat(sig1,1,col);
mu0  = repmat(mu0,1,col);
sig0 = repmat(sig0,1,col);

n0= 1./(sig0+eps);
n1= 1./(sig1+eps);
e1= -1./(2*sig1.^2+eps);
e0= -1./(2*sig0.^2+eps);

x = samples.feature;
p0 = exp((x-mu0).^2.*e0).*n0;
p1 = exp((x-mu1).^2.*e1).*n1;

r  = (log(eps+p1)-log(eps+p0));

数据在作者的主要上有哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值