转载:Object Visual Tracker Benchmark 使用教程
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数据集,某些算法的结果不明原因的少了几帧,由于博主也不知道这是什么情况,所以博主在测试时注释掉了该序列