现在的位置: 首页 > 综合 > 正文

TLD取经之路(4)– 始于足下–tldInit.m中涉及到的相关函数

2018年02月21日 ⁄ 综合 ⁄ 共 6997字 ⁄ 字号 评论关闭

matlab版源程序:http://download.csdn.net/detail/cv_richie/4982673

C程序:http://download.csdn.net/detail/cv_richie/4982678

晚点我会把我注释的版本发上来。

1.1初始化部分

1.1.1 tldGenerateFeatures.m  %初始化FERN中的pixel comparison特征对tld.featrue.x为52*10 tld.feature.type='forest'

function f = tldGenerateFeatures(nTREES, nFEAT, show)%产生pixel comparison并显示

SHI = 1/5;
SCA = 1;
OFF = SHI;

x = repmat(ntuples(0:SHI:1,0:SHI:1),2,1);  %x:4x36的数组
x = [x x + SHI/2];  %x:4x72
k = size(x,2);   %k=72
r = x; r(3,:) = r(3,:) + (SCA*rand(1,k)+OFF);  %r:4x72第三行加随机量
l = x; l(3,:) = l(3,:) - (SCA*rand(1,k)+OFF); %l:4x72第三行减随机量
t = x; t(4,:) = t(4,:) - (SCA*rand(1,k)+OFF); %类似
b = x; b(4,:) = b(4,:) + (SCA*rand(1,k)+OFF);%类似

x = [r l t b];  %x:4x288 

idx = all(x([1 2],:) < 1 & x([1 2],:) > 0,1);  %取出所有1,2行小于1大于0.1的列,相应idx[i]=1
x = x(:,idx); %取出所有idx[i]=1的列组成新的x
x(x > 1) = 1;  %大于1的赋1
x(x < 0) = 0;

numF = size(x,2);  %计算新x的列数 164

x = x(:,randperm(numF)); %随机排列这16列
x = x(:,1:nFEAT*nTREES); %取特征对数*随机树数个列13*10=130列 4*130
x = reshape(x,4*nFEAT,nTREES); %变为52*10并输出  1、2行为一个坐标 3、4行为一个坐标,两个坐标行成一个特征对,论文里称为pixel comparisons

f.x = x;                 %输出f.x中为
f.type = 'forest';

% show
if nargin == 3    %只有当第三输入参量赋值且不为0时才输出显示这些特征点,并且在每一对之间连线
if show
    for i = 1:nTREES
        F = 1+99*reshape(f.x(:,i),4,[]);  %f.x的每一列为一个tree里的特征对,这里取出一列重排为4*13 并*99+1保证不出现0
        img = zeros(100,100);
        imshow(img);
        
        line(F([1 3],:),F([2 4],:),'linewidth',1,'color','w');
        pause(.05);
    end
end
end


1.1.2 随机厥分类函数fern.cpp(部分)

这一部分主要用来对随机厥分类器进行产生、初始化、验证,随机厥分类就是坐着文中提到的ensemble classifier,关于随机厥的介绍详见:http://download.csdn.net/detail/cv_richie/4983172 挣点分下资源,没分的朋友给我留言留邮箱吧。

还要注意的就是matlab和c中数组存储方式的不同。可以参加我上一篇文章

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	if (nrhs == 0) {
		mexPrintf("CLEANUP: function(0);\n");
		mexPrintf("INIT: function(1, img, bb, features, scales)\n");
		mexPrintf("UPDATE: Conf = function(2,X,Y,Margin,Bootstrap,Idx)\n");
		mexPrintf("EVALUATE: Conf = function(3,X)\n");
		mexPrintf("DETECT: function(4,img,maxBBox,minVar,Conf,X)\n");
		mexPrintf("GET PATTERNS: patterns = fern(5,img,idx,minVar)\n");
		return;
	}

	switch ((int) *mxGetPr(prhs[0])) {

		// CLEANUP: function(0);//清零用
		// =============================================================================
	case 0:  {
		srand(0); // fix state of random generator

		thrN = 0; nBBOX = 0; mBBOX = 0; nTREES = 0; nFEAT = 0; nSCALE = 0; iHEIGHT = 0; iWIDTH = 0;

		free(BBOX); BBOX = 0;
		free(OFF); OFF = 0;
		free(IIMG); IIMG = 0;
		free(IIMG2); IIMG2 = 0;
		WEIGHT.clear();
		nP.clear();
		nN.clear();
		return;
			 }

			 // INIT: function(1, img, bb, features, scales) img:当前帧 bb:tld.grid 初始化用
			 //                        0  1      2       3         4
			 // =============================================================================
	case 1:  {

		if (nrhs!=5) { mexPrintf("fern: wrong input.\n"); return; }
		if (BBOX!=0) { mexPrintf("fern: already initialized.\n"); return; }

		iHEIGHT    = mxGetM(prhs[1]);//图像的行数
		iWIDTH     = mxGetN(prhs[1]);//图像的列数
		nTREES     = mxGetN(mxGetField(prhs[3],0,"x"));//mxGetField(prhs[3]) is a (num_features*4)   *    (num_trees ) 
		nFEAT      = mxGetM(mxGetField(prhs[3],0,"x")) / 4; // feature has 2 points: x1,y1,x2,y2
		thrN       = 0.5 * nTREES;
		nSCALE     = mxGetN(prhs[4]);//尺度数

		IIMG       = (double*) malloc(iHEIGHT*iWIDTH*sizeof(double));//分配图像内存空间
		IIMG2      = (double*) malloc(iHEIGHT*iWIDTH*sizeof(double));

		// BBOX
		mBBOX      = mxGetM(prhs[2]); //6
		nBBOX      = mxGetN(prhs[2]);//网格数
		BBOX	   = create_offsets_bbox(mxGetPr(prhs[2]));//计算每个网格角点在图像中的偏移量
		double *x  = mxGetPr(mxGetField(prhs[3],0,"x"));//featrues.x (num_features*4)   *    (num_trees)
		double *s  = mxGetPr(prhs[4]);//scales
		OFF		   = create_offsets(s,x);//创建的是每个特征在每个尺度网格下的偏移量

		for (int i = 0; i<nTREES; i++) {//pow取幂
			WEIGHT.push_back(vector<double>(pow(2.0,nBIT*nFEAT), 0));
			nP.push_back(vector<int>(pow(2.0,nBIT*nFEAT), 0));
			nN.push_back(vector<int>(pow(2.0,nBIT*nFEAT), 0));
		}

		for (int i = 0; i<nTREES; i++) { 
			for (int j = 0; j < WEIGHT[i].size(); j++) {
				WEIGHT[i].at(j) = 0;//初始化权制都赋0
				nP[i].at(j) = 0;
				nN[i].at(j) = 0;
			}
		}

		return;
			 }

	// UPDATE  训练更新随机厥时候用
	// =============================================================================
	case 2: {

		if (nrhs!=5 && nrhs!=6) { mexPrintf("Conf = function(2,X,Y,Margin,Bootstrap,Idx)\n"); return; }
		//                                                                                0 1 2    3            4         5

		double *X     = mxGetPr(prhs[1]);//样本集
		int numX      = mxGetN(prhs[1]);//样本数量
		double *Y     = mxGetPr(prhs[2]);//标号集
		double thrP   = *mxGetPr(prhs[3]) * nTREES; 
		int bootstrap = (int) *mxGetPr(prhs[4]);


		int step = numX / 10;

		if (nrhs == 5) {
			for (int j = 0; j < bootstrap; j++) {//迭代两次
				for (int i = 0; i < step; i++) {
					for (int k = 0; k < 10; k++) {
					
						int I = k*step + i;//遍历样本的标号
						double *x = X+nTREES*I;//注意,matlab中的数是按列纵向存储的,这里的i遍历全部样本
						if (Y[I] == 1) {
							if (measure_forest(x) <= thrP)
								update(x,1,1);
						} else {
							if (measure_forest(x) >= thrN)
								update(x,0,1);
						}
					}
				}
			}
		}
		if (nrhs == 6) {
			double *idx   = mxGetPr(prhs[5]);
			int nIdx      = mxGetN(prhs[5])*mxGetM(prhs[5]);


			for (int j = 0; j < bootstrap; j++) {
				for (int i = 0; i < nIdx; i++) {
					int I = idx[i]-1;
					double *x = X+nTREES*I;
					if (Y[I] == 1) {
						if (measure_forest(x) <= thrP)
							update(x,1,1);
					} else {
						if (measure_forest(x) >= thrN)
							update(x,0,1);
					}
				}
			}
		}



		if (nlhs==1) {
			plhs[0] = mxCreateDoubleMatrix(1, numX, mxREAL); 
			double *resp0 = mxGetPr(plhs[0]);

			for (int i = 0; i < numX; i++) {
				*resp0++ = measure_forest(X+nTREES*i);
			}
		}

		return;
			}

	// EVALUATE PATTERNS 验证分类器效果
	// =============================================================================
	case 3: {

		if (nrhs!=2) { mexPrintf("Conf = function(2,X)\n"); return; }
		//                                                             0 1  

		double *X     = mxGetPr(prhs[1]);//测试用的都是负样本
		int numX      = mxGetN(prhs[1]);

		plhs[0] = mxCreateDoubleMatrix(1, numX, mxREAL); 
		double *resp0 = mxGetPr(plhs[0]);

		for (int i = 0; i < numX; i++) {
			*resp0++ = measure_forest(X+nTREES*i);
		}

		return;
			}
//略。。。。

}

