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

来源:互联网 发布:gbk转utf java 编辑:程序博客网 时间:2024/05/02 01:53

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:4x72k = size(x,2);   %k=72r = 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]=1x = x(:,idx); %取出所有idx[i]=1的列组成新的xx(x > 1) = 1;  %大于1的赋1x(x < 0) = 0;numF = size(x,2);  %计算新x的列数 164x = x(:,randperm(numF)); %随机排列这16列x = x(:,1:nFEAT*nTREES); %取特征对数*随机树数个列13*10=130列 4*130x = reshape(x,4*nFEAT,nTREES); %变为52*10并输出  1、2行为一个坐标 3、4行为一个坐标,两个坐标行成一个特征对,论文里称为pixel comparisonsf.x = x;                 %输出f.x中为f.type = 'forest';% showif 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);    endendend


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 generatorthrN = 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,y2thrN       = 0.5 * nTREES;nSCALE     = mxGetN(prhs[4]);//尺度数IIMG       = (double*) malloc(iHEIGHT*iWIDTH*sizeof(double));//分配图像内存空间IIMG2      = (double*) malloc(iHEIGHT*iWIDTH*sizeof(double));// BBOXmBBOX      = mxGetM(prhs[2]); //6nBBOX      = 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]);//scalesOFF   = 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;//初始化权制都赋0nP[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         5double *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 bboxesidxP = 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个endbbP  = tld.grid(:,idxP);%取出这10个网格if isempty(bbP), return; end% Get hullbbH  = 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.fliplrpEx = [pEx tldGetPattern(im1,bbP0,tld.model.patchsize,1)];%水平翻转的最大网格归一化结果endfor 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 bboxidxN        = 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 variancenX          = nX(:,status==1); %未被方差分类器丢弃的样本% Randomly select 'num_patches' bboxes and measure patchesidx = 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里面的内容就可以理解

原创粉丝点击