KCF目标跟踪算法

KCF目标跟踪算法,第1张

最近刚开始学习単目标跟踪,最近想搞明白KCF的思想,看了一个星期的公式推导,要看哭了!!!!把自己现在已经知道的一滚宏些结论写下来理理思路。欢迎指正。

先说一下它的优点吧:

1.通过图片的矩阵循环,增加了训练样本,提高了正确率。

2.进行傅里叶变换,避免矩阵求逆 *** 作,计算更快速。

3.使用高斯label,更合理。

现在来梳理一下它整个计算的流程:

1.目标函数:

我们的目标是最小化我们的采样数据xi的计算标签f(xi)与下一帧真实目标位置的真实标签yi(回归目标)的距离。(这个应该不难理解吧,我计算出来的标签越像真实标签,说明我找到的下一帧得得位置离它真实位置越近)

这个表示的形式为脊回归,下面的部分求解过程,可以参考SVM的求解过程。虽然不是一摸一样的形式,但是帮助理解本篇文章中的求解方式是非常有用的(“ 支持向量机通俗导论(理解SVM的三层境界)LaTex最新版_2015.1.9.pdf ”这篇文章中关于表达式的意思和求解写的很清楚)

在线性问题中:

在求解这里的最小值的时候,将f(xi)根据公式(1)换成矩阵形式Wt*X(为什么可以转换成这种形式参考SVM),X的每一行表示一个采样结果的xi,X是经过第一行的xi不断循环得到的一个矩阵,Wt表示W的转置。y表示yi组成的向量。然后计算公式(2)对W的求导等于0可以得到:

(4)式即将(3)式中的转置转换成了共轭,只要是考虑在下面的傅里叶转换中有负数的出现。

这里我们看到在求w得最小值的时候有矩阵求逆的 *** 作,这使得计算量比较大。然而根据之前说的X是一个循环矩阵,形式为:

将矩阵进行傅立叶变换后,循环矩阵有一个性质:

即一个循环矩阵可以用它的第一行的向量进行傅里叶变换之后表示,x带一个帽子表示对向量x进行了傅里叶变换。傅里叶变换的具体理解可以参考: 此篇傅里叶博客

对于如何进行傅里叶转换可以参考: 傅里叶转换方法

然后就可以发现一个循环矩阵可以转换成用一个向量来表示。将(6)式带入(4)式化简:

w戴帽子的意思就是进行了傅里叶转换,这样就从大旁册一个矩阵的运算换到了向量的运算。减少了求逆的 *** 作。

当然在大多数情况下我们解决的是非线性问题 :

那我们就引进了高维求解和 核函数的概念(仔细的求解参考上文提到的SVM文章)。

在高维空间中非线性问题w可以变成一个线性问题。

fai(xi)表示将x映射到高位空间的函数启哗。

那我们的目标函数就可以表示成

其中k表示核函数它的定义运算如下:

由(8)可见之前求最小w的问题转换成了求最小阿尔法的问题。将(8)带入(2)阿尔法的求解参考一篇文章“ R. Rifkin, G. Yeo, and T. Poggio, “Regularized least-squares classification,Nato Science Series Sub Series III Computer and Systems Sciences, vol. 190, pp. 131–154, 2003.”

最后可以解得

进行傅里叶变换:

这里Kxx代表K矩阵的第一行元素的傅里叶变换。K也是一个循环矩阵可证,此处省略具体方式可参考 “High-Speed Tracking with Kernelized Correlation Filters João F. Henriques, Rui Caseiro, Pedro Martins, and Jorge Batista”的5.2节。

这样(8)式可以表示成:

Kz是所有训练样本和候补patch之间的核矩阵

现在就剩讨论一下k的形式,如果k是线性核的话就可以转换成我们在讨论线性问题时求得的w的傅里叶转换之后的形式。本篇文章中用的是高斯核,形式如下:

这就是里面用到的主要的公式的推倒吧。

推倒下一帧的地方时就是计算采样的特征和之前的训练完的数据做高斯匹配再与阿尔法相乘,得到的一个响应值最大的就是下一帧的可能值最大的地方。

在这篇文章中,我们将介绍如何使用通过 MultiTracker 类实现的 OpenCV 的多对象跟踪 API。我们将共享C++ 和 Python 代码。

