PyTorch实现傅里叶变换相位位移特性输出噪点问题求解
问题原因及修正方案
- 输入类型错误:
cv2.imread返回的是uint8类型的numpy数组,直接传入PyTorch的FFT接口会导致类型不匹配,计算精度损失。 - 频域排布不匹配:
torch.fft.fft2默认输出的频域结果低频分量位于数组四个角,你生成的是中心为0的频率坐标,必须先通过fftshift将低频移到中心,相位叠加完成后再用ifftshift转换回原始频域排布才能做逆变换。 - 相位公式错误:傅里叶位移定理的相位项为
-2π*(u*x_shift/W + v*y_shift/H),你当前的计算缺少2π系数,相位值量级完全不符合要求。 - 重复缩放位移量:
phase_shifters函数中已经对line_x、line_y分别乘以了x_alpha、y_alpha,返回时又重复乘以了一次位移系数,导致相位偏移量是预期值的平方倍。 - 多余的相位取模操作:不需要手动对相位做
%(2*pi)处理,torch.polar本身支持任意范围的相位输入,手动取模反而可能引入数值误差。
修正后可运行代码
import torch import cv2 import numpy as np from math import pi def phase_shifters(y_alpha=0, x_alpha=0, shape=None): # HxWxC # x shift line_x = torch.linspace(-shape[1]/2, shape[1]/2, shape[1]) line_x = line_x.expand(shape[0], shape[2], shape[1]).transpose(1, 2) line_x = line_x / shape[1] * x_alpha # y shift line_y = torch.linspace(-shape[0]/2, shape[0]/2, shape[0]) line_y = line_y.expand(shape[2], shape[1], shape[0]).transpose(0, 2) line_y = line_y / shape[0] * y_alpha # 移除重复的位移系数乘法 return line_x + line_y # 读取图像并转成torch浮点张量 img = cv2.imread("test.png") img_tensor = torch.tensor(img, dtype=torch.float32) # FFT后先做fftshift将低频移到中心 img_fft = torch.fft.fft2(img_tensor, dim=(0,1)) img_fft_shifted = torch.fft.fftshift(img_fft, dim=(0,1)) mag = torch.abs(img_fft_shifted) phase = torch.angle(img_fft_shifted) # 相位项补充2π系数 p_shift = phase_shifters(y_alpha=0, x_alpha=50, shape=phase.shape) phase = phase - 2 * pi * p_shift recon = torch.polar(mag, phase) # 逆变换前先做ifftshift还原频域排布 recon = torch.fft.ifftshift(recon, dim=(0,1)) recon = torch.fft.ifft2(recon, dim=(0,1)).real recon = torch.clamp(recon, 0, 255) cv2.imshow("recon", np.array(recon, dtype=np.uint8)) cv2.waitKey(0) cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者이민규
相关产品推荐
相关产品推荐

