Python scipy.numpy.convolve 和 scipy.signal.fftconvolve 结果不同
我有两个数组(G 和 G_)。这两个数组的形状和大小都是一样的,我想对它们进行卷积操作。我找到了 numpy.convolve 和 fftconvolve 这两个函数。
foldedX = getFoldGradientsFFT(G, G_)
foldedY = getFoldGradientsNumpy(G, G_)
def getFoldGradientsFFT(G, G_):
# convolve via scipy fast fourier transform
X =signal.fftconvolve(G,G_, "same)
X*=255.0/numpy.max(X);
return X
def getFoldGradientsNumpy(G, G_):
# convolve via numpy.convolve
Y = ndimage.convolve(G, G_)
Y*=255.0/numpy.max(Y);
return Y
但是结果并不相同。结果是这样的:
Numpy.convolve()[ 11.60287582 3.28262652 18.80395211 52.75829556 99.61675945
147.74124258 187.66178244 215.06160439 234.1907606 229.04221552]
而使用 scipy.signal.fftconvolve 的结果是:
[ -4.88130620e-15 6.74371119e-02 4.91875539e+00 1.94250997e+01
3.88227012e+01 6.70322921e+01 9.78460423e+01 1.08486302e+02
1.17267015e+02 1.15691562e+02]
我以为这两个函数的结果应该是一样的,尽管它们的卷积过程不同?!
我忘了提,实际上我想对两个二维数组进行卷积操作 :S
这两个数组是:
G = array([[1,2],[3,4]])
G_ = array([[5,6],[7,8]])
代码如下:
def getFoldGradientsFFT(G, G_):
X =signal.fftconvolve(G,G_,"same")
X=X.astype("int")
X*=255.0/np.max(X);
return X
def getFoldGradientsNumpy(G, G_):
# convolve via convolve
old_shape = G.shape
G = np.reshape(G, G.size)
G_ = np.reshape(G_, G.size)
Y = np.convolve(G, G_, "same")
Y = np.reshape(Y,old_shape)
Y = Y.astype("int")
Y*=255.0/np.max(Y);
return Y
def getFoldGradientsNDImage(G, G_):
Y = ndimage.convolve(G, G_)
Y = Y.astype("int")
Y *= 255.0/np.max(Y)
return Y
结果是:
getFoldGradientsFFT
[[ 21 68]
[ 93 255]]
getFoldGradientsNumpy
[[ 66 142]
[250 255]]
getFoldGradientsNDImage
[[147 181]
[220 255]]
2 个回答
3
getFoldGradientsNumpy
这个函数使用了 scipy.ndimage.convolve
。这个函数可以进行多维卷积,和 scipy.convolve
是不一样的。
对我来说,当我对两个一维数组进行卷积时,scipy.convolve
、scipy.signal.convolve
和 scipy.signal.fftconvolve
都会给出相同的结果。
5
numpy.convolve 是用来处理一维数据的。
下面的代码比较了 signal.convolve、signal.fftconvolve 和 ndimage.convolve 的结果。
对于 ndimage.convolve,我们需要将 mode 参数设置为 "constant",而 origin 参数在 N 为偶数时设置为 -1,N 为奇数时设置为 0。
from scipy import signal
from scipy import ndimage
import numpy as np
np.random.seed(1)
for N in xrange(2, 20):
a = np.random.randint(0, 10, size=(N, N))
b = np.random.randint(0, 10, size=(N, N))
r1 = signal.convolve(a, b, mode="same")
r2 = signal.fftconvolve(a, b, mode="same")
r3 = ndimage.convolve(a, b, mode="constant", origin=-1 if N%2==0 else 0)
print "N=", N
print np.allclose(r1, r2)
print np.allclose(r2, r3)