本文是CSK与KCF算法推导的第五篇,主要介绍具体实现的细节。

  • CSK与KCF算法推导(一)——DFT、相关运算和循环卷积
  • CSK与KCF算法推导(二)——带核函数的岭回归问题求解
  • CSK与KCF算法推导(三)——算法主体部分推导
  • CSK与KCF算法推导(四)——从一维推广到二维
  • (本文)CSK与KCF算法推导(五)——具体实现细节
  • CSK与KCF算法推导(六)——HOG特征提取与多通道计算

算法流程

  算法的大致流程如上图所示。左边是第一次训练,右边是每次的更新。我认为整个算法最关键的地方在于提取特征图核函数的计算。作者的代码里有提取hog特征,也有直接用原始的灰度图像数据作为特征图,目前我只看了用灰度图作为特征图的部分。需要注意的是,这里的灰度图是归一化到[-0.5,0.5]的区间内的!!!

fftshift()

  MATLAB里有一个fftshift()的函数。原本DFT的结果中,低频部分是在序列两端,高频在中间;这个函数可以把低频移到中间,高频移到两边。

  在我前面的文章中介绍了,标签值应该是一个峰值在序列两端的高斯函数。既然我们是用这样的标签训练的,我们在检测的时候,如果检测一个和训练样本类似的样本,那么得到的结果也会是一个峰值在两端的结果。这时候可以用类似fftshift()的函数将结果重新排布一下,这样能便于分析。

// Create Gaussian Peak. Function called only in the first frame.
cv::Mat KCFTracker::createGaussianPeak(int sizey, int sizex)
{cv::Mat_<float> res(sizey, sizex);int syh = (sizey) / 2;int sxh = (sizex) / 2;float output_sigma = std::sqrt((float) sizex * sizey) / padding * output_sigma_factor;float mult = -0.5 / (output_sigma * output_sigma);for (int i = 0; i < sizey; i++)for (int j = 0; j < sizex; j++){int ih = i - syh;int jh = j - sxh;res(i, j) = std::exp(mult * (float) (ih * ih + jh * jh));}return FFTTools::fftd(res);
}

  上面是作者采用的生成标签值的代码,可以看到这个生成得到标签值并没有符合峰值在四个角点的要求。但作者的代码确实是能用的,为什么呢?因为作者是在计算高斯核相关的时候做了fftshift。

// Evaluates a Gaussian kernel with bandwidth SIGMA for all relative shifts between input images X and Y, which must both be MxN. They must    also be periodic (ie., pre-processed with a cosine window).
cv::Mat KCFTracker::gaussianCorrelation(cv::Mat x1, cv::Mat x2)
{using namespace FFTTools;cv::Mat c = cv::Mat( cv::Size(size_patch[1], size_patch[0]), CV_32F, cv::Scalar(0) );// HOG featuresif (_hogfeatures) {……}// Gray featureselse {cv::mulSpectrums(fftd(x1), fftd(x2), c, 0, true);c = fftd(c, true);rearrange(c);c = real(c);}
……

  上面的rearrange()函数就是完成了fftshift()的功能。为什么能够这么做呢?
α^=y^k^xx+λ\hat \alpha = \frac{{\hat y}}{{{{\hat k}^{xx}} + \lambda }}α^=k^xx+λy^​​
  我们可以对作者代码中采用的计算方式做一个推导。记α′\alpha'α′是代码中计算的结果,yyy是一个峰值在四周的二维高斯函数,y′y'y′是峰值在中央的二维高斯函数,矩阵的维度是M×N。那么:
α^′=F(y′)F(kxx(x−N/2,y−M/2))+λ=F(y(x−N/2,y−M/2))F(kxx(x−N/2,y−M/2))+λ\hat \alpha ' = \frac{{{\mathcal F}(y')}}{{{\mathcal F}\left( {k^{xx}(x - N/2,\;y - M/2)} \right){\rm{ + }}\lambda }}= \frac{{{\mathcal F}(y(x - N/2,\;y - M/2))}}{{{\mathcal F}\left( {{k^{xx}}(x - N/2,\;y - M/2)} \right){\rm{ + }}\lambda }}α^′=F(kxx(x−N/2,y−M/2))+λF(y′)​=F(kxx(x−N/2,y−M/2))+λF(y(x−N/2,y−M/2))​
  二维fftshift()相当于是在矩阵行列方向上分别循环移位一半的长度。自然yyy和y′y'y′也是fftshift()的关系。利用傅立叶变换的时移性质可以得出:
α^′(u,v)=y^WNuN/2WMvM/2k^xxWNuN/2WMvM/2+λ=y^(−1)u+vk^xx(−1)u+v+λ\hat \alpha '(u,v) = \frac{{\hat yW_N^{uN/2}W_M^{vM/2}}}{{{{\hat k}^{xx}}W_N^{uN/2}W_M^{vM/2} + \lambda }} = \frac{{\hat y{{( - 1)}^{u + v}}}}{{{{\hat k}^{xx}}{{( - 1)}^{u + v}} + \lambda }} α^′(u,v)=k^xxWNuN/2​WMvM/2​+λy^​WNuN/2​WMvM/2​​=k^xx(−1)u+v+λy^​(−1)u+v​
=y^(−1)u+vk^xx(−1)u+v+λ(−1)u+v=y^k^xx+λ=α^(u,v)= \frac{{\hat y{{( - 1)}^{u + v}}}}{{{{\hat k}^{xx}}{{( - 1)}^{u + v}} + \lambda {{( - 1)}^{u + v}}}} = \frac{{\hat y}}{{{{\hat k}^{xx}} + \lambda }} = \hat \alpha(u,v) =k^xx(−1)u+v+λ(−1)u+vy^​(−1)u+v​=k^xx+λy^​​=α^(u,v)
  所以作者代码中的做法是可行的。

