Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python scipy.numpy.convolve and scipy.signal.fftconvolve different results

i am having 2 arrays (G and G_). They have the same shape and size and i want to convolve them. i found the numpy.convolve and fftconvolve. My Code is like:

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

But the results aren't the same. The result is like: Numpy.concolve()

[  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]

I thought the result is supposed to be the same, even if the two functions convolves with a different procedure?!


i forgot to mention, that i want to convolve 2 2-dimensional arrays :S the arrays:

G = array([[1,2],[3,4]])
G_ = array([[5,6],[7,8]])

the code

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

the results:

getFoldGradientsFFT
[[ 21  68]
[ 93 255]]

getFoldGradientsNumpy
[[ 66 142]
[250 255]]

getFoldGradientsNDImage
[[147 181]
[220 255]]
like image 922
tienbuiDE Avatar asked Jun 08 '26 05:06

tienbuiDE


2 Answers

numpy.convolve is for one-dimensional data.

The following code compares the results of signal.convolve, signal.fftconvolve, and ndimage.convolve.

for ndimage.convolve, we need to set mode argument to "constant", and origin argument to -1 when N is even, and 0 when N is odd.

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)
like image 134
HYRY Avatar answered Jun 10 '26 19:06

HYRY


getFoldGradientsNumpy is using scipy.ndimage.convolve. That does multi-dimensional convolution and is not the same as scipy.convolve.

For me, when convolving two one-dimensional arrays, scipy.convolve, scipy.signal.convolve, and scipy.signal.fftconvolve all return the same answer.

like image 30
Steve Tjoa Avatar answered Jun 10 '26 20:06

Steve Tjoa