Python 使用傅里叶变换进行卷积?

Python 使用傅里叶变换进行卷积?,python,numpy,filter,fft,convolution,Python,Numpy,Filter,Fft,Convolution,根据该方法,我们可以将傅里叶变换算子转换为卷积 使用Python和Scipy,我的代码如下,但不正确。 你能帮我解释一下吗 import tensorflow as tf import sys from scipy import signal from scipy import linalg import numpy as np x = [[1 , 2] , [7 , 8]] y = [[4 , 5] , [3 , 4]] print "conv:" , sign

根据该方法,我们可以将傅里叶变换算子转换为卷积

使用Python和Scipy,我的代码如下,但不正确。 你能帮我解释一下吗

import tensorflow as tf
import sys
from scipy import signal

from scipy import linalg
import numpy as np

x = [[1 , 2] , [7 , 8]]

y = [[4 , 5] , [3 , 4]]


print "conv:" ,  signal.convolve2d(x , y , 'full')

new_x = np.fft.fft2(x)
new_y = np.fft.fft2(y)


print "fft:" , np.fft.ifft2(np.dot(new_x , new_y))
代码的结果:

conv: [[ 4 13 10]
 [31 77 48]
 [21 52 32]]

fft: [[  20.+0.j   26.+0.j]
 [ 104.+0.j  134.+0.j]]

我糊涂了

问题可能在于离散卷积和连续卷积之间的差异。卷积核(即y)将超出x的边界,这些区域需要在卷积中考虑

默认情况下,scipy.signal.convalve将用0填充越界区域,这将使结果产生偏差:

默认情况下,傅里叶乘法不会这样做-您可以通过制作填充的x、y数组并比较结果来测试这一点

这些技术之间的差异应该随着内核大小变得比图像尺寸小得多而减小

作为进一步说明-您不应该在new_x和new_y之间使用点积。相反,只需将数组与*运算符相乘即可

希望这有帮助。

我回答我的问题。 正确的代码

import sys
from scipy import signal

from scipy import linalg
import numpy as np

x = [[1 , 0 , 0 , 0] , [0 , -1 , 0 , 0] , [0 , 0 , 3 , 0] , [0 , 0 , 0 , 1]]
x = np.array(x)
y = [[4 , 5] , [3 , 4]]
y = np.array(y)

print "conv:" ,  signal.convolve2d(x , y , 'full')

s1 = np.array(x.shape)
s2 = np.array(y.shape)

size = s1 + s2 - 1


fsize = 2 ** np.ceil(np.log2(size)).astype(int)
fslice = tuple([slice(0, int(sz)) for sz in size])


new_x = np.fft.fft2(x , fsize)


new_y = np.fft.fft2(y , fsize)
result = np.fft.ifft2(new_x*new_y)[fslice].copy()

print "fft for my method:" , np.array(result.real , np.int32)

print "fft:" , np.array(signal.fftconvolve(x ,y) , np.int32)

你知道吗?我没有scipy,所以我不知道它产生了什么输出。您应该将代码的输出添加到问题中。您是否希望Numpy生成
[[67.65.][79.77.]
?我不知道scipy.signal.fftconvolve.Thank。@PM2Ring,是的,我希望结果是[[4 13 10][31 77 48][21 52 32],而不是您说的那样。@user7138814谢谢,此方法很有用,结果与conv2d相同。区别不是离散与连续;它是圆形的,而不是填充的。请参阅“感谢您发布正确的代码”。一个快速的问题:告诉你如何计算:大小、fsize和fslice的来源/书籍/讲座是什么?我几乎可以肯定,这个fsize必须与这样一个事实相结合,即如果大小是“2的幂”(2^n),fft的计算速度要快得多。因此,如果你的尺寸为1000,他将计算速度提高到1024,然后fslice将削减结果上额外的24个值。在这些情况下,为什么计算速度要快得多,这一点可以通过任何有关fft工作原理的教程很容易理解(我说的是计算fft的算法,而不是傅里叶变换理论本身)。