根据卷积定理(links),我们可以用傅里叶变换算子进行卷积。
使用python和scripy,我的代码在下面,但不正确。 你能帮我解释一下吗?
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]]
我很困惑!
答案 0 :(得分:3)
问题可能在于离散和连续卷积之间的差异。卷积核(即y)将超出x的边界,这些区域需要在卷积中计算。
默认情况下,scipy.signal.convolve将使用0填充超出范围的区域,这将偏向结果: https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.signal.convolve2d.html默认情况下,傅立叶乘法不会这样做 - 您可以通过填充x,y数组并比较结果来测试它。
这些技术之间的差异应该随着内核大小远小于图像尺寸而减小。
进一步说明 - 你不应该使用new_x,new_y之间的点积。相反,只需将数组与*运算符相乘即可。
希望这有帮助。
答案 1 :(得分:2)
我回答我的问题。 正确的代码。
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)