【目标跟踪】KCF高速跟踪详解

Henriques, João F., et al. “High-speed tracking with kernelized
correlation filters.” Pattern Analysis and Machine Intelligence, IEEE
Transactions on 37.3 (2015): 583-596.

本文的跟踪方法效果甚好,速度奇高,思想和实现均十分简洁。其中利用循环矩阵进行快速计算的方法尤其值得学习。另外,作者在主页上十分慷慨地给出了各种语言的实现代码。
本文详细推导论文中的一系列步骤,包括论文中未能阐明的部分。请务必先参看这篇简介循环矩阵性质的博客

思想

一般化的跟踪问题可以分解成如下几步:

  1. I t I_t It帧中,在当前位置 p t p_t pt附近采样,训练一个回归器。这个回归器能计算一个小窗口采样的响应。
  2. I t + 1 I_{t+1} It+1帧中,在前一帧位置 p t p_t pt附近采样,用前述回归器判断每个采样的响应。
  3. 响应最强的采样作为本帧位置 p t + 1 p_{t+1} pt+1

循环矩阵表示图像块

在图像中,循环位移操作可以用来近似采样窗口的位移。
这里写图片描述
训练时,围绕着当前位置进行的一系列位移采样可以用二维分块循环矩阵 X X X表示,第ij块表示原始图像下移i行右移j列的结果。类似地,测试时,前一帧结果附近的一系列位移采样也可以用 X X X表示。
这里写图片描述
这样的 X X X可以利用傅里叶变换快速完成许多线性运算。

线性回归训练提速

此部分频繁用到了循环矩阵的各类性质,请参看这篇博客
线性回归的最小二乘方法解为:
w = ( X H X + λ I ) − 1 X H y w=\left( X^HX+\lambda I\right)^{-1}X^Hy w=(XHX+λI)1XHy

根据循环矩阵乘法性质, X H X X^HX XHX的特征值为 x ^ ⊙ x ^ ∗ \hat x \odot \hat x^* x^x^ I I I本身就是一个循环矩阵,其生成向量为 [ 1 , 0 , 0...0 ] [1,0,0...0] [1,0,0...0],这个生成向量的傅里叶变换为全1向量,记为 δ \delta δ
w = ( F d i a g ( x ^ ⊙ x ^ ∗ ) F H + λ F d i a g ( δ ) F H ) − 1 X H y w=\left( Fdiag(\hat x \odot \hat x^*)F^H+\lambda Fdiag(\delta)F^H\right)^{-1}X^Hy w=(Fdiag(x^x^)FH+λFdiag(δ)FH)1XHy

= ( F d i a g ( x ^ ⊙ x ^ ∗ + λ δ ) F H ) − 1 X H y =\left( Fdiag(\hat x \odot \hat x^*+\lambda\delta)F^H \right)^{-1}X^Hy =(Fdiag(x^x^+λδ)FH)1XHy

根据循环矩阵求逆性质,可以把矩阵求逆转换为特征值求逆。
w = F ⋅ d i a g ( 1 x ^ ⊙ x ^ ∗ + λ δ ) ⋅ F H X H y w=F\cdot diag\left(\frac{1}{\hat x \odot \hat x^*+\lambda\delta} \right) \cdot F^H X^H y w=Fdiag(x^x^+λδ1)FHXHy

w = F ⋅ d i a g ( 1 x ^ ⊙ x ^ ∗ + λ δ ) ⋅ F H ⋅ F d i a g ( x ^ ∗ ) F H ⋅ y w=F\cdot diag\left(\frac{1}{\hat x \odot \hat x^*+\lambda\delta} \right) \cdot F^H \cdot Fdiag(\hat{x}^*)F^H\cdot y w=Fdiag(x^x^+λδ1)FHFdiag(x^)

  • 100
    点赞
  • 548
    收藏
    觉得还不错? 一键收藏
  • 71
    评论
KCF(Kernelized Correlation Filter)是一种基于核方法的目标跟踪算法,它在计算速度和跟踪精度上都有很好的表现。OpenCV 3.2中提供了KCF算法的实现,可以方便地进行目标跟踪。 以下是使用C++和OpenCV 3.2进行KCF目标跟踪的示例代码: ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main(int argc, char** argv) { // 打开视频文件 VideoCapture cap("test.mp4"); if (!cap.isOpened()) { std::cerr << "Failed to open video file!" << std::endl; return -1; } // 读取第一帧图像并手动选择目标区域 Mat frame, roi; cap >> frame; Rect2d bbox = selectROI(frame, false); roi = frame(bbox); // 初始化KCF跟踪器 Ptr<Tracker> tracker = TrackerKCF::create(); tracker->init(frame, bbox); // 开始跟踪 while (cap.read(frame)) { // 更新跟踪器 bool ok = tracker->update(frame, bbox); if (ok) { // 目标跟踪成功,绘制跟踪框 rectangle(frame, bbox, Scalar(0, 255, 0), 2, 1); } else { // 目标跟踪失败,重新选择目标区域 bbox = selectROI(frame, false); tracker->init(frame, bbox); } // 显示当前帧图像 imshow("KCF Tracker", frame); // 按ESC键退出程序 char c = waitKey(1); if (c == 27) { break; } } return 0; } ``` 在代码中,首先使用VideoCapture打开视频文件,然后读取第一帧图像并手动选择目标区域。接着使用TrackerKCF::create()创建KCF跟踪器,并使用init()函数初始化跟踪器。随后进入循环,使用update()函数更新跟踪器,并在跟踪成功的情况下绘制跟踪框。如果跟踪失败,则重新选择目标区域并重新初始化跟踪器。最后使用waitKey()等待按键事件,并在按下ESC键时退出程序。 需要注意的是,KCF算法对目标区域的选择非常敏感,不同的选择可能会导致跟踪失败。因此,在实际应用中,需要根据具体情况选择合适的目标区域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 71
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值