简体   繁体   English

在Python中需要循环FFT卷积

[英]Need a circular FFT convolution in Python

I need a faster analog of 我需要更快的模拟

scipy.signal.convolve2d(data, filter, boundary="wrap", mode="same")

Cannot you advice me how to replace it? 您不能建议我如何更换它吗?

PS scipy.signal.fftconvolve is fast enough, but it does not have boundary option and I cannot make it work in circular convolution mode. PS scipy.signal.fftconvolve足够快,但是没有boundary选项,因此我无法使其在循环卷积模式下工作。

If you compute the following: 如果您计算以下内容:

from scipy.fftpack import fft2, ifft2

f2 = ifft2(fft2(data, shape=data.shape) * fft2(filter, shape=data.shape)).real

then f2 contains the same values as convolve2d(data, filt, boundary='wrap', mode='same') , but the values are shifted ("rolled", in numpy terminology) in each axis. 然后f2包含与convolve2d(data, filt, boundary='wrap', mode='same')的值,但是这些值在每个轴上移动(以“ numpy”术语表示为“ rolled”)。 (This is an application of the convolution theorem .) (这是卷积定理的一个应用。)

Here's a short function that rolls the result to the give same result as the convolve2d function call: 这是一个简短的函数,可将结果转换为与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

For example, 例如,

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)

Verify that the results are the same: 验证结果是否相同:

In [95]: np.allclose(c2d, f2)
Out[95]: True

Check the performance: 检查性能:

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)

The FFT version is much faster (but note that I chose the dimensions of data to be a power of 2). FFT版本快得多(但请注意,我选择的data尺寸为2的幂)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM