要在前面的答案中添加一点,您可以通过使相关变量为非整数来获得上采样带限互相关的等价物。
以下(python)代码计算τ, 在哪里
τ=argmaxτ∑n=0N−1f(n)g(n+τ)
也就是说,它找到了互相关的最大值。
输入变量a
和b
描述和对于并且都假设是带限和周期性的周期(在离散傅立叶域中实现移位)。在范围内。f(n)g(n)n={0,1,...,N−1}Nτ[−N+1,N−1]
目的是展示如何对由闭包定义的非整数执行互相关。这使用了数组,它描述了复相量在每个离散频率上的旋转,对应于时移。然后为每个班次缩放。很明显,为了保持实时信号,负频率的旋转只是倍(对于相应的频率对)。τcorrelate_point
omega
τ=1τ−1
一个微妙之处在于您如何处理样本(奈奎斯特频率),因为它在正带和负带之间共享。这里使用的解决方案是在正旋转相量和负旋转相量(它们是实轴上的反射)之间进行插值,即将单位旋转相量投影到实轴上,这是一个 cos 函数(这是因为是对应于奈奎斯特频率的值)。显然,该值需要为实数才能保持实时域信号。N2pi
omega
的任意精确值的互相关。只需使用您喜欢的任何值调用闭包(可以作为可调用对象返回) 。ττ
import numpy
from numpy import fft
from scipy import optimize
def arg_max_corr(a, b):
if len(a.shape) > 1:
raise ValueError('Needs a 1-dimensional array.')
length = len(a)
if not length % 2 == 0:
raise ValueError('Needs an even length array.')
if not a.shape == b.shape:
raise ValueError('The 2 arrays need to be the same shape')
# Start by finding the coarse discretised arg_max
coarse_max = numpy.argmax(numpy.correlate(a, b, mode='full')) - length+1
omega = numpy.zeros(length)
omega[0:length/2] = (2*numpy.pi*numpy.arange(length/2))/length
omega[length/2+1:] = (2*numpy.pi*
(numpy.arange(length/2+1, length)-length))/length
fft_a = fft.fft(a)
def correlate_point(tau):
rotate_vec = numpy.exp(1j*tau*omega)
rotate_vec[length/2] = numpy.cos(numpy.pi*tau)
return numpy.sum((fft.ifft(fft_a*rotate_vec)).real*b)
start_arg, end_arg = (float(coarse_max)-1, float(coarse_max)+1)
max_arg = optimize.fminbound(lambda tau: -correlate_point(tau),
start_arg, end_arg)
return max_arg