2013年Object Visual Tracker Benchmark的提出是视频图像跟踪另一的大事件,自此视频跟踪领域有了公认的Benchmark,跟踪方面的研究与以前已经完全不一样的。虽然下载源码,摸索之后都可以看懂,但是博主还是想系统的介绍其中的工具。官方的SDK可以极大的帮助我们评估算法,产生一些可以直接出现在Paper上的图表。

        这篇博客主要介绍如何Visual Tracker Benchmark 中提供的Matlab代码,希望能有所帮助。Python的可以看那些开源的demo,差不多一样的思路。

一、纵览

首先,简单介绍下各个文件夹的内容:

drawresultBB.m 是根据结果画BoundingBox的脚本

main_running.m 是跟踪算法测试的脚本,可以跑自己的tracker算法

perfPlot.m 是根据结果绘制曲线图的脚本,Paper中的图就可以通过这个角度得到

/anno 中存放的是groundtruth.txt文件

/figs 是输出的图片结果

/initOmit 也是groundtruth,被用于初始化第一帧

/perfMat 中计算曲线图时中间保存的结果,为.mat格式

/results 里面是.mat格式的各个算法的运行结果

/rstEval 是各个和计算结果精度有关的脚本或者函数

/tmp 里面主要是绘制Boundingbox的输出图片

/trackers 是跟踪算法程序所在的目录

/util 是我们常常需要修改的配置参数脚本文件,这个里面我们可以修改测量的序列、被测量的算法等等

/vlfeat 这个不是自带的,是该包依赖的环境,我们在官网下载安装,需要变一下

        关于结果,我们可以在网站上下载,Matlab代码总自带13年版本的结果,15年版本增加了100个图像序列,增加了三个跟踪算法,这些都要在官网额外下载,压缩包的名字带pami-15字样。关于13和15版本的不同,以及一些特例,博主把它放在最后介绍。

二、结果格式

        这个其实没什么好讲的,我们如果没有特殊需求,按照左边格式进行存储即可,如果其它格式的话,点开results里面随便导入一个.mat来看看就懂了。根据类型不同会有不同的额外字段,就讲下type字段好了,

type主要有六种,只介绍其中最常用两种,其它的看代码吧:

    ‘rect’: 矩形,存储的格式为[x y width height]

    ‘ivtAff’: 粒子滤波里面和放射变换有关的格式,1×6,可以组成一个2×3的仿射矩阵

    在2015版本的有些程序中,会是’affine_inv’之类的名字,在13程序中会无法识别,其实这两个是相同的,修改成一样就好

然后我们看drawResultsBB.m里面的一段代码,如果想了解某个格式,顺着读下去就可以了

            switch resultsAll{j}.type
                case 'rect'
                    rectangle('Position', resultsAll{j}.res(i,:), 'EdgeColor', plotDrawStyle{j}.color, 'LineWidth', LineWidth,'LineStyle',LineStyle);
                case 'ivtAff'
                    drawbox(resultsAll{j}.tmplsize, resultsAll{j}.res(i,:), 'Color', plotDrawStyle{j}.color, 'LineWidth', LineWidth,'LineStyle',LineStyle);
                case 'L1Aff'
                    drawAffine(resultsAll{j}.res(i,:), resultsAll{j}.tmplsize, plotDrawStyle{j}.color, LineWidth, LineStyle);                    
                case 'LK_Aff'
                    [corner c] = getLKcorner(resultsAll{j}.res(2*i-1:2*i,:), resultsAll{j}.tmplsize);
                    hold on,
                    plot([corner(1,:) corner(1,1)], [corner(2,:) corner(2,1)], 'Color', plotDrawStyle{j}.color,'LineWidth',LineWidth,'LineStyle',LineStyle);
                case '4corner'
                    corner = resultsAll{j}.res(2*i-1:2*i,:);
                    hold on,
                    plot([corner(1,:) corner(1,1)], [corner(2,:) corner(2,1)], 'Color', plotDrawStyle{j}.color,'LineWidth',LineWidth,'LineStyle',LineStyle);
                case 'SIMILARITY'
                    warp_p = parameters_to_projective_matrix(resultsAll{j}.type,resultsAll{j}.res(i,:));
                    [corner c] = getLKcorner(warp_p, resultsAll{j}.tmplsize);
                    hold on,
                    plot([corner(1,:) corner(1,1)], [corner(2,:) corner(2,1)], 'Color', plotDrawStyle{j}.color,'LineWidth',LineWidth,'LineStyle',LineStyle);
                otherwise
                    disp('The type of output is not supported!')
                    continue;
            end

