OTB数据集和VOT数据集自己存数据接口参考代码:
type为目标框类型;
res为目标框的所在位置;
fps为跟踪算法的速度;
len为帧数;
startFrame为开始帧的值;
annoBegin为具有groundtruth真实值开始的帧数;
annoBegin与startFrame一般相同。
results.res表示目标框格式为:
四个值的分别表示(X,Y,W,H),他们的位置关系如图所示:
groundtruth的值也和 results.res格式一样。
这个代码用groundtruth为例,数据集选择的是OTB-2013.
有三个需要注意的地方:
1)Jogging和Skating2具有两个跟踪目标需要区分;
2)David,Football1,Freeman3,Freeman4并非第一帧开始最后一帧结束;
3)Tiger1的首5帧目标被遮挡需要去掉,原benchmark中也是去掉了的。
clear;clc;
close all;
% 数据集路径路径
base_path = 'D:\Datasets\OTB100\';
% 视频序列
% videos = {'Basketball'};
videos = {'Soccer', 'Matrix', 'Ironman', 'Deer', 'Skating1', 'Shaking', ...
'Singer1', 'Singer2', 'CarDark', 'Car4', 'David2', 'Sylvester', 'Trellis', ...
'Fish', 'Mhyang', 'David', 'Coke', 'Bolt', 'Boy', 'Dudek', ...
'Crossing', 'Couple', 'Football1', 'Jogging-1', 'Jogging-2', 'Doll', ...
'Girl', 'Walking2', 'Walking', 'Fleetface', 'Freeman1', 'Freeman3', ...
'Freeman4', 'David3', 'Jumping', 'CarScale', 'Skiing', 'Dog1',...
'Suv', 'MotorRolling', 'MountainBike', 'Lemming', 'Liquor', 'Woman', 'Faceocc1', ...
'Faceocc2', 'Basketball', 'Football', 'Subway', 'Tiger1', 'Tiger2'};
% 跟踪器名字
tracker='GT';
% 保存路径
savePath='./results/';
for vid = 1:numel(videos)
close all;
disp(videos{vid});
% 两个视频序列具有两个groundtruth
if (strcmp(videos{vid}, 'Jogging-1'))
video_path = [base_path '/' 'Jogging'];
[seq, ground_truth] = load_video_info(video_path,1);
elseif (strcmp(videos{vid}, 'Jogging-2'))
video_path = [base_path '/' 'Jogging'];
[seq, ground_truth] = load_video_info(video_path,2);
elseif (strcmp(videos{vid}, 'Skating2-1'))
video_path = [base_path '/' 'Skating2'];
[seq, ground_truth] = load_video_info(video_path,1);
elseif (strcmp(videos{vid}, 'Skating2-2'))
video_path = [base_path '/' 'Skating2'];
[seq, ground_truth] = load_video_info(video_path,2);
else
video_path = [base_path '/' videos{vid}];
[seq, ground_truth] = load_video_info(video_path,0);
end
% 四个视频并非从第一帧开始,最后一帧结束
seq.VidName = videos{vid};
st_frame = 1;
en_frame = seq.len;
if (strcmp(videos{vid}, 'David'))
st_frame = 300;
en_frame = 770;
elseif (strcmp(videos{vid}, 'Football1'))
st_frame = 1;
en_frame = 74;
elseif (strcmp(videos{vid}, 'Freeman3'))
st_frame = 1;
en_frame = 460;
elseif (strcmp(videos{vid}, 'Freeman4'))
st_frame = 1;
en_frame = 283;
end
seq.st_frame = st_frame;
seq.en_frame = en_frame;
% 帧数
num_frames=en_frame-st_frame+1;
% 预声明目标框
rect_position = zeros(num_frames, 4);
% 初始化目标框
rect_position(1,:)=ground_truth(1,:);
% 初始化时间
time = 0;
% 从第二帧开始检测
for frame=st_frame+1:en_frame
% 开始计时
tic();
% 跟踪代码,这里直接用groundtruth为例,从第二帧开始
rect_position(frame-st_frame+1,:)=ground_truth(frame-st_frame+1,:);
% 计算时间
time = time + toc();
end
% 原始数据集中,Tiger1的前5帧都是有遮挡的,所以需要直接去掉
if (strcmp(videos{vid}, 'Tiger1'))
rect_position=rect_position(6:en_frame,:);
st_frame1=st_frame+5;
num_frames=num_frames-5;
else
st_frame1=st_frame;
end
% save resutls.
fps = (en_frame-st_frame) / time;
results{1}.type = 'rect';
results{1}.res = rect_position;
results{1}.fps = fps;
results{1}.len = num_frames;
results{1}.annoBegin = st_frame;
results{1}.startFrame = st_frame1;
save([savePath videos{vid} '_' tracker '.mat'], 'results');
end
https://download.csdn.net/download/qq_17783559/11199984
说明:VOT数据集使用trax来运行跟踪代码,贼麻烦还总容易出错,这里使用matlab自己生成分析文件。
每帧有八个数据,分别表示目标框四边形的四个顶点如下图蓝色框所示:(x1,y1)、 (x2,y2)、(x3,y3)、(x4,y4)。
在我们跟踪过程中将其转化为黑色的矩形框表示为:(x,y,width, height) 。
默认vot-toolkit工具的实验,分为两个部分:
baseline实验是为了分析{'ar', 'expected_overlap', 'speed'}这三个指标。
unsupervised实验是为了分析{'overlap', 'speed'}这两个指标。
1)baseline参数详细解释
baseline.parameters.repetitions = 15;
对每个序列进行多次评估,以获得更好的统计性能。如果跟踪器连续产生两次相同的轨迹,则跟踪器被认为是确定性的,并且省略了进一步的迭代。此处设置重复运行15次,一般最后我们的结果会保存三次,都是一模一样的。
baseline.parameters.burnin = 10;
baseline.parameters.skip_initialize = 5;
baseline.parameters.failure_overlap = 0;
在VOT提出之前,比较流行的评价系统是让tracker在序列的第一帧进行初始化,之后让tracker一直跑到最后一帧。然而tracker可能会因为其中一两个因素导致其在开始的某些帧就跟丢(fail),所以最终评价系统只利用了序列的很小一部分,造成浪费。而VOT提出,评价系统应该在tracker跟丢的时候检测到错误(failure),并在failure发生的5帧之后对tracker重新初始化(reinitialize),这样可以充分利用数据集。之所以是5帧而不是立即初始化,是因为failure之后立即初始化很可能再次跟踪失败,又因为视频中的遮挡一般不会超过5帧,所以会有这样的设定。这是VOT的一个特色机制,即重启(reset/reinitialize)。但重启之后的一部分帧是不能用于评价的,这些帧被称作burn-in period,大量实验结果表明,burn-in period大约为初始化之后(包括第一帧的初始化和所有重启)的10帧。
这段原文:https://blog.csdn.net/Dr_destiny/article/details/80108255
所以这也能够解释baseline实验是监督属性的,因为我们需要已经知道了groundtruth的labels,我们才能够实施重启机制。当平均重叠度为零时,VOT重启机制开启,这是VOT作者给的检测重启示意图:
注意:原始工程的计算重叠度公式在\vot-toolkit-master\native\trax\src\region.c中,本文对其进行仿写。
2)unsupervised参数详细解释
无监督方式就是我们不知道groundtruth,所以通过第一帧给定的目标框跟踪就可以了。
此处以csr-dcf为例,也可以用其他的代码,按照格式稍微改一改就好了。csr-dcf代码的配置见博客:https://blog.csdn.net/qq_17783559/article/details/82025118
1)baseline实验代码:
细节介绍:通过compute_polygon_overlap函数计算跟踪结果与groundtruth的重叠度,如果重叠度为零,则重新初始化。这里的重叠度计算函数和vot-toolkit工具中的计算方法是一样的。
本来需要运行至少三次,因为三次的数据除了FPS都是一样的,为了简化我们只运行一次,第二第三次的数据是copy产生的。
%---------------------------------------------------------
% baseline 实验
%---------------------------------------------------------
startframe=1;
finishflag=0;
% 预声明目标框
rect_positionb = cell(num_frames,1);
rect_positionb{1}=1;
while(1)
% 初始化
tic();
% 读取第一帧
image = imread([sequence_path '/' img_files{startframe}]);
[w,h,~]=size(image);
% 读取groundtruth
region=ground_truth(startframe,:);
if numel(region) > 4
% all x,y points shifted by 1
region = region + 1;
else
% shift x,y by 1
region(1:2) = region(1:2) + 1;
end
% 初始化
[tracker, ~] = create_csr_tracker(image, region);
% 记录初始化时间
timeb(startframe,1:3) = toc();
% 从第二帧开始检测
for frame=startframe+1:num_frames
% 开始计时
tic();
% 跟踪代码,从第二帧开始
image = imread([sequence_path '/' img_files{frame}]);
[tracker, region] = track_csr_tracker(tracker, image);
% matlab indexing: starts with (1,1); gt starts with (0,0)
if numel(region) > 4
% all x,y points shifted by 1
region = region - 1;
else
% shift x,y by 1
region(1:2) = region(1:2) - 1;
end
% 计算时间
timeb(frame,1:3) = toc();
% 计算重叠度
OP=compute_polygon_overlap(ground_truth(frame,:),double(region),double([0,0,h,w]));
if OP==0
if num_frames-frame>4
rect_positionb{frame}=2;
zero4 = num2cell(zeros(4,1));
rect_positionb(frame+1:frame+4,1)=zero4;
timeb(frame+1:frame+4,1:3) = 0/0;% 生成Nan
rect_positionb{frame+5}=1;
startframe=frame+5;
break;
else
rect_positionb{frame}=2;
zeron = num2cell(zeros(num_frames-frame,1));
rect_positionb(frame+1:num_frames,1)=zeron;
timeb(frame+1:num_frames,1:3) = 0/0;% 生成Nan
finishflag=1;
break;
end
else
rect_positionb{frame}=double(region);
end
end
if (finishflag==1)||(frame==num_frames)
break;
end
end
% Save Data
baselinepath=[savePath trackerName '/baseline/' videos{vid}];
mkdir(baselinepath);
dlmwrite([baselinepath '/' videos{vid} '_001.txt'], rect_positionb{1},'newline','pc');
dlmwrite([baselinepath '/' videos{vid} '_002.txt'], rect_positionb{1},'newline','pc');
dlmwrite([baselinepath '/' videos{vid} '_003.txt'], rect_positionb{1},'newline','pc');
for fid=2:num_frames
dlmwrite([baselinepath '/' videos{vid} '_001.txt'], rect_positionb{fid},'-append','newline','pc');
dlmwrite([baselinepath '/' videos{vid} '_002.txt'], rect_positionb{fid},'-append','newline','pc');
dlmwrite([baselinepath '/' videos{vid} '_003.txt'], rect_positionb{fid},'-append','newline','pc');
end
dlmwrite([baselinepath '/' videos{vid} '_time.txt'], timeb,'newline','pc', 'precision',5);
2)unsupervised实验代码:
细节介绍:通过第一帧初始化,跟踪到最后一帧。
%---------------------------------------------------------
% unsupervised 实验
%---------------------------------------------------------
% 预声明目标框
rect_positionu = cell(num_frames,1);
rect_positionu{1}=1;
% 初始化
tic();
% 读取第一帧
image = imread([sequence_path '/' img_files{1}]);
% 读取groundtruth
region=ground_truth(1,:);
if numel(region) > 4
% all x,y points shifted by 1
region = region + 1;
else
% shift x,y by 1
region(1:2) = region(1:2) + 1;
end
% 初始化
[tracker, ~] = create_csr_tracker(image, region);
% 记录初始化时间
timeu(1) = toc();
% 从第二帧开始检测
for frame=2:num_frames
% 开始计时
tic();
% 跟踪代码,从第二帧开始
image = imread([sequence_path '/' img_files{frame}]);
[tracker, region] = track_csr_tracker(tracker, image);
% matlab indexing: starts with (1,1); gt starts with (0,0)
if numel(region) > 4
% all x,y points shifted by 1
region = region - 1;
else
% shift x,y by 1
region(1:2) = region(1:2) - 1;
end
% 计算时间
timeu(frame) = toc();
rect_positionu{frame}=double(region);
end
% Save Data
unsupervisedpath=[savePath trackerName '/unsupervised/' videos{vid}];
mkdir(unsupervisedpath);
dlmwrite([unsupervisedpath '/' videos{vid} '_001.txt'], rect_positionu{1},'newline','pc');
for fid=2:num_frames
dlmwrite([unsupervisedpath '/' videos{vid} '_001.txt'], rect_positionu{fid},'-append','newline','pc');
end
dlmwrite([unsupervisedpath '/' videos{vid} '_time.txt'], timeu,'newline','pc', 'precision',5);
完整工程见文末。
目标跟踪的每篇文章提出的算法都是在不同硬件条件平台上跑的,编程语言也不尽相同,那么该如何对这些算法的实时性进行客观评价?VOT采用的评价标准是:EFO。
EFO(Equivalent Filter Operations )是VOT2014提出来的一个衡量tracking速度的新单位,在利用vot-toolkit评价tracker之前,先会测量在一个600*600的灰度图像上用30*30最大值滤波器进行滤波的时间,以此得出一个基准单位,再以这个基础单位衡量tracker的速度,以此减少硬件平台和编程语言等外在因素对tracker速度的影响。
这段原文:https://blog.csdn.net/Dr_destiny/article/details/80108255。
运行代码tracker\benchmark_hardware.m会得到一个电脑的配置文件,生成路径:\vot-toolkit-master\cache\performance.txt。
为了得到更大的EFO,运行benchmark_hardware.m的时候记得把英雄联盟打开,嘿嘿嘿嘿嘿。
硬件参数如下:
csr-dcftest是通过上述代码运行的结果。
CSRDCF是通过vot-toolkit工具得到的结果。
ncc,ACT,CCOT是随便找的三个对比算法,这些结果可去官网下载:http://www.votchallenge.net/vot2016/results.html
结果存放路径:\vot-toolkit-master\reports\report_csr-dcftest\
1)overall数据结果
2)AR指标:
3)EAO指标:
4)无监督下overlap指标:
csr-dcftest与CSRDCF结果基本一致,有细微差距。我认为差距来源:原vot-toolkit工具计算overlap是用C++代码,本工程是在matlab中计算的,所以计算某一帧的计算结果可能不一样。FPS详细比较没有贴图,FPS有一定差距,还在可以接受的范围内。
https://download.csdn.net/download/qq_17783559/11215438