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'
1.1.2 随机厥分类函数fern.cpp(部分)
这一部分主要用来对随机厥分类器进行产生、初始化、验证,随机厥分类就是坐着文中提到的ensemble classifier,关于随机厥的介绍详见:http://download.csdn.net/detail/cv_richie/4983172 挣点分下资源,没分的朋友给我留言留邮箱吧。
还要注意的就是matlab和c中数组存储方式的不同。可以参加我上一篇文章
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最大网格的坐标
1.1.4 tldGenerateNegativeData.m
从重叠度小于0.2的网格中产生
其他部分相对简单,参照前面init.m里面的内容就可以理解
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里面的内容就可以理解
相关文章推荐
- TLD取经之路(3)-- 始于足下--tldDemo.m tldInit.m
- VS下EXE可执行文件启动代码剖析(3)_ioinit 函数
- 关于opencv通过initUndistortRectifyMap函数获取undistort后的对应点的方法
- Linux 信号处理机制中涉及到的相关几个函数解释
- C++ inline函数相关总结
- Zstack之InitBoard()函数分析
- InitUndistortMap矫正函数
- TLD取经之路(3)-- 始于足下
- Oracle安装相关Linux参数(转自m77m78 in ITPUB)
- zlib之基本函数zlibVersion、deflateInit/deflate/deflateEnd、inflateInit/inflate/inflateEnd
- ORACLE SQL 函数 INITCAP()
- Redis in Python: Redis 键(key)相关函数简介
- history and its relevant variables in Linux/GNU and Mac OS history命令以及相关环境变量
- 运行TLD时的initcamera问题
- 数据库Initcap函数实现
- ZygoteInit 相关分析
- [C/CPP系列知识] 在C中使用没有声明的函数时将发生什么 What happens when a function is called before its declaration in C
- jqMobile中pageinit,pagecreate,pageshow等函数的执行顺序
- Cocos2dx通信(Http&Socket)相关编译到Android细节总结 编译加入curl关联lib与头文件 && 解决pthread的cancel函数NDK不支持,找不到sockaddr_in
- VFW中VCM的基本操作过程及相关函数