目标跟踪VOT-ECO中,cubic_spline_fourier函数推导与源码解释
读visual object tracking -- eco (Efficient Convolution Operator (ECO) tracker.) 算法的源码,一时好奇,想自己推导一下这个cubic spline kernel的计算函数。
作者:Martin-danelljan 原项目地址:https://github.com/martin-danelljan/ECO
原来的matlab是这样写的,
function bf = cubic_spline_fourier(f, a)
% The continuous Fourier transform of a cubic spline kernel.
bf = -(- 12*a + 12*exp(-pi*f*2i) + 12*exp(pi*f*2i) + 6*a*exp(-pi*f*4i) + ...
6*a*exp(pi*f*4i) + f.*(pi*exp(-pi*f*2i)*12i) - f.*(pi*exp(pi*f*2i)*12i) + ...
a*f.*(pi*exp(-pi*f*2i)*16i) - a*f.*(pi*exp(pi*f*2i)*16i) + ...
a*f.*(pi*exp(-pi*f*4i)*4i) - a*f.*(pi*exp(pi*f*4i)*4i) - 24)./(16*f.^4*pi^4);
bf(f == 0) = 1;
首先是自己走了些弯路,不知道作者到底用的哪个cubic spline, 找了一通,最后发现是这个函数(很普通,但没找到之前让好一番好猜,再后来才发现作者提供的supplementary material中有说明),详情可参考wikimedia :
https://en.wikipedia.org/wiki/Bicubic_interpolation
对该函数作傅立叶变换,得到
表达式有点乱,因为最终和作者给出的相差一个(不影响计算结果的)系数,我这里把这个系数去掉
显然前面的t相当于我们平常说的,代进去,再整理一下顺序就和作者提供的完全一样了 :-),
另外,作者最后面加了一个负号,我看了下,如果没有这个负号,所以结果都是负值,所以必须转成正数。
其实在计算时,最后只用到了函数的实部,取出来直接计算的话就是这样的
如果要看C++源码的话,可以去这里看:https://github.com/nicewsyly/ECO/blob/master/ECO/interpolator.cpp
这里我把他贴出来,如下
cv::Mat interpolator::cubic_spline_fourier(cv::Mat f, float a)
{
if (f.empty())
return cv::Mat();
cv::Mat bf(f.size(), CV_32FC1), temp1(f.size(), CV_32FC1), temp2(f.size(), CV_32FC1),
temp3(f.size(), CV_32FC1), temp4(f.size(), CV_32FC1);
std::transform(f.begin<float>(), f.end<float>(), temp1.begin<float>(), mat_cos2);
std::transform(f.begin<float>(), f.end<float>(), temp2.begin<float>(), mat_cos4);
std::transform(f.begin<float>(), f.end<float>(), temp3.begin<float>(), mat_sin2);
std::transform(f.begin<float>(), f.end<float>(), temp4.begin<float>(), mat_sin4);
bf = -1 * (-12 * a * cv::Mat::ones(f.size(), CV_32FC1) + 24 * temp1 +
12 * a * temp2 + CV_PI * 24 * f.mul(temp3) +
CV_PI * a * 32 * f.mul(temp3) + CV_PI * 8 * a * f.mul(temp4) -
24 * cv::Mat::ones(f.size(), CV_32FC1));
cv::Mat L(f.size(), CV_32FC1);
cv::pow(f, 4, L);
cv::divide(bf, 16 * L * cv::pow(CV_PI, 4), bf);
bf.at<float>(bf.rows / 2, bf.cols / 2) = 1;
return bf;
}
嗯,希望看到的童鞋可以省点时间。
Latex写长公式好累,眼都花了!