三、进行测试

        当然,你完全可以不适用这个框架进行测试,只需把结果存成对应格式拿过来画图就可以了,这里介绍下框架用法。

        把自己的tracker做一个matlab接口,不管你是exe还是什么脚本,我们需要一个统一的matlab接口,输入序列输出结果,都要完全按照格式来。

        然后把自己的程序放到tracker文件夹下,用自己的名字命名文件夹,接口的脚本名称为run_XXX.m,XXX就是你tracker的名字。

        然后需要在utils/configTrackers中进行配置,其实就是把你的tracker名字加进去,utils/configTrackers中的测试序列如果有变动也可以进行修改。

        最后,在main_running.m中进行配置你的测试项,是TRE还是OPE还是SRE,默认的OPE结果目录是在TRE目录里面,因为TRE中第1帧开始就是OPE的结果,所以自己的结果需要提前拷贝到results目录下的对应位置。然后等待结果即可。

四、绘制结果曲线

        运行Perplot,要改什么直接定位代码进行修改,没什么好讲的,结果保存在figs文件夹下

addpath('./util','./rstEval');

        原来的脚本如果直接运行,可能会提示有函数找不到,我们在代码中按照上面进行修改,把对应函数加到目录里面就可以了

        如果要改线条样式,直接修改line_style结构体,要修改绘制的算法、计算的序列,也是直接在utils文件夹下的config脚本总修改,总之直接看脚本就可以知道改哪里,不多讲了。

五、绘制结果框

        这个直接运行就可以了,和前面一样的配置在utils文件夹下,个人觉得他给的这个不是很好。他使用matlab画在figure窗口上,把figure窗口图像保存下来,图像分辨率都丢了,还有个白框在外面,于是博主写了一个直接在原图进行绘制的。

        这段代码只是一个函数,你需要加上配合的接口,允许rect和invaff两种格式的直接绘制,还可以绘制旋转矩形,如果不需要旋转矩形theta参数给0就可以了,由于使用invaff格式时需要模板大小,最后一个参数tp_sz就是模板大小,不需要的时候赋值0就可以。还有就是帧号会被标识在左上角,如果不需要,那么frame_no赋值0就可以不绘制帧号。

        这是绘制图片制作的gif动画:gif动画制作,请参考这篇博客

function [ Iout ] = draw_rects_inc( I, frame_no, boxes, theta, colors, tp_sz )
%UNTITLED 此处显示有关此函数的摘要
%   I   Image
%   box = [x y width height];
%   theta 弧度制,顺时针
assert(numel(boxes)==numel(colors));
assert(numel(theta)==numel(colors));
rects = numel(boxes);

% 根据box和theta算顶点
if size(I,3)==1
    rgb = cat(3,I,I,I);
    I = rgb;
end

if frame_no < 1000,
    text = sprintf('#%03d', frame_no);
end
if frame_no >= 1000,
    text = sprintf('#%04d', frame_no);
end

if frame_no < 0,
    Iout = I;
else
    ti = vision.TextInserter(text, 'Location', [2 2], 'FontSize', 20, ...
        'Color', [72 255 72], 'Font', 'Arial Black');
    Iout = step(ti, I);
end

