圓形FFT卷積我需要的需要在Python
scipy.signal.convolve2d(data, filter, boundary="wrap", mode="same")
更快的模擬你能不能指點我如何取代它?
P.S. scipy.signal.fftconvolve
速度夠快,但它沒有boundary
選項,我無法使其在循環卷積模式下工作。
圓形FFT卷積我需要的需要在Python
scipy.signal.convolve2d(data, filter, boundary="wrap", mode="same")
更快的模擬你能不能指點我如何取代它?
P.S. scipy.signal.fftconvolve
速度夠快,但它沒有boundary
選項,我無法使其在循環卷積模式下工作。
如果計算如下:
from scipy.fftpack import fft2, ifft2
f2 = ifft2(fft2(data, shape=data.shape) * fft2(filter, shape=data.shape)).real
然後f2
包含相同的值作爲convolve2d(data, filt, boundary='wrap', mode='same')
,但值被移位(「滾動」,在numpy的術語)中的每個軸。 (這是convolution theorem的一個應用程序。)
這裏的一個短函數滾動的結果向得到相同的結果convolve2d
函數調用:
def fftconvolve2d(x, y):
# This assumes y is "smaller" than x.
f2 = ifft2(fft2(x, shape=x.shape) * fft2(y, shape=x.shape)).real
f2 = np.roll(f2, (-((y.shape[0] - 1)//2), -((y.shape[1] - 1)//2)), axis=(0, 1))
return f2
例如,
In [91]: data = np.random.rand(256, 256)
In [92]: filt = np.random.rand(16, 16)
In [93]: c2d = convolve2d(data, filt, boundary='wrap', mode='same')
In [94]: f2 = fftconvolve2d(data, filt)
驗證結果是否相同:
In [95]: np.allclose(c2d, f2)
Out[95]: True
Check性能:
In [96]: %timeit c2d = convolve2d(data, filt, boundary='wrap', mode='same')
44.9 ms ± 77.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [97]: %timeit f2 = fftconvolve2d(data, filt)
5.23 ms ± 11.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
的FFT版本多更快(但請注意,我選擇的data
尺寸是2的冪)。
謝謝同志!我認爲就是這樣! ^ __ ^ – Felix
我認爲沒有邊界選項的原因是因爲FFT不能像那樣工作。而「循環」卷積究竟是什麼意思?編輯:沒關係,我在[Wikipedia](https://en.wikipedia.org/wiki/Circular_convolution)上找到了一個定義。 –