scipy.ndimage.filters.convolve and multiplying Fourier Transforms give different results

后端 未结 2 1863
無奈伤痛
無奈伤痛 2020-12-19 15:21

Here\'s my code:

from scipy.ndimage import filters
import numpy

a = numpy.array([[2,43,42,123,461],[453,12,111,123,55] ,[123,112,233,12,255]])
b = numpy.arr         


        
2条回答
  •  悲哀的现实
    2020-12-19 16:01

    This turned out to be a fascinating question. It seems that convolution using the Discrete Fourier Transform (as implemented by numpy.fft.fftn) is equivalent to a circular convolution. So all we need to do is use the 'wrap' convolution mode, and set the origin appropriately:

    >>> filters.convolve(a, b, mode='wrap', origin=(-1, -2))
    array([[37416, 32251, 46375, 32660, 23986],
           [30265, 33206, 62450, 19726, 17613],
           [40239, 38095, 24492, 51478, 13028]])
    >>> numpy.fft.ifftn(numpy.fft.fftn(a) * numpy.fft.fftn(b))
    array([[ 37416.+0.j,  32251.+0.j,  46375.+0.j,  32660.+0.j,  23986.+0.j],
           [ 30265.+0.j,  33206.+0.j,  62450.+0.j,  19726.+0.j,  17613.+0.j],
           [ 40239.+0.j,  38095.+0.j,  24492.+0.j,  51478.+0.j,  13028.+0.j]])
    >>> (filters.convolve(a, b, mode='wrap', origin=(-1, -2)) ==
    ...  numpy.around(numpy.fft.ifftn(numpy.fft.fftn(a) * numpy.fft.fftn(b))))
    array([[ True,  True,  True,  True,  True],
           [ True,  True,  True,  True,  True],
           [ True,  True,  True,  True,  True]], dtype=bool)
    

    The difference has only to do with the way filters.convolve handles edges. A way to use fftn to perform convolution in other modes didn't strike me right away; for a clever (and hindsight-obvious) approach to that problem, see Warren Weckesser's excellent answer.

提交回复
热议问题