傅里叶变换卷积采用何种边界条件/模式?Python测试卷积定理出错求排查及示例
傅里叶变换卷积的边界条件与卷积定理的正确实现
问题根源
你完全搞反了卷积定理的形式:
- 正确的卷积定理是:时域卷积的傅里叶变换 = 各自傅里叶变换的点乘,即
FT(f * g) = FT(f) ⊙ FT(g)(⊙表示逐元素相乘) - 反过来,时域点乘的傅里叶变换 = 各自傅里叶变换的循环卷积 除以总元素数,即
FT(f ⊙ g) = (FT(f) *_circular FT(g)) / (M*N)(M、N是数组的行列数)
你的代码把两个关系搞混了,且没有做必要的归一化,自然等式不成立。另外,傅里叶变换对应的卷积是循环卷积,你用的boundary='wrap'这个边界条件是正确的,但要配合定理的正确形式。
正确实现示例
验证:时域卷积的FT = FT的点乘
from scipy import signal import numpy as np a = np.array([[1,2],[3,4]]) b = np.array([[5,6],[7,8]]) # 1. 计算时域循环卷积(傅里叶变换对应的卷积类型) conv_time = signal.convolve2d(a, b, mode='same', boundary='wrap') # 2. 计算卷积结果的傅里叶变换 ft_conv_time = np.fft.fft2(conv_time) # 3. 计算两个数组各自的傅里叶变换,再做逐元素点乘 ft_a = np.fft.fft2(a) ft_b = np.fft.fft2(b) ft_product = ft_a * ft_b # 浮点精度问题,用allclose判断是否相等 print(np.allclose(ft_conv_time, ft_product)) # 输出 True
验证:时域点乘的FT = FT的循环卷积 / 总元素数
# 1. 计算时域的逐元素点乘 pointwise_product = a * b # 2. 计算点乘结果的傅里叶变换 ft_pointwise = np.fft.fft2(pointwise_product) # 3. 计算两个傅里叶变换的循环卷积 conv_ft = signal.convolve2d(ft_a, ft_b, mode='same', boundary='wrap') # 4. 除以数组总元素数(2x2=4)做归一化 conv_ft_normalized = conv_ft / (2*2) # 对比结果 print(np.allclose(ft_pointwise, conv_ft_normalized)) # 输出 True
关键注意点
- 傅里叶变换默认对应循环卷积,必须用
boundary='wrap'来模拟这种周期性重复的边界条件 - 严格区分卷积定理的两种形式,不要搞反时域和频域的操作对应关系
- 时域点乘对应的频域卷积必须做归一化,除以数组的总元素数,这是离散傅里叶变换的特性决定的
内容的提问来源于stack exchange,提问作者Winniebear
相关产品推荐
相关产品推荐