case 4用作检测时的分类

case 5计算特征值

fern中的几个函数:

update更新蕨类直方图,即WEIGHT

measure_forest:返回分类结果

measure_tree_offset:计算特征值

measure_bbox_offset:对新样本计算可信度

create_offsets:计算特征在每个尺度网格下的相对偏移量

create_offsets_bbox:计算每个网格的角点在图像中的偏移量


1.1.3 tldGeneratePositiveData.m 

产生正样本PX输出前十网格的特征,每行是一个网格,10列是一层随机;pex最大网格归一化图像 bbp最大网格的坐标


function [pX,pEx,bbP0] = tldGeneratePositiveData(tld,overlap,im0,p_par)
%px输出前十网格的特征 pex最大网格归一化图像 bbp0最大网格的坐标
pX   = [];
pEx  = [];%zeros(prod(tld.patchsize),numWarps);

% Get closest bbox
[~,idxP] = max(overlap);  %找出与目标重叠度最大的网格编号
bbP0 =  tld.grid(1:4,idxP);%重叠度最大的网格的坐标

% Get overlapping bboxes
idxP = find(overlap > 0.6);%重叠度大于0.6的网格索引
if length(idxP) > p_par.num_closest
    [~,sIdx] = sort(overlap(idxP),'descend'); %重叠度从大到小排序的网格编号   
    idxP = idxP(sIdx(1:p_par.num_closest));%重叠度最大的p_par.num_closest个
end
bbP  = tld.grid(:,idxP);%取出这10个网格
if isempty(bbP), return; end

% Get hull
bbH  = bb_hull(bbP);%这十个网格的范围 对角线坐标
cols = bbH(1):bbH(3);
rows = bbH(2):bbH(4);

im1 = im0;
pEx = tldGetPattern(im1,bbP0,tld.model.patchsize); %最大网格归一化都得结果100*1,0为中心
if tld.model.fliplr
pEx = [pEx tldGetPattern(im1,bbP0,tld.model.patchsize,1)];%水平翻转的最大网格归一化结果
end
for i = 1:p_par.num_warps %初始化为20,更新为10
    if i > 1
        randomize = rand; % Sets the internal randomizer to the same state
        %patch_input = img_patch(im0.input,bbH,randomize,p_par);
        patch_blur = img_patch(im0.blur,bbH,randomize,p_par);
        im1.blur(rows,cols) = patch_blur;
        %im1.input(rows,cols) = patch_input;
    end
    
    % Measures on blured image
    pX  = [pX fern(5,im1,idxP,0)];%这10个网格的随机厥特征 
    
    % Measures on input image
    %pEx(:,i) = tldGetPattern(im1,bbP0,tld.model.patchsize);
    %pEx = [pEx tldGetPattern(im1,tld.grid(1:4,idxP),tld.model.patchsize)];
    
end



1.1.4 tldGenerateNegativeData.m

从重叠度小于0.2的网格中产生



function [nX,nEx] = tldGenerateNegativeData(tld,overlap,img)
%nx负网格特征 nex负网格图像100个
% Measure patterns on all bboxes that are far from initial bbox

idxN        = find(overlap<tld.n_par.overlap);%重叠度小于0.2的网格索引
[nX,status] = fern(5,img,idxN,tld.var/2);%这些网格的特征
idxN        = idxN(status==1); % bboxes far and with big variance
nX          = nX(:,status==1); %未被方差分类器丢弃的样本

% Randomly select 'num_patches' bboxes and measure patches
idx = randvalues(1:length(idxN),tld.n_par.num_patches);
bb  = tld.grid(:,idxN(idx));%100个非目标网格
nEx = tldGetPattern(img,bb,tld.model.patchsize);%100个非目标网格的归一化,每列为一个网格图像


其他部分相对简单,参照前面init.m里面的内容就可以理解

抱歉!评论已关闭.