峰值点估计

  因为处理的图像的点都是离散的,所以我们在f(z)f(z)f(z)中找到的某一个峰值点,不一定恰好就是真正的峰值,需要对真正的峰值点进行估计。

  用检测到的峰值点和与它临近的两个点可以对真正的峰值点进行估计。用三个点来拟合二次函数,非常简单,设f(x)=ax2+bx+qf(x)=ax^2+bx+qf(x)=ax2+bx+q,将三个点代入可以得到:
{a−b+q=lq=ca+b+q=r\left\{ \begin{array}{l} a - b + q = l\\ q = c\\ a + b + q = r \end{array} \right.⎩⎨⎧​a−b+q=lq=ca+b+q=r​
x=−b2a=−r−l2(l+r−2c)=r−l2(2c−l−r)x = - \frac{b}{{2a}} = - \frac{{r - l}}{{2(l + r - 2c)}} = \frac{{r - l}}{{2(2c - l - r)}}x=−2ab​=−2(l+r−2c)r−l​=2(2c−l−r)r−l​
  下面是作者采用的代码:

// Calculate sub-pixel peak for one dimension
float KCFTracker::subPixelPeak(float left, float center, float right)
{   float divisor = 2 * center - right - left;if (divisor == 0)return 0;return 0.5 * (right - left) / divisor;
}

峰值位置与目标位置


  我们按照这样的样本C(x)C(x)C(x)和标签yyy训练得到了α\alphaα,那么如果接下来给一个下面这样的样本zzz:

  那么会得到怎样的响应呢?先把zzz写成循环矩阵,这一循环矩阵中的样本分别求出响应值,就得到了f(z)f(z)f(z),峰值点相对于标签值左移了一个单位,而样本则是右移一个单位

  所以f(z)f(z)f(z)中的峰值点相对于原点的偏移表示当前的样本需要进行这样的移位才能和原来的训练样本一样;也就是说当前的样本是朝反方向偏移了。对于二维的图像,f(z)f(z)f(z)的峰值点相对于原点偏移了(Δx,Δy)(\Delta x,\ \Delta y)(Δx, Δy),那么目标实际上是从原来的位置偏移了(−Δx,−Δy)(-\Delta x,\ -\Delta y)(−Δx, −Δy)。
  那么怎样才能让结果符合我们的直觉呢?只要在f(z)f(z)f(z)的行列索引前面加负号,进行倒序就行。根据傅立叶变换的性质,x[−n]=X∗[k]x[-n]=X^*[k]x[−n]=X∗[k],所以我们其实可以直接求f^∗(z)\hat f^*(z)f^​∗(z),而不是求f^(z)\hat f(z)f^​(z)。
  再结合我的上一篇文章中的内容:
f^∗(z)=k^zx⊙α^∗=k^zx⊙real(α^){{\hat f}^*}(z) = {{\hat k}^{zx}} \odot {{\hat \alpha }^*} = {{\hat k}^{zx}} \odot real(\hat \alpha )f^​∗(z)=k^zx⊙α^∗=k^zx⊙real(α^)
  其中k^zx{\hat k}^{zx}k^zx表示在求zzz和xxx的互相关时,需要对x^\hat xx^取复共轭,这也是作者的代码中实际采用的做法。

CSK与KCF算法推导(五)相关推荐

  1. CSK与KCF算法推导(二)

      本文是CSK与KCF算法推导的第二篇,主要介绍标量对向量求导.核函数.岭回归问题求解等内容. CSK与KCF算法推导(一)--DFT.相关运算和循环卷积 (本文)CSK与KCF算法推导(二)--带 ...

  2. CSK与KCF算法推导(四)

      本文是CSK与KCF算法推导的第四篇,主要介绍将前面推导采用的一维情况推广到二维. CSK与KCF算法推导(一)--DFT.相关运算和循环卷积 CSK与KCF算法推导(二)--带核函数的岭回归问题 ...

  3. CSK与KCF算法推导(六)

      本文是CSK与KCF算法推导的第六篇,主要介绍HOG特征提取与多通道计算. CSK与KCF算法推导(一)--DFT.相关运算和循环卷积 CSK与KCF算法推导(二)--带核函数的岭回归问题求解 C ...

  4. CSK与KCF算法推导(三)

      本文是CSK与KCF算法推导的第三篇,主要介绍算法的主体部分推导. CSK与KCF算法推导(一)--DFT.相关运算和循环卷积 CSK与KCF算法推导(二)--带核函数的岭回归问题求解 (本文)C ...

  5. CSK与KCF算法推导(一)

      从2015年João F. Henriques等人提出KCF以来,网上已经有了很多相关的科普,也有博主给出了非常详细的推导,但如果想要真正理解我觉得还是得自己推导一遍,所以我在这里准备写一下自己学 ...

  6. 相关滤波目标追踪二:从Mosse、csk、kcf、ddst单目标跟踪算法的一些总结。

    相关滤波源于信号处理领域,相关性用于表示两个信号之间的相似程度,通常用卷积表示相关操作.那么基于相关滤波的跟踪方法的基本思想就是,寻找一个滤波模板,让下一帧的图像与我们的滤波模板做卷积操作,响应最大的 ...

  7. 五一带你找到最省旅游路线【dijkstra算法推导详解】

    前言 五一快到了,小张准备去旅游了! 查了查到各地的机票 因为今年被扣工资扣得很惨,小张手头不是很宽裕,必须精打细算.他想弄清去各个城市的最低开销. [嗯,不用考虑回来的开销.小张准备找警察叔叔说自己 ...

  8. 【KCF算法解析】High-Speed Tracking with Kernelized Correlation Filters笔记

    前段时间研究了一下KCF算法,单单看论文有很多看不懂的地方.查阅参考了,很多博客和其他材料才算了解了文章的大题思路,现将个人的理解在此记录,作为笔记. 主要内容 0.1 目标跟踪的背景介绍 0.2 学 ...

  9. 收藏 | 人人都能看懂的LSTM介绍及反向传播算法推导

    点上方蓝字计算机视觉联盟获取更多干货 在右上方 ··· 设为星标 ★,与你不见不散 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:作者:陈楠 来源:知乎 链接:https://zhuanla ...

最新文章

  1. Intellij IDEA的下载和使用(针对学生的免费使用计划)
  2. c++ vector方法
  3. oracle易忘函数用法(5)
  4. C语言 #pragma once - C语言零基础入门教程
  5. 安装git之后,桌面出现蓝色问号的解决方法
  6. Hibernate的transaction嵌套
  7. Python在SQL Server管理中的重要性
  8. java 判断类型_Java中类型判断的几种方式
  9. win7下的HP1010打印机驱动安装
  10. idea php 提示丢失,解决idea 暂存文件或idea切换分支代码丢失的问题
  11. 使用IAR下载烧录调试
  12. 区块链+保险从这些方面落地应用效果显著
  13. 什么是软件测试中的人工智能(AI)?
  14. 仿新浪微博的ListView下拉更新功能
  15. android 摄像头同时打开方式,Android,同时打开前置和后置摄像头
  16. 限定性定语从句和非限定性定语从句的区别
  17. 读《MySQL性能调优与架构设计》笔记之ORDER BY,GROUP BY 和DI STI NCT 优化
  18. JKD 下载、安装、配置
  19. iconfont字体图标线上环境加载偶尔乱码问题
  20. 外泌体相关研究最新进展(2022年6月)

热门文章

  1. centos 7 nginx hhvm mysql_CentOS 7下hhvm Nginx环境搭建
  2. nmon命令linux安装,手把手教你安装nmon
  3. leftjoin/innerjoin以后数据条数比原数据表多的原因及解决办法
  4. iOS小技能:自定义导航栏,设置全局导航条外观。(iOS15适配)
  5. efuse 加密文件 linux,开发者分享 | EFuse AES 密钥验证步骤
  6. 国外服务器为什么抽风
  7. Vertica和Hive表互操作方法比较(hdfs bulk load和shell pipe方法)
  8. Chrome插件离线安装 + Chrono下载管理器
  9. Android客户端的表情实现------来自王阳
  10. 3.8 表达式生成器