You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者이민규

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 16:54:03