大多数计算机视觉和机器学习的初学者都学习对象检测。如果您是初学者,您可能会想为什么我们需要对象跟踪。我们不能只检测每一帧中的对象吗?

让我们来探究一下跟踪是有用的几个原因。

首先,当在视频帧中检测到多个对象(例如人)时,跟踪有助于跨帧建立对象的身份。

其次,在某些情况下,对象检测可能会失败,但仍可能跟踪对象,因为跟踪考虑了对象在前一帧中的位置和外观。

第三,一些跟踪算法非常快,因为它们做的是局部搜索,而不是全局搜索。因此,我们可以通过每n帧进行目标检测,并在中间帧中跟踪目标,从而为我们的系统获得很高的帧率。

那么,为什么不在第一次检测后无限期地跟踪对象呢?跟踪算法有时可能会丢失它正在跟踪的对象。例如,当对象的运动太大时,跟踪算法可能跟不上。许多现实世界的应用程序同时使用检测和跟踪。

在本教程中,我们只关注跟踪部分。我们想要跟踪的对象将通过拖动它们周围的包围框来指定。

OpenCV 中的 MultiTracker 类提供了多目标跟踪的实现。它是一个简单的实现,因为它独立处理跟踪对象,而不对跟踪对象进行任何优化。

让我们逐步查看代码,了解如何使用 OpenCV 的多目标跟踪 API。

2.1 第 1 步:创建单一对象跟踪器

多目标跟踪器只是单目标跟踪器的集合。我们首先定义一个函数,该函数接受一个跟踪器类型作为输入,并创建一个跟踪器对象。OpenCV有8种不同的跟踪器类型:BOOSTING, MIL, KCF,TLD, MEDIANFLOW, GOTURN, MOSSE, CSRT。

如果您想使用 GOTURN 跟踪器,请务必阅读这篇文章并下载 caffe 模型。

在下面的代码中,给定跟踪器类的名称,我们返回跟踪器对象。这将在稍后用于多目标跟踪器。

Python

C++

2.2 第 2 步:读取视频的第一帧

多目标跟踪器需要两个输入

给定这些信息,跟踪器在所有后续帧中跟踪这些指定对象的位置。 在下面的代码中,我们首先使用 VideoCapture 类加载视频并读取第一帧。这将在稍后用于初始化 MultiTracker。

Python

C++

2.3 第 3 步:在第一帧中定位对象

接下来,我们需要在第一帧中定位我们想要跟踪的对象。该位置只是一个边界框。 OpenCV 提供了一个名为 selectROI 的函数,该函数会d出一个 GUI 来选择边界框(也称为感兴趣区域 (ROI))。 在 C++ 版本中,selectROI 允许您获取多个边界框,但在 Python 版本中,它只返回一个边界框。所以,在 Python 版本中,我们需要一个循环来获取多个边界框。 对于每个对象,我们还选择一种随机颜色来显示边界框。 代码如下所示。

Python

C++

getRandomColors 函数相当简贺并单

2.4 第 3 步:初始化 MultiTracker

到目前为止,我们已经读取了第一帧并获得了对象周围的边界框。这就是我们初始化多目标跟踪器所需的所有信息。

我们首先创建一个 MultiTracker 对象,并向其中添加与边界框一样多的单个对象跟踪器。在此示例中,我们使用 CSRT 单对象跟踪器,但您可以通过将下面的 trackerType 变量更改为本文开头提到的 8 个跟踪器之一来尝试其他跟踪器类型。 CSRT 跟踪器不是最快的,但在我们尝试的许多情况禅雀迹下它产生了最好的结果。

您还可以使用包裹在同岁运一个 MultiTracker 中的不同跟踪器,但当然,这没什么意义。

MultiTracker 类只是这些单个对象跟踪器的包装器。正如我们从上一篇文章中知道的那样,单个对象跟踪器是使用第一帧初始化的,并且边界框指示我们想要跟踪的对象的位置。 MultiTracker 将此信息传递给它在内部包装的单个对象跟踪器。

Python

C++

2.5 第 4 步:更新 MultiTracker 并显示结果

最后,我们的 MultiTracker 已准备就绪,我们可以在新帧中跟踪多个对象。我们使用 MultiTracker 类的 update 方法来定位新框架中的对象。每个跟踪对象的每个边界框都使用不同的颜色绘制。

Python

C++

C++

Python


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12487401.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存