&引用;“有效”;及;全称;在Python中使用fft2进行卷积
这是一个不完整的Python卷积FFT片段 我想修改它,使其支持1)有效卷积 2) 和全卷积&引用;“有效”;及;全称;在Python中使用fft2进行卷积,python,numpy,scipy,fft,convolution,Python,Numpy,Scipy,Fft,Convolution,这是一个不完整的Python卷积FFT片段 我想修改它,使其支持1)有效卷积 2) 和全卷积 import numpy as np from numpy.fft import fft2, ifft2 image = np.array([[3,2,5,6,7,8], [5,4,2,10,8,1]]) kernel = np.array([[4,5], [1,2]]) fft_size = # what size sh
import numpy as np
from numpy.fft import fft2, ifft2
image = np.array([[3,2,5,6,7,8],
[5,4,2,10,8,1]])
kernel = np.array([[4,5],
[1,2]])
fft_size = # what size should I put here for,
# 1) valid convolution
# 2) full convolution
convolution = ifft2(fft2(image, fft_size) * fft2(kernel, fft_size))
提前谢谢。对于长度分别为
L
和M
的一维数组x
和y
,需要将FFT填充到L+M-1
的mode=“full”
。对于二维情况,将该规则应用于每个轴
使用numpy,您可以使用
np.array(x.shape) + np.array(y.shape) - 1
要实现“有效”模式,您必须计算“完整”结果,然后切掉有效部分。对于1-d,假设L
M
,则有效数据为完整数据中心的L-M+1
元素。同样,对二维情况下的每个轴应用相同的规则
比如说,
import numpy as np
from numpy.fft import fft2, ifft2
def fftconvolve2d(x, y, mode="full"):
"""
x and y must be real 2-d numpy arrays.
mode must be "full" or "valid".
"""
x_shape = np.array(x.shape)
y_shape = np.array(y.shape)
z_shape = x_shape + y_shape - 1
z = ifft2(fft2(x, z_shape) * fft2(y, z_shape)).real
if mode == "valid":
# To compute a valid shape, either np.all(x_shape >= y_shape) or
# np.all(y_shape >= x_shape).
valid_shape = x_shape - y_shape + 1
if np.any(valid_shape < 1):
valid_shape = y_shape - x_shape + 1
if np.any(valid_shape < 1):
raise ValueError("empty result for valid shape")
start = (z_shape - valid_shape) // 2
end = start + valid_shape
z = z[start[0]:end[0], start[1]:end[1]]
return z
可以添加更多的错误检查,并对其进行修改以处理复杂数组和n维数组。如果选择额外的填充以提高FFT计算的效率,那就更好了。如果您进行了所有这些增强,您可能会得到类似()的结果:
In [146]: image
Out[146]:
array([[ 3, 2, 5, 6, 7, 8],
[ 5, 4, 2, 10, 8, 1]])
In [147]: kernel
Out[147]:
array([[4, 5],
[1, 2]])
In [148]: fftconvolve2d(image, kernel, mode="full")
Out[148]:
array([[ 12., 23., 30., 49., 58., 67., 40.],
[ 23., 49., 37., 66., 101., 66., 21.],
[ 5., 14., 10., 14., 28., 17., 2.]])
In [149]: fftconvolve2d(image, kernel, mode="valid")
Out[149]: array([[ 49., 37., 66., 101., 66.]])
In [152]: from scipy.signal import fftconvolve
In [153]: fftconvolve(image, kernel, mode="full")
Out[153]:
array([[ 12., 23., 30., 49., 58., 67., 40.],
[ 23., 49., 37., 66., 101., 66., 21.],
[ 5., 14., 10., 14., 28., 17., 2.]])
In [154]: fftconvolve(image, kernel, mode="valid")
Out[154]: array([[ 49., 37., 66., 101., 66.]])