scipy 提供了一个相关函数,该函数对于小输入也可以很好地工作,并且如果您想要非循环相关(意味着信号不会环绕)。请注意,在mode='full'
, signal.correlation 返回的数组的大小是信号大小之和减一(即len(a) + len(b) - 1
), so 的值来自argmax
与您预期的偏差(信号大小 -1 = 20).
from scipy import signal, fftpack
import numpy
a = numpy.array([0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0, 0, 0, 0, 0])
b = numpy.array([0, 0, 0, 0, 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0])
numpy.argmax(signal.correlate(a,b)) -> 16
numpy.argmax(signal.correlate(b,a)) -> 24
两个不同的值对应是否处于平移a
or b
.
如果您想要循环相关并且对于大信号大小,您可以使用卷积/傅里叶变换定理,但需要注意的是相关与卷积非常相似但不相同。
A = fftpack.fft(a)
B = fftpack.fft(b)
Ar = -A.conjugate()
Br = -B.conjugate()
numpy.argmax(numpy.abs(fftpack.ifft(Ar*B))) -> 4
numpy.argmax(numpy.abs(fftpack.ifft(A*Br))) -> 17
同样,这两个值对应于您是否解释了转变a
或转变b
.
负共轭是由于卷积翻转了函数之一,但相关性中没有翻转。您可以通过反转其中一个信号然后进行 FFT,或者对信号进行 FFT 然后进行负共轭来撤消翻转。即以下情况为真:Ar = -A.conjugate() = fft(a[::-1])