要为先前的答案添加一些信息,可以通过使相关变量为非整数来获得与上采样的带限互相关等效。
τ
τ=argmaxτ∑n=0N−1f(n)g(n+τ)
即,找到互相关的最大值。
a
b
f(n) ñ = { 0 ,1 ,。。。,Ñ - 1 } ñ τ [ - Ñ + 1 ,Ñ - 1 ]g(n)n={0,1,...,N−1}Nτ[−N+1,N−1]
目的是说明如何对由闭包定义的非整数进行互相关。这使用了数组,该数组描述了复相量在每个离散频率处的旋转,该频率对应于时移。然后为每个班次缩放此比例。显然,为了保持实时信号,负频率的旋转仅为正频率的旋转的倍(对于相应的频率对)。τ = 1 τ - 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