for ii = rects:-1:1
   box = boxes{ii};
   t = theta{ii};
   if length(box) == 4,  % 'rect'
   if t==0,
       Iout = insertShape(Iout, 'Rectangle', box, 'LineWidth', 3, ...
            'Color', colors{ii}, 'Opacity', 0.7);
       continue;
   end
   
   R = [cos(t) -sin(t);
        sin(t) cos(t)];
   B(1,:) = [box(1) box(1)+box(3) box(1)+box(3) box(1)       ];%x
   B(2,:) = [box(2) box(2)        box(2)+box(4) box(2)+box(4)];%y
   C(1,:) = B(1,:)-box(1)-box(3)/2;
   C(2,:) = B(2,:)-box(2)-box(4)/2;
   D = R*C;
   D(1,:) = D(1,:)+box(1)+box(3)/2;
   D(2,:) = D(2,:)+box(2)+box(4)/2;
   
   Iout = insertShape(Iout, 'Polygon', D(:)', 'LineWidth', 3, ...
       'Color', colors{ii}, 'Opacity', 0.7);
   else if length(box) == 6,  % 'invAff'
   w = tp_sz(1);
   h = tp_sz(2);
   p = box;
   M = [p(1) p(3) p(4); p(2) p(5) p(6)];
   E = [ 1,-w/2,-h/2; 1,w/2,-h/2; 1,w/2,h/2; 1,-w/2,h/2; 1,-w/2,-h/2 ]';
   E = M * E;
   
   xs = min(E(1,:)); xe = max(E(1,:));
   ys = min(E(2,:)); ye = max(E(2,:));
   Iout = insertShape(Iout, 'Rectangle', [xs ys xe-xs ye-ys], 'LineWidth', 3, ...
            'Color', colors{ii}, 'Opacity', 0.7);
   %Iout = insertShape(Iout, 'Polygon', E(:)', 'LineWidth', 3, ...
   %    'Color', colors{ii}, 'Opacity', 0.7);
   end        
   end
end

end

六、注意事项

        这一节可能是最重要的,不过把它放到了最后…

        15年版本和13年版本的区别:

1. 13和15版本的david测试集的start相通,但是end不同,就是所帧数量是不同的

2. 13版本和15版本在存储例子滤波格式的结果时,一个type为’invAff’,15年版本变成了’affine_inv’

3. 关于名字的修改,Jogging-1,Jogging-2在15年修改成了Jogging.1,Jogging.2,可能会导致load_video_info的变动

4. Tiger1数据集,某些算法的结果不明原因的少了几帧,由于博主也不知道这是什么情况,所以博主在测试时注释掉了该序列

        OK,See You Next Chapter!

8 对 “Object Visual Tracker Benchmark 使用教程”的想法;

  1. 楼主你好,我在配置完后(用的是OTB-2013),在运行perfplot时,出现以下错误:
    soccer DSST
    试图访问 results.res(2,:);由于 size(results.res)=[1,4],索引超出范围。

    出错 calcSeqErrRobust (line 16)
    r = results.res(i,:);

    出错 genPerfMat (line 84)
    [aveCoverage, aveErrCenter, errCoverage, errCenter] = calcSeqErrRobust(res, anno);

    出错 perfPlot (line 167)
    genPerfMat(seqs, trackers, evalType, nameTrkAll, perfMatPath);
    希望楼主帮忙,万分感谢

    1. 报错说的很清楚了,result.res是一行四列的,res(2,:)超出索引范围,检查下什么原因导致的

  2. 博主,你好!“当然,你完全可以不适用这个框架进行测试,只需把结果存成对应格式拿过来画图就可以了”,我直接把结果存到results/results_TRE_CVPR13文件下,然后运行perfPlot.m,画出来的图是我上次用框架测试法的图,初入小白,求博主解答一下。谢谢~

    1. 就是把自己结果保存成.mat文件,这个文件BenchMark的通用格式,这个格式可以直接参考现成的(可以直接在官网下载结果,里面是一大堆results_.mat),这个框架不运行算法(这个框架本身是支持在框架内运行多个跟踪算法的),只是通过perPlot脚本把图画出来,仅此而已

  3. 你好,怎样更改线条样式,出错了
    错误使用 plot
    ‘o’ 是无效值。请使用以下某个值: ‘-‘ | ‘–‘ | ‘:’ | ‘-.’ | ‘none’。

  4. 你好,前辈,看到你的关于自己画图显示的部分遇到点问题,不知怎么按照你的方法实现,可以详细交流一下嘛微信:chuyanqiu2255

  5. 前辈,最近看你的教程一步一步配置过来,收获很多,想进一步向你请教,能留一下联系方式嘛?真的很着急!拜托了1628464345这是我的QQ,上一个评论留了微信。真的拜托了

发表评论

邮箱地址不会被公开。 必填项已用*标注