在与@Divakar的讨论后,以下是scipy中不同卷积方法的比较:
import numpy as np
from scipy import signal, ndimage
def conv2(A, size):
return signal.convolve2d(A, np.ones((size, size)), mode='same') / float(size**2)
def fftconv(A, size):
return signal.fftconvolve(A, np.ones((size, size)), mode='same') / float(size**2)
def uniform(A, size):
return ndimage.uniform_filter(A, size, mode='constant')
所有三种方法都返回完全相同的值。但是,请注意,
uniform_filter
有一个参数
mode='constant'
,它指示过滤器的边界条件,而
constant == 0
是强制傅里叶域(在其他两种方法中)的相同边界条件。对于不同的用例,您可以更改边界条件。
现在是一些测试矩阵:
A = np.random.randn(1000, 1000)
以下是一些时间:
%timeit conv2(A, 3) # 33.8 ms per loop
%timeit fftconv(A, 3) # 84.1 ms per loop
%timeit uniform(A, 3) # 17.1 ms per loop
%timeit conv2(A, 5) # 68.7 ms per loop
%timeit fftconv(A, 5) # 92.8 ms per loop
%timeit uniform(A, 5) # 17.1 ms per loop
%timeit conv2(A, 10) # 210 ms per loop
%timeit fftconv(A, 10) # 86 ms per loop
%timeit uniform(A, 10) # 16.4 ms per loop
%timeit conv2(A, 30) # 1.75 s per loop
%timeit fftconv(A, 30) # 102 ms per loop
%timeit uniform(A, 30) # 16.5 ms per loop
简而言之,
uniform_filter
更快,因为在两个1D卷积中(类似于
gaussian_filter),
卷积是可分离的。
其他具有不同内核的不可分离滤波器更可能使用signal
模块(@Divakar的解决方案中的一个)更快。
fftconvolve
和uniform_filter
的速度对于不同的内核大小保持恒定,而convolve2d
会稍微变慢。
max_x
和max_y
... - Mad Physicist