KCF目标跟踪方法分析与总结



correlation filter



Kernelized correlation filter



tracking



读"J. F. Henriques, R. Caseiro, P. Martins, J. Batista, 'High-speed tracking with kernelized correlation filters'" 笔记

KCF是一种鉴别式追踪方法,这类方法一般都是在追踪过程中训练一个目标检测器,使用目标检测器去检测下一帧预测位置是否是目标,然后再使用新检测结果去更新训练集进而更新目标检测器。而在训练目标检测器时一般选取目标区域为正样本,目标的周围区域为负样本,当然越靠近目标的区域为正样本的可能性越大。

注意论文中关于向量是行向量还是列向量总是指示不清楚,所以本文对变量符号统一之后进行推导,首先所有的小写字母均表示列向量,所有的大写字母表示矩阵,其中矩阵的每一行是一个样本,文中的函数除了

java kcf java kcf跟踪_java kcf

是对行向量操作,其余都是对元素操做的,四则运算符号也都是针对元素操作的。还有所有对循环矩阵使用傅里叶变换时使用的生成向量都是循环矩阵的第一行向量,这点很重要。

KCF的主要贡献

  • 使用目标周围区域的循环矩阵采集正负样本,利用脊回归训练目标检测器,并成功的利用循环矩阵在傅里叶空间可对角化的性质将矩阵的运算转化为向量的Hadamad积,即元素的点乘,大大降低了运算量,提高了运算速度,使算法满足实时性要求。
  • 将线性空间的脊回归通过核函数映射到非线性空间,在非线性空间通过求解一个对偶问题和某些常见的约束,同样的可以使用循环矩阵傅里叶空间对角化简化计算。
  • 给出了一种将多通道数据融入该算法的途径。

一维脊回归

脊回归

设训练样本集

java kcf java kcf跟踪_核函数_02

,那么其线性回归函数

java kcf java kcf跟踪_转置_03

,

java kcf java kcf跟踪_转置_04

是列向量表示权重系数,可通过最小二乘法求解

java kcf java kcf跟踪_转置_05

其中

java kcf java kcf跟踪_循环矩阵_06

用于控制系统的结构复杂性,也就是VC维以保证分类器的泛化性能。

写成矩阵形式

java kcf java kcf跟踪_循环矩阵_07

其中

java kcf java kcf跟踪_循环矩阵_08

的每一行表示一个向量,

java kcf java kcf跟踪_循环矩阵_09

是列向量,每个元素对应一个样本的标签,于是令导数为0,可求得

java kcf java kcf跟踪_循环矩阵_10


因为后面实在傅里叶域内计算,牵涉到复数矩阵,所以我们将结果都统一写成复数域中形式


java kcf java kcf跟踪_java kcf_11

其中

java kcf java kcf跟踪_循环矩阵_12

表示复共轭转置矩阵。

循环矩阵
KCF中所有的训练样本是由目标样本循环位移得到的,向量的循环可有排列矩阵得到,比如


java kcf java kcf跟踪_循环矩阵_13


java kcf java kcf跟踪_核函数_14


java kcf java kcf跟踪_循环矩阵_15


当然对于二维图像的话,可以通过x轴和y轴分别循环移动实现不同位置的移动


java kcf java kcf跟踪_核函数_16


举例


java kcf java kcf跟踪_核函数_17


1474942884758.jpg


java kcf java kcf跟踪_转置_18


1474942898329.jpg

所以由一个向量

java kcf java kcf跟踪_转置_19

可以通过不断的乘上排列矩阵得到n个循环移位向量,将这n个向量依序排列到一个矩阵中,就形成了x生成的循环矩阵,表示成

java kcf java kcf跟踪_循环矩阵_20


java kcf java kcf跟踪_循环矩阵_21


1D向量得到的循环矩阵.jpg


java kcf java kcf跟踪_核函数_22


2D图像不同循环次数后的移位.jpg


循环矩阵傅氏空间对角化
所有的循环矩阵都能够在傅氏空间中使用离散傅里叶矩阵进行对角化


java kcf java kcf跟踪_转置_23

其中x对应于生成X的向量(就是X的第一行矩阵)的傅里叶变化后的值,

java kcf java kcf跟踪_java kcf_24

,

java kcf java kcf跟踪_循环矩阵_25

是离散傅里叶矩阵,是常量

java kcf java kcf跟踪_java kcf_26


关于矩阵的傅里叶对角化请参加 循环矩阵傅里叶对角化,后面的笔记会专门讲解傅里叶变换。

傅氏对角化简化的脊回归


java kcf java kcf跟踪_java kcf_27

带入脊回归公式得到

java kcf java kcf跟踪_循环矩阵_28

注意这里的分号是点除运算,就是对应元素相除。因为

java kcf java kcf跟踪_循环矩阵_29

,( 循环矩阵傅里叶对角化)对上式两边同时傅氏变换得

java kcf java kcf跟踪_循环矩阵_30


于是


java kcf java kcf跟踪_转置_31


这里和论文式(12)不一样,论文里(12)式分子上似乎多了个共轭符号,因为Appendix A.5中的式(55)后面那个

java kcf java kcf跟踪_核函数_32

应该是少了个共轭转置符号。

这样就可以使用向量的点积运算取代矩阵运算,特别是求逆运算,大大提高了计算速度。


java kcf java kcf跟踪_java kcf_33


核空间的脊回归

我们希望找到一个非线性映射函数

java kcf java kcf跟踪_核函数_34

列向量,使映射后的样本在新空间中线性可分,那么在新空间中就可以使用脊回归来寻找一个分类器

java kcf java kcf跟踪_核函数_35

,所以这时候得到的权重系数为

java kcf java kcf跟踪_核函数_36


java kcf java kcf跟踪_java kcf_37


java kcf java kcf跟踪_java kcf_38

行向量张成的空间中的一个向量,所以可以令

java kcf java kcf跟踪_循环矩阵_39


上式就变为

java kcf java kcf跟踪_循环矩阵_40

该问题称为

java kcf java kcf跟踪_核函数_41

的对偶问题

令关于列向量

java kcf java kcf跟踪_转置_42

导数为0,

java kcf java kcf跟踪_循环矩阵_43

注:

java kcf java kcf跟踪_java kcf_44

其实类似于核空间变量的协方差矩阵,矩阵的转置乘以矩阵,一定可逆。对于核方法,我们一般不知道非线性映射函数

java kcf java kcf跟踪_循环矩阵_45

的具体形式,而只是刻画在核空间的核矩阵

java kcf java kcf跟踪_循环矩阵_46

,那么我们令

java kcf java kcf跟踪_转置_47

表示核空间的核矩阵,由核函数得到,那么

java kcf java kcf跟踪_java kcf_48


于是

java kcf java kcf跟踪_核函数_49

java kcf java kcf跟踪_转置_50

论文提出的一个创新点就是使循环矩阵的傅氏对角化简化计算,所以这里如果希望计算

java kcf java kcf跟踪_循环矩阵_51

时可以同样将矩阵求逆运算变为元素运算,就希望将

java kcf java kcf跟踪_转置_52

对角化,所以希望找到一个核函数使对应的核矩阵式循环矩阵。

Theorem 1. Given circulant data C(x), the corresponding kernel matrix K is circulatant if the kernel function satisfies

java kcf java kcf跟踪_java kcf_53

,for any permutation matrix M.


即核矩阵是循环矩阵应该满足两个条件:第一个样本和第二个样本都是由生成样本循环移位产生的,可以不是由同一个样本生成;满足

java kcf java kcf跟踪_循环矩阵_54

,其中

java kcf java kcf跟踪_核函数_55

是排列矩阵。

证明:设

java kcf java kcf跟踪_核函数_56

,则

java kcf java kcf跟踪_转置_57

,于是

java kcf java kcf跟踪_java kcf_58

因为K的第一行为

java kcf java kcf跟踪_转置_59

所以

java kcf java kcf跟踪_java kcf_60

相当于将第一行的第

java kcf java kcf跟踪_核函数_61

个元素放到K的第i行j列上,

那么

java kcf java kcf跟踪_java kcf_62

就得到了循环矩阵,所以

java kcf java kcf跟踪_转置_63

是循环矩阵。证明里

java kcf java kcf跟踪_循环矩阵_64

表示除

java kcf java kcf跟踪_核函数_65

的余数,因为这个过程是循环的。

证毕。

若K是循环矩阵,则


java kcf java kcf跟踪_转置_66

其中

java kcf java kcf跟踪_java kcf_67

是K中第一行。这里觉得奇怪?两个转置?这是因为我们已经约定

java kcf java kcf跟踪_java kcf_68

是列向量,而

java kcf java kcf跟踪_转置_69

的第i行是

java kcf java kcf跟踪_转置_70

,是不是明白了~

这里推出来的公式和论文中公式(17)也不大一样

那么那些核函数满足上述性质呢?论文中给出

  • Radial Basis Function kernels -e.g. Gaussian
  • Dot-Product kernels -e.g. linear, polynomial
  • Additive kernels - e.g. intersection,
  • java kcf java kcf跟踪_java kcf_71

  • Exponentiated additive kernels.

快速检测

首先由训练样本和标签训练检测器,其中训练集是由目标区域和由其移位得到的若干样本组成,对应的标签是根据距离越近正样本可能性越大的准则赋值的,然后可以得到

java kcf java kcf跟踪_转置_72

待分类样本集,即待检测样本集,是由预测区域和由其移位得到的样本集合

java kcf java kcf跟踪_java kcf_73


那么就可以选择

java kcf java kcf跟踪_核函数_74

最大的样本作为检测出的新目标区域,由

java kcf java kcf跟踪_转置_75

判断目标移动的位置。定义

java kcf java kcf跟踪_java kcf_76

是测试样本和训练样本间在核空间的核矩阵

java kcf java kcf跟踪_转置_77


由于核矩阵满足

java kcf java kcf跟踪_循环矩阵_78

,即

java kcf java kcf跟踪_转置_79

类似于theorem 1 的证明可得

java kcf java kcf跟踪_转置_80

是循环矩阵我记得曾经见到过有人问

java kcf java kcf跟踪_循环矩阵_81

非方阵的情况,假设采样窗口非方形,即

java kcf java kcf跟踪_循环矩阵_82

那么采样窗口通过移位都会产生

java kcf java kcf跟踪_java kcf_83

个样本,无论是训练样本还是测试样本,所以

java kcf java kcf跟踪_循环矩阵_84

一定是方阵

于是得到各个测试样本的响应


java kcf java kcf跟踪_转置_85

注意我们说过小写的都是列向量,

java kcf java kcf跟踪_java kcf_86

是列向量。注意我们这里

java kcf java kcf跟踪_转置_87

是矩阵

java kcf java kcf跟踪_循环矩阵_88

的第一行,即

java kcf java kcf跟踪_java kcf_89

的第一列,而文中(22)式中

java kcf java kcf跟踪_核函数_90

是论文中

java kcf java kcf跟踪_转置_91

的第一行,这是因为本文和论文中关于

java kcf java kcf跟踪_核函数_92

的定义正好是相转置的。也就是说我觉得(22)式只是少了一个共轭。。。

觉得蛮奇怪的,怎么和论文中推导结果好多都差一个共轭符号??

这是因为

java kcf java kcf跟踪_循环矩阵_93

都是对称向量,而对称向量的共轭转置是实数,所以就和论文中一样了,这点参考KCF高速跟踪详解

核矩阵的快速计算

现在还存在的矩阵运算就是核矩阵的第一行的计算

java kcf java kcf跟踪_java kcf_94

内积和多项式核

这种核函数核矩阵可以表示成

java kcf java kcf跟踪_核函数_95

,于是

java kcf java kcf跟踪_转置_96

因此对于多项式核

java kcf java kcf跟踪_java kcf_97


java kcf java kcf跟踪_java kcf_98

径向基核函数

比如高斯核,这类函数是

java kcf java kcf跟踪_转置_99

的函数

java kcf java kcf跟踪_循环矩阵_100


所以


java kcf java kcf跟踪_转置_101


对于高斯核则有


java kcf java kcf跟踪_转置_102


1D到2D

上面公式推导的很爽,可是都是在1D情况下得到了结论,2D图像该怎么办呢?

这个问题困扰了我好久。。。。刚开始我也想从线性空间的脊回归推导,假设

java kcf java kcf跟踪_核函数_103

是目标图像,

java kcf java kcf跟踪_转置_104

是由

java kcf java kcf跟踪_转置_105

生成的循环矩阵块,即

java kcf java kcf跟踪_java kcf_106

表示

java kcf java kcf跟踪_核函数_107

的第

java kcf java kcf跟踪_java kcf_108

块,是由

java kcf java kcf跟踪_核函数_109

右移

java kcf java kcf跟踪_java kcf_110

,下移

java kcf java kcf跟踪_循环矩阵_111

得到的样本块。那么即使块循环矩阵能够通过2D傅里叶变换矩阵对角化又怎么用呢??因为我们不可能带入

java kcf java kcf跟踪_核函数_112

类似的式子中啊(这个式子是类比于1D脊回归写的,并无实际意义)

哎呀,想破脑袋啊!

啊哈,想明白了,线性假设下没办法用,直接在核空间推导,发现豁然开朗~

现在有一个函数

java kcf java kcf跟踪_java kcf_113

,自变量

java kcf java kcf跟踪_核函数_114

,因变量

java kcf java kcf跟踪_循环矩阵_115

,也不知道怎么映射的,也不知道

java kcf java kcf跟踪_循环矩阵_116

是多少,反正是个确定但未知的值。那么在核空间我们就可以使用脊回归的公式了~

java kcf java kcf跟踪_核函数_117

注意:由

java kcf java kcf跟踪_java kcf_118

移位生成的样本共有

java kcf java kcf跟踪_核函数_119

个,所以

java kcf java kcf跟踪_java kcf_120

,这里

java kcf java kcf跟踪_java kcf_121

,

java kcf java kcf跟踪_循环矩阵_122

是对应样本的标签,

java kcf java kcf跟踪_核函数_123

是对应样本标签的矩阵形式。

ok,现在再来看看定理2

Theorem 2. The block matrix

java kcf java kcf跟踪_循环矩阵_124

with elements

java kcf java kcf跟踪_核函数_125

is a Block-Circulant Matrix (BCCM) if

java kcf java kcf跟踪_循环矩阵_126

is a unitarily invariant kernel.


这里和Theorem 1是类似的,a unitarily invariant kernel就是说

java kcf java kcf跟踪_java kcf_127

,定理的证明参见Theorem 1.

而径向基核,dot-product kernel等都满足这个条件,所以得到的核矩阵都是块循环矩阵。

块循环矩阵可以使用2D傅里叶变换矩阵对角化( 循环矩阵傅里叶对角化


java kcf java kcf跟踪_转置_128

其中

java kcf java kcf跟踪_java kcf_129

是2D傅里叶变换矩阵,

java kcf java kcf跟踪_java kcf_130

是生成块循环矩阵

java kcf java kcf跟踪_循环矩阵_131

的生成矩阵,

java kcf java kcf跟踪_核函数_132

表示对

java kcf java kcf跟踪_循环矩阵_133

进行2D傅里叶变换的结果。

ok,那现在


java kcf java kcf跟踪_核函数_134

其中

java kcf java kcf跟踪_java kcf_135

表示全1的m维列向量。

java kcf java kcf跟踪_核函数_136

这里的

java kcf java kcf跟踪_java kcf_137

分别对应着

java kcf java kcf跟踪_java kcf_138

的矩阵形式。

对应的响应


java kcf java kcf跟踪_核函数_139

其中

java kcf java kcf跟踪_转置_140

表示块循环矩阵

java kcf java kcf跟踪_核函数_141

的生成矩阵。

后面测试就类似于1D不推了

多通道问题

论文中在提取目标区域的特征时可以是灰度特征,但是使用Hog特征能够取得更好的效果,那么Hog特征该如何加入前面提到的模型呢?

Hog特征是将图像划分成较小的局部块,称为cell,在cell里提取梯度信息,绘制梯度方向直方图,然后为了减小光照影响,将几个cell的方向直方图串在一起进行block归一化,最终将所有的cell直方图串联起来就是图像的特征啦。

那么,按照传统的方式一张图像就提取出一个向量,但是这个向量怎么用啊?我们又不能通过该向量的移位来获得采样样本,因为,你想啊,把直方图的一个bin循环移位有什么意义啊?

所以论文中Hog特征的提取是将sample区域划分成若干的区域,然后再每个区域提取特征,代码中是在每个区域提取了32维特征,即

java kcf java kcf跟踪_java kcf_142

,其中

java kcf java kcf跟踪_循环矩阵_143

就是梯度方向划分的bin个数,每个方向提取了3个特征,2个是对方向bin敏感的,1个是不敏感的,另外4个特征是关于表观纹理的特征还有一个是零,表示阶段特征,具体参见fhog。提取了31个特征(最后一个0不考虑)之后,不是串联起来,而是将每个cell的特征并起来,那么一幅图像得到的结果就是一个立体块,假设划分cell的结果是

java kcf java kcf跟踪_循环矩阵_144

,那么fhog提取结果就是

java kcf java kcf跟踪_核函数_145

,我们成31这个方向为通道。那么就可以通过cell的位移来获得样本,这样对应的就是每一通道对应位置的移位,所有样本的第i通道都是有生成图像的第i通道移位获得的,

,所以分开在每一个通道上计算,就可以利用循环矩阵的性质了。我们来看1D的情况,1D弄明白了,2D也就明白咯,因为我们上面说了怎么推导2D的

样本cell数为M,每个cell特征维数为L,第

java kcf java kcf跟踪_java kcf_146

个样本的第

java kcf java kcf跟踪_循环矩阵_147

通道向量表示成

java kcf java kcf跟踪_转置_148

,样本的总特征可以表示成

java kcf java kcf跟踪_转置_149

.

java kcf java kcf跟踪_转置_150


于是K矩阵的第一行有


java kcf java kcf跟踪_核函数_151

这里用到

java kcf java kcf跟踪_转置_152

这是dot product kernel的情况,那径向基核就很容易推了


java kcf java kcf跟踪_核函数_153


java kcf java kcf跟踪_核函数_154


多通道的处理.jpg


总结

KCF相对于其他的tracking-by-detection方法速度得到了极大的提升,效果也相对较好,思想和实现十分简单。


java kcf java kcf跟踪_转置_155


KCF目标检测.jpg


借上图来总结下KCF的过程,左图是刚开始我们使用红色虚线框框定了目标,然后红色实线框就是使用的padding了,其他的框就是将padding循环移位之后对齐目标得到的样本,由这些样本就可以训练出一个分类器,当分类器设计好之后,来到了下一帧图像,也就是右图,这时候我们首先在预测区域也就是红色实线框区域采样,然后对该采样进行循环移位,对齐目标后就像图中显示的那个样子 了,(这是为了理解,实际中不用对齐。。。),就是周围那些框框啦,使用分类器对这些框框计算响应,显然这时候白色框响应最大,因为他和之前一帧红色框一样,那我们通过白色框的相对移位就能推测目标的位移了。

然后继续,再训练再检测。。。。

论文中还说到几点

  1. 对特征图像进行cosine window加权,这主要是为了减轻由于边界移位导致图像不光滑。
  2. padding的size是目标框的2.5倍,肯定要使用padding窗口,要不然移位一次目标就被分解重组合了。。。效果能好哪去。。
  3. 对于标签使用了高斯加权
  4. java kcf java kcf跟踪_转置_156

  5. 前后帧结果进行了线性插值,为了让他长记性,不至于模型剧烈变化。

但是其缺点也是很明显的。

  1. 依赖循环矩阵,对于多尺度的目标跟踪效果并不理想。当然可以通过设置多个size,在每个size上进行KCF运算,但这样的话很难确定应预先设置多少size,什么样的size,而且对size的遍历必将影响算法的速度。KCF最大的优势就是速度。

我在想能不能通过少量特征点的匹配来调整窗口的size,当然这样的话,速度也是个问题。


java kcf java kcf跟踪_核函数_157


1475242117128.jpg


这种情况下还能保证最大响应就对应着目标中心所在的框吗?如果不能偏差会不会越来越大?

  1. 初始化矩阵不能自适应改变,其实这个问题和上一个缺点类似,这里强调的是非刚体运动,比如跳水运动员,刚开始选定区域肯定是个瘦长的矩形框,但当运动员开始屈体的时候显然这个预选定框就很大误差了。


java kcf java kcf跟踪_循环矩阵_158


1475242288757.jpg


3.难处理高速运动的目标

  1. 难处理低帧率中目标,这个和3类似,都是说相邻帧间目标位移过大。


java kcf java kcf跟踪_核函数_159


1475242373962.jpg


目标下一帧出现位置不在你的padding内,你怎么也不可能移位找到。。。

5.虽然算法中对模型系数

java kcf java kcf跟踪_循环矩阵_160

进行线性插值,但是对于目标一旦被遮挡若干帧之后,可能模型就再也回不去了。。。因为模型已经完全被遮挡物污染掉了。

6.我觉的论文还有一个问题就是仅仅通过检测到的框中心和目标实际中心的距离来度量性能,这是有问题的。
比如我现在有一个人垂直我的镜头逐渐远去了,但他的中心一直在我镜头的中心处,那我就开始画个框就是镜头的视角范围,那这样我检测结果百分之百,可是有什么用呢。。。。当然论文方法是在很多不同数据集上检验的性能还是很有说服力的。我的意思就是对于单个数据集不能仅凭这个指标定方法的好坏。