本文主要是面向使用C/C++设计跟踪器算法的同学,搭建VOT的测试环境,以及一部分使用的经验。
  VOT挑战赛是世界上公认的最权威的目标跟踪的比赛,赛事相关的论文奇数年会发在ICCV上,偶数年会发在ECCV上。在赛事的官网上能下载历年的比赛结果和数据集,VOT采用的算法性能评估工具是基于TraX协议,待评估的算法需要按照TraX的协议进行编写。

TraX协议

  参考Luka Čehovin 2014年的论文:TraX: Visual Tracking eXchange Protocol,里面比较详细地介绍了基于TraX协议测试跟踪器的方式。

  比较反直觉的是,我们自己写的跟踪器被称为“Server”,而给我们的跟踪器送图片的进程称为“Client”。Client会调用我们的跟踪器产生一个Seerver进程,两个进程之间按照一定的消息格式通信。

编译OpenCV

  TraX的编译是依赖OpenCV的,后面作为样例的跟踪器也需要OpenCV。虽然可以在网上找到别人编译好的OpenCV,但是难免会遇到和我们本地的编译器不兼容的情况。别人编译的库文件要是有问题,就会很头疼,所以最好的办法就是我们自己编译。
  我们自己编译还有一个好处就是编译得到的OpenCV包含OpenCVConfig.cmake和OpenCVConfig-version.cmake,在之后的要用到OpenCV的地方,只要在CMakeLists.txt里通过find_package就能找到OpenCV相关的路径。工程里不需要自己去设置include和lib文件的路径。
  首先在OpenCV的官网下载需要的源文件,并解压缩。

  我习惯的做法是,在解压后的目录下面新建一个“build”文件夹作为生成工程的路径。然后打开CMake GUI,选择源码的路径和输出工程的路径。依次点击Config、Generate和Open Project就行。BUILD下面可以选需要具体编译哪些库文件,有些不需要的可以不勾选,比如opencv_python我不打算用就不用勾。

  中间可能会遇到一些问题,比如下面这个Warning,可以通过去掉OPENCV_GENERATE_SETUPVARS这个选项的勾选来消除。

  还有可能因为一些网络问题下载不了一些文件,可以用一些科学上网的方法,去GitHub上手动下载。另外Python2.7也是需要安装的,OpenCV也会去找VTK,找BLAS,但是找不到也不重要,目前还没影响到我的使用,之后大不了在编译OpenCV之前先编译OpenBLAS和VTK,步骤是类似的。
  打开CMake生成的VS工程之后,选择Release版本。

  然后在Class View里面右键“INSTALL”,选择“Build”。

  INSTALL是依赖ALL_BUILD的,所以在选择编译INSTALL的时候,它会编译ALL_BUILD。编译INSTALL会把前面编译的结果安装到一个目录下面。这个目录是在CMake中确定的,在CMake GUI进行配置的时候,CMAKE_INSTALL_PREFIX指定了安装路径的前缀。

  编译完成之后,将bin路径放到PATH环境变量里即可。还可以添加一个“OpenCV_DIR”的环境变量,把OpenCVConfig.cmake所在的路径作为这个变量的值。这样在每次遇到需要OpenCV的CMake工程时,CMake就可以自动找到OpenCV。

编译TraX

  成功编译OpenCV后,编译TraX就没什么难度了。从GitHub上clone源码。然后用同样的方式通过CMake生成VS工程,编译并INSTALL之后得到下面这些文件:

  可以设置trax_DIR这个变量,变量的值是share文件夹的路径,比如我的就是“C:\Tools\TraX\share”。然后把bin目录设置到PATH环境变量里。

VOT Toolkit环境配置

  在使用最新的python版本的vot-toolkit之前,我还尝试折腾了一下旧版的Matlab版本的。但是我遇到了Matlab崩溃的问题,后来在GitHub上找到了和我遇到一样问题的人。大概是新版本的Matlab不兼容,所以作者转而开发了python版本的toolkit,确实更好用一些。

虚拟环境

  在安装vot-toolkit之前,建议先单独搞一个虚拟环境,这样可以起到一个隔离的作用,像Matlab版本升级之后就运行崩溃这样的问题就不会出现了。

1
py -0

  我在电脑上装了3.9和2.7版本的python,具体运行那个python可以靠python launcher进行选择。“py -0”命令可以显示当前系统中安装了那些版本的python。

  搭建虚拟环境我用的是python官方的venv模块,使用模块需要加上“-m”的选项。比如我想在当前路径下创建一个新的虚拟环境,可以用:

1
py -3.9 -m venv .

  如果是想在别的路径创建,就只要把“.”换成别的路径名就好了。

  刚创建虚拟环境的路径下面有一个Scripts文件夹,通过里面的activate.bat(cmd)或者Activate.ps1(PS)来激活虚拟环境。如果使用CMD,还是需要用Scripts目录下的deactivate.bat退出虚拟环境,而如果是PS,就只需要用deactivate命令就可以退出。
  后面就可以参考官方教程安装vot-toolkit。

初始化

  参考官方文档初始化workspace的时候,可能会遇到找不到stack的问题。提示“Experiment stack None not found”,这是因为pip下载安装的vot/stack路径下面缺少了stack的配置文件。

  找到GitHub的源码中的目录,可以发现上面是有这些配置文件的,只需要把这个目录下面的文件复制到vot/stack目录下就行了。
  下载数据集可能会比较慢,百度网盘,提取码:4id2。我下载了近几年的几个数据集放在了网盘上。在初始化的时候可以加上“–nodownload”选项,然后手动下载数据集,再把这些下载的数据放在workspace的sequence目录下面就行。

编译跟踪器

  在GitHub上还可以找到跟踪器的样例,在native目录下用和编译OpenCV和TraX同样的方式编译NCC跟踪器,得到一个ncc.exe可执行文件。
  GitHub上还可以找到KCF的源码,同样clone到本地之后,我们需要做一些修改。因为网上这个版本的KCF没有将TraX内嵌进来,我们需要做一些改动。
  打开CMakeLists.txt,主要是参考NCC,添加对TraX的include:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cmake_minimum_required(VERSION 3.3)
project(kcf)

find_package(OpenCV REQUIRED)

FIND_PACKAGE(trax REQUIRED COMPONENTS core)
LINK_DIRECTORIES(${TRAX_LIBRARY_DIRS})
LINK_LIBRARIES(${TRAX_LIBRARIES})
INCLUDE_DIRECTORIES(AFTER ${TRAX_INCLUDE_DIRS})

if(NOT WIN32)
ADD_DEFINITIONS("-std=c++0x -O3")
endif(NOT WIN32)

include_directories(src)
FILE(GLOB_RECURSE sourcefiles "src/*.cpp")
add_executable( KCF ${sourcefiles} )
target_link_libraries( KCF ${OpenCV_LIBS})

  然后把NCC源码里的vot.h也复制到KCF的src的路径下面。用CMake构建VS工程之后,打开runtracker.cpp,把main函数改成和NCC类似的格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include "kcftracker.hpp"
#include <dirent.h>
#include "vot.h"

int main(int argc, char* argv[]){

#if __USE_VOT

// Create KCFTracker object
KCFTracker tracker;
VOT vot;

cv::Rect initialization;
initialization << vot.region();
cv::Mat image = cv::imread(vot.frame());
tracker.init(initialization, image);

while (!vot.end()) {
string imagepath = vot.frame();
if (imagepath.empty()) break;
cv::Mat image = cv::imread(imagepath);
float confidence = 0.0;
cv::Rect rect = tracker.update(image);
vot.report(rect);
}
}

  编译的时候发现没有dirent.h这个头文件,需要在网上下载,参考这篇文章。编译完成之后也会得到一个KCF.exe的可执行文件。

结果分析

  参照官网的教程,进行测试之前需要写trackers.ini配置文件。目前我有NCC和KCF两个跟踪器。

1
2
3
4
5
6
7
8
9
10
11
12
13
# trackers.ini
[KCF] # <tracker-name>
label = KCF
protocol = trax
command = D:\Algorithm\Trackers\KCFCpp\build\Release\KCF.exe
# Additional environment paths
env_PATH = ${PATH}

[NCC]
label = NCC
protocol = trax
command = D:\Algorithm\Trackers\integration\native\build\Release\ncc.exe
env_PATH = ${PATH}

  只要之前把OpenCV和TraX的bin路径加入到了PATH环境变量里,这里的设置就没问题。可以用"vot test <tracker>"先进行测试。

  比如像这样,而且最后提示“Test concluded successfully”,那就是TraX通信没问题了。除非是跟踪器的跟踪代码有问题,后面在evaluate的时候会报错。

  在VOT的workspace目录下对两个跟踪器进行evaluate:

  再进行analysis,生成报告,报告会生成在workspace的analysis目录下,默认是html格式。

VOT实验

  我采用的stack是vot2019,主要分为三个实验。
  baseline是VOT的特色实验,就是在跟踪失败之后会再重新初始化跟踪。最早在VOT2015中提出,在跟踪连续5帧失败之后重新初始化,重新初始化后的前10帧忽略。
  realtime是在VOT2018中提出的,主要考察算法的实时性。vot-toolkit会给跟踪器以20fps的速度送图片,如果跟踪器没有及时给出结果,那么vot-toolkit就会拿上一次的结果作为新的结果,类似零阶保持。
  unsupervised就是没有监督,不管跟踪器有没有跟丢,toolkit不会去重新初始化跟踪器。所以只有一个AUC的测试指标。

Accuracy

  精度其实比较好理解,就是跟踪框和grandtruth的重合范围占比。值得注意的是,这里只有那些有效跟踪的图才加入计算。就比如重新初始化之后的前10帧是不算有效帧的。

Robustness

  稳定性是通过丢失帧的数量来衡量的,丢帧的数量越多,稳定性越差。在Visual object tracking performance measures revisited这篇论文里,为了把精度和稳定性一同直观地展示,对稳定性的衡量指标引入了一个指数函数:

eSF0N{e^{ - S{ { {F_0} } \over N} } }

  其中F0F_0是跟丢的次数,N是总的帧数。S是一个系数,这个系数的含义是这个跟踪器能连续稳定跟踪的帧数。这个计算结果就是这个跟踪器在连续跟踪S帧后,仍能稳定跟踪的概率。经过这样的计算,A和R就可以都统一到0~1的范围,然后像下面这样展示到一张图上,越靠近右上角的点表明跟踪器性能越好。

Expected Average Overlap

  现在VOT的排名主要看EAO的指标,EAO是结合了精度和稳定性的指标。EAO也是在VOT2015的时候提出来的,提出这个指标主要是因为考虑到数据集中不同的图像序列长度是不同的。

  在一个数据集中,统计不同长度的序列的个数,可以画出关于序列长度的一个概率密度函数。从中取50%的序列,让NloN_{lo}的序列的数量和NhiN_{hi}序列的数量相同。在NloN_{lo}NhiN_{hi}长度范围内的序列计算EAO。
  不同长度的序列可以计算一个跟踪的准确率,序列越长,准确率越低,也就有了一个EAO曲线,如上图的左上角。然后在NloN_{lo}NhiN_{hi}计算平均数即得到EAO的指标。

自定义设置

  如何自定义这个vot-toolkit?毕竟它是开源的,想怎么改都行。stack里的yaml文件是配置文件,以vot2019为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
title: VOT-ST2019 challenge
dataset: vot:vot-st2019
url: http://www.votchallenge.net/vot2019/
experiments:
baseline:
type: supervised
repetitions: 15
skip_initialize: 5
analyses:
- type: supervised_average_ar
sensitivity: 30
- type: supervised_eao_score
low: 46
high: 291
- type: supervised_eao_curve
realtime:
type: supervised
realtime:
grace: 3
repetitions: 1
skip_initialize: 5
analyses:
- type: supervised_average_ar
sensitivity: 30
- type: supervised_eao_score
low: 46
high: 291
- type: supervised_eao_curve
unsupervised:
type: unsupervised
repetitions: 1
analyses:
- type: average_accuracy

  python我用得不多,整个vot-toolkit的工作机制我还没太看懂。但是看这个配置文件,里面已经有很很多信息。里面列出了三个实验,每个实验的type是supervised,可以对应到analysis/supervised.py这个文件;sensitivity就是稳定性衡量指标中的SS;repetitions是实验的重复次数;skip_initialize是跳过初始化的帧数;grace是连续多少帧跟踪失败后判定为失败。
  除了改这里的配置,另外也可以改vot目录下的python脚本,当然也是得看懂之后才能改。