TLD源码深度分析:初始化模块

本文详细解读了TLD算法的关键步骤,包括构建网格、获取最相似边界框、特征提取、生成正负样本数据、分类器训练和评估等过程。通过实际案例分析,旨在帮助读者理解并避免常见错误,提高算法应用效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于TLD的研究,已有些时日。最开始的时候看Zdenek Kalal的论文,但是有很多啃不动的地方。看完只觉得了解了个大体框架,很多地方都不明白。后来,又看完了各位牛人的分析及讲解(大部分已转载到本博客,大家可以查阅),受益匪浅!但是觉得对很多问题还是不明白!好在网友【冷月无心】给我推荐了C++版本作者的论文,作者分析得很细,看完很受用,解除了很多困惑!最近,打算再根据C++源码深入地走一遍,并把源码功能详细分享给大家!希望后面学习使用TLD算法的朋友通过我的分析,能够不走那么多弯路,也欢迎朋友们和我一起讨论!废话就说到这里,开始分享。。。

1.       buildGrid(frame1,box)

输入:

      当前帧图像:frame1

      初始边界框:box

输出:

         所有边界框及其信息:vector<BoundingBox> grid

    描述:

使用滑动窗法对整帧图像,按从上到下、从左到右的顺序,取边界框并记录其大

小、位置、尺度、与初始边界框(第一帧中手工所取)重叠度。其中,尺度取初

始边界框的1.2(S次方)倍,S取值为-10、-9、…、9、10。

 

2.       getOverlappingBoxes(box,num_closest_init)

输入:

      初始边界框:box

      欲得到good_box(与初始边界框最相似的box)的个数:num_closest_init

输出:

      最相似边界框:best_box

        最相似的num_closest_init个边界框:vector<int>good_boxes

          不重叠边界框:vector<int> bad_boxes

描述:

将所有边界框中,与初始框box重叠度最高的边界框信息赋给best_box。把所有重

叠度高于0.6的边界框归类到good_boxes;把所有重叠度低于阈值bad_overlap(读

取自parameters.yml,论文中为0.2)的边界框归类到bad_boxes。如果good_boxes

中边界框个数多于num_closest_init个,则从中取重叠率最高num_closest_init

个边界框good_boxes。

函数末尾调用getBBHull()函数的目的是,得到good_boxes中所有边界框能覆盖到

的最大边界。

 

3.       classifier.prepare(scales):函数位于FerNNClassifier.cpp中。

输入:

所有有效尺度:scales

   输出:

         所有待获取2bitBP特征(位置):features

         阈值:0.5*nstructs

         初始化Posteriors、pCounter、nCounter

   描述:

对特征提取的位置(均匀任选图像块中两点)进行选取(共计:蕨个数*特征位数

(二进制数位数)*尺度大小(21) 个),声明并初始化每个蕨的可信度、正样

本计数器、负样本计数器。

4.       generatePositiveData(frame1,num_warps_init)

输入:

当前帧图像:frame1

图像块变换次数:num_warps_init

最相似边界框:best_box

相似边界框:good_boxes

   输出:

              集成分类器正样本集:pX

              best_box图像块处理结果:pEx

描述:

getPattern(frame(best_box),pEx,mean,stdev):

frame(best_box)为该帧图像中best_box边界框对应图像块;将该图像块resize

为15*15的大小;计算该图像的均值、方差,分别存放到mean、stdev中;将该

图像块与均值作差的结果存于pEx中。

 

        generator(frame,pt,warped,bbhull.size(),rng):

        pt为good_boxes最大边界框(2中有提到)的中心点;该函数对每个good_box对

应图像块仿射变换:±1%范围的偏移,±1%范围的尺度变化,±10%范围的平面

内旋转,并且在每个像素上增加方差为5的高斯噪声(确切的大小是在指定的范

围内随机选择的),共计num_warps_init种。

关于该部分,详情见《关于PatchGenerator类 》 

     对每一仿射图像块计算特征,并存于pX中。

      

        classifier.getFeatures(patch,grid[idx].sidx,fern):

        对尺度grid[idx].sidx下的图像块patch,使用3中定义的位置计算特征,并存于

        fern中。

 

