您的位置:首页 > 其它

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

2013-01-14 17:54 239 查看
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里面的内容就可以理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: