单目标跟踪--KCF算法(核化相关滤波算法)Python实现(超详细)

Posted Absurd_LS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单目标跟踪--KCF算法(核化相关滤波算法)Python实现(超详细)相关的知识,希望对你有一定的参考价值。

Tracking-KCF Algorithm

注:本文涉及的算法的代码实践已上传至GitHub,恳求大佬们指点!^ _ ^

1. 目标检测跟踪与算法背景概述

​ 目标跟踪任务在许多的计算机视觉系统中都是极为关键的一个组成部分。对于任意给定的一个初始图像的Patch(Filter滑过的区域),目标跟踪任务的目的在于训练一个分类器来将待跟踪的目标与它所处的环境区分开,为了能够在后续帧中能继续检测到这个目标,分类去需要能够在很多位置上都能进行详尽的评估,同时在滑动的过程中都会提供一个新的图像Patch来帮助提升模型的性能。

​ 在上述任务中,我们将感兴趣的对象——即待追踪的目标称作正样本(positive samples),将目标所在的环境或者背景称作负样本。一幅图像中包含的负样本数量几乎是无限的,在达到合并尽可能多的样本保持较低的计算量之间的平衡上,前人作出了很多尝试。KCF算法中,引入了轮转矩阵(circulant matrices)这一工具来合并大量的样本,实现了一个基于“核岭回归”的跟踪器(tracer),该跟踪器可以认为是一个核化版的线性相关滤波器(Linear Correlation Filter )。

​ Correlation Filter(CF)源于信号处理领域,其用于tracking方面的想法是:相关是衡量两个信号相似值的度量,如果两个信号越相似,那么其相关值就越高。在tracking的应用里,设计一个滤波模板,利用该模板与目标候选区域做相关运算,最大输出响应的位置即为当前帧的目标位置。

​ 用数学语言来表述, x x x表示一幅图像, w \\mathcalw w表示相应的滤波模板, y y y表示模板与相关候选区域进行相关运算后的相应输出,则有如下关系: y = x ⊗ w y=x\\otimes\\mathcalw y=xw,为减小计算量,可将 x , y , w x,y,\\mathcalw x,y,w分别转换到其傅里叶空间后计算点积,即 y ^ = x ^ ⋅ w ^ ∗ \\haty = \\hatx· \\hat\\mathcalw^* y^=x^w^。相关滤波的任务则是寻找最优的滤波模板 w \\mathcalw w

​ 目下以相关滤波类的方法和深度学习方法为代表的判别类模型方法效果普遍好于生成模型,其显著特点是分类器的训练过程中运用到了前景与背景信息,分类器的任务专注于区分前景与背景。Kernelized Correlation Filter(KCF)是相关滤波方法中的典型算法,该方法的一般流程是:在跟踪的过程中训练一个目标检测器,使用目标检测器去检测下一帧预测位置是否是目标,然后再使用新检测结果去更新训练集进而更新目标检测器。

2. HOG特征

​ KCF算法中使用了图像的HOG特征替代了传统跟踪器所用的灰度特征。

​ HOG特征全称为Histogram of Oriented Gradients,即方向梯度直方图。作为一种图像的特征描述子(图像的一种表示,通过提取有用的信息并扔掉多余的信息来简化图像),HOG特征将一张大小为 w i d t h × h e i g h t × c h a n n e l s width \\times height \\times channels width×height×channels的图像转化为一个长度为 n n n的特征向量,例如输入图像大小为 64 × 128 × 3 64 \\times 128 \\times 3 64×128×3,HOG特征的输出为长度 3780 3780 3780的向量。HOG特征的计算过程如下:

(1)图像预处理

​ 最早提出的HOG特征通过在一张 64 × 128 64 \\times 128 64×128的图像上计算得到,预处理的操作要求图片保持1:2的横纵比,原文中提及的 γ \\gamma γ矫正已知其增益效果较小,不再考虑。

(2)计算梯度图

​ 首先计算图像的水平方向梯度 g x g_x gx和竖直方向的梯度 g y g_y gy,以如下公式来计算梯度的强度值 g g g和梯度方向 θ \\theta θ
g = g x 2 + g y 2 θ = a r c t a n g x g y g=\\sqrtg_x^2+g_y^2\\\\ \\theta = arctan \\fracg_xg_y g=gx2+gy2 θ=arctangygx
​ 同时梯度方向有如下的性质: θ ∈ [ 0 , π ] \\theta \\in [0,\\pi] θ[0,π]

(3)计算梯度直方图

​ 这一步中,首先将图像分割成多个 8 × 8 8 \\times 8 8×8的cell,在这些cell中计算梯度直方图。(2)中计算的每个像素点的位置处包含了2个值: g 和 θ g和\\theta gθ,一个cell就保存了128个值,单个像素的梯度信息往往包含了噪声,采用 8 × 8 8 \\times 8 8×8的图片块表示后能够是的直方图对噪声不敏感。

​ 由(2)的性质,将0-180度分成9个区间:0,20,40,…160,之后统计每个像素点所在的区间——将这个区间命名为bin,采取的原则是对每个像素点处的 g g g值,按 θ \\theta θ的比例将 g g g分配给相邻的bin,如下图所示。

​ 最终统计得到如下图所示的直方图:

(4)对 16 × 16 16 \\times 16 16×16大小的Block进行标准化

​ 标准化(Normalization)也称归一化,即将每个向量的分量除以向量的模长。Block选取示意图如下:

(5)得到HOG向量

​ 将(4)中计算的单个Block的向量连接起来得到整个图片块的最终的特征向量,其中可以由这样的认识:每个16×16块由36×1向量表示。

​ OpenCV中封装了提取HOG特征的类HOGDescriptor,实现过程中只需构造一个hog对象来实现,见于HOG.py文件中的构造方法:

    def __init__(self, winSize):
        self.winSize = winSize
        self.blockSize = (8, 8)
        self.blockStride = (4, 4)
        self.cellSize = (4, 4)
        self.nbins = 9
        self.hog = cv2.HOGDescriptor(winSize,self.blockSize, self.blockStride,self.cellSize, self.nbins)

3. 傅里叶变换

3.1 傅里叶变换概念简述

傅里叶变换(Fourier transform,FT)是一种线性积分变换,用于函数(应用上称作“信号”)在时域和频域之间的变换,在物理学和工程学中有许多应用,其作用是将函数分解为不同特征的正弦函数的和,如同化学分析来分析一个化合物的元素成分。对于一个函数,也可对其进行分析,来确定组成它的基本(正弦函数)成分。

​ 经过傅里叶变换生成的函数 f ^ \\hat f f^称作原函数 f f f的傅里叶变换,应用意义上称作频谱。在特定情况下,傅里叶变换是可逆的,即将 f ^ \\hatf f^通过逆变换可以得到其原函数 f f f。通常情况下, f f f是一个实函数,而 f ^ \\hatf f^ 则是一个复数值函数,其函数值作为复数可同时表示振幅和相位。高斯函数是傅里叶变换的本征函数(也称固有函数,即对已定义的函数空间中任意一个非零函数 f f f 进行变换仍然是函数 f f f或者其标量倍数的函数。更加精确的描述就是 A f = λ f \\mathcalAf = \\lambda f Af=λf其中 λ \\lambda λ是标量,它是对应的特征值),即若一个函数(或分布)在真实空间中是一个高斯函数,则在傅里叶空间中它还是一个高斯函数,如下图所示:

​ 维基百科中对连续可积函数 f f f的傅里叶变换给出的定义形式如下:
f ^ ( ξ ) = ∫ − ∞ ∞ f ( x ) e − 2 π i x ξ d x , ξ 为 定 义 在 频 域 上 的 任 意 实 数 \\hatf(\\xi)=\\int _-\\infty^\\inftyf(x)e^-2 \\pi ix\\xidx, \\xi为定义在频域上的任意实数 f^(ξ)=f(x)e2πixξdxξ
​ 同时在适当的条件下, f ^ \\hatf f^的逆傅里叶变换可得到 f f f
f ( x ) = ∫ − ∞ ∞ f ^ ( ξ ) e − 2 π i x ξ d ξ , x 为 定 义 在 时 域 上 的 任 意 实 数 f(x)=\\int _-\\infty^\\infty\\hatf(\\xi)e^-2 \\pi ix\\xid\\xi, x为定义在时域上的任意实数 f(x)=f^(ξ)e2πixξdξx

3.2 傅氏空间与离散傅里叶矩阵

​ 傅里叶变换的奇妙之处就在于,将真实空间中复杂的波形通过“分解”之后可以得到若干简单的正弦波,这个“分解”操作是为傅里叶变换,从而“傅里叶空间”也可理解为“频率空间”,如下图所示:

离散傅里叶变换矩阵则是将离散傅里叶变换以矩阵乘法来表示的一种表达形式,其一般形式为:
F = 1 n [ 1 1 . . . 1 1 1 w . . . w n − 2 w n − 1 1 w 2 . . . w 2 ( n − 2 ) w 2 ( n − 1 ) . . . . . . . . . . . . . . . 1 w n − 1 . . . w ( n − 1 ) ( n − 2 ) w ( n − 1 ) 2 ] F=\\frac1\\sqrtn\\beginbmatrix 1&1&...&1&1\\\\ 1&\\mathcalw&...&\\mathcalw^n-2&\\mathcalw^n-1\\\\ 1&\\mathcalw^2&...&\\mathcalw^2(n-2)&\\mathcalw^2(n-1)\\\\ ...&...&...&...&...&\\\\ \\\\ 1&\\mathcalw^n-1&...&\\mathcalw^(n-1)(n-2)&\\mathcalw^(n-1)^2\\endbmatrix F=n 以上是关于单目标跟踪--KCF算法(核化相关滤波算法)Python实现(超详细)的主要内容,如果未能解决你的问题,请参考以下文章

相关滤波的历史及发展

目标跟踪算法----KCF进阶(基于KCF改进的算法总结)

目标跟踪检测算法(一)——传统方法

软件课设第七天 8.25

目标跟踪的深度学习方法与opencv下的KCF方法

Opencv人数统计 yolo kcf人头跟踪 人数统计 KCF目标跟踪 YOLO目标跟踪