注意:

         原C++版本作者此处代码有误。没有用到变换后的图像块。

   (也有朋友说没有错,待验证,但修改的一定是正确的)

修改方法一:

    将generator(frame,pt,warped,bbhull.size(),rng);

    修改成generator(img,pt,img,frame.size(),rng);

修改方法二:

    将整个for循环内容修改为:

    for (int i=0;i<num_warps;i++)

   {

     if(i == 0)

     {

for (int b = 0; b < good_boxes.size(); b ++)

{

   idx=good_boxes[b];

   patch = img(grid[idx]);

   classifier.getFeatures(patch, grid[idx].sidx, fern);

   pX.push_back(make_pair(fern,1));

}

   }

  else

   {

      generator(img,pt,warped,bbhull.size(),rng);

      for (int b = 0; b < good_boxes.size(); b ++)

      {

idx=good_boxes[b];

Rect region(grid[idx].x-bbhull.x, grid[idx].y - bbhull.y, grid[idx].width, grid[idx].height);

patch = warped(region);

classifier.getFeatures(patch, grid[idx].sidx, fern);

pX.push_back(make_pair(fern,1));

     }

  }

}

 

5.       meanStdDev(frame1(best_box),mean,stdev)

输入:

最相似图像块:frame1(best_box)

输出:

图像块均值:mean

图像块标准差:stdev

描述:

计算best_box边界框对应图像块的均值和标准差,并分别存于mean、stdev中。

 

6.       integral(frame1,iisum,iisqsum)

输入:

        整帧图像:frame1

输出:

        积分图:iisum

        平方积分图:iisqum

描述:

        对整帧图像计算积分图、图像平方的积分图

 

7.       generateNegativeData(frame1)

输入:

         整帧图像:frame1

              模板个数:bad_patches

        所有不重叠边界框:bad_boxes

        积分图:iisum

        平方积分图:iisqum

输出:

         负样本特征集:nX

         负样本模板集:nEx

描述:

               random_shuffle(bad_boxes.begin(),bad_boxes.end()):

       随机打乱bad_boxes的顺序。

 

       取所有bad_boxes边界框中,方差值高于best_box图像块阈值一半的图像块,计算

特征并保存到nX中。(why?:因为检测的时候,方差分类器位于集合分类器的前一

级。也就是说,方差低于0.5倍best_box图像块方差的部分都被排除,如果在此处

将其作为负样本是没有意义的,甚至会降低集合分类器的检测效果。)

              任取bad_patches个图像块作为负模板。


注意:

      原程序版本有错,对方差分类器方差重复取50%。

      将if (getVar(grid[idx],iisum,iisqsum)<var*0.5f)

      修改成if (getVar(grid[idx],iisum,iisqsum)<var*1.0f)


8.       classifier.trainF(ferns_data,2)

输入:

          已混合打乱的正负样本特征数据:ferns_data

输出:

        分类器模型:任何特征对应可信度(该图像块为正样本的概率):posteriors

描述:

     统计P/N约束被使用的次数,来计算一个特征的可信度

更多详情见《集成分类器》      

9.       classifier.trainNN(nn_data)

输入:

     已混合打乱的正负样本模板数据:nn_data

输出:

     筛选出的模板:pEx、nEx

描述:

     通过计算自相关系数NCC筛选模板

更多详情见《最近邻分类器》

10.       classifier.evaluateTh(nXT,nExT)

输入:

         负样本随机蕨测试集:nXT

         负样本模板测试集:nExT

   输出:

            更新后的随机蕨阈值:thr_fern

            更新后的模板NCC阈值:thr_nn

            更新后的有效性判断(P/N学习)阈值:thr_nn_valid

   描述:

             对所有负样本随机蕨测试集,计算其随机蕨可信度,若最大值大于预设阈值

             thr_fern,则用该最大值替换更新;对所有负样本模板测试集,计算其NCC系数,

      若最大值大于预设阈值thr_nn,则用该最大值替换更新;若最后更新得到的thr_nn

大于预设thr_nn_valid,则替换更新thr_nn_valid。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值