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

2D DFT与IDFT图像实现异常:IDFT输出与原图不符且反转问题排查

二维DFT/IDFT实现问题排查与修复

问题描述

实现二维离散傅里叶变换(2D DFT)和逆变换(IDFT)后,IDFT输出图像与原始图像不一致,呈现反转状态,无法正确还原原始图像,怀疑遗漏关键计算项或相位信息处理错误。

现有代码

DFT 实现代码

var
i, j, k, M, N, u, v, x, y:integer; 
aux: extended; 
Real, Imaginario, Mag, IMag, Vagxy:TMatriz; 
Vag:TVetorE;
 
M:=16; 
N:=16; 
SetLength(Mag, M, N); //Magnitudes
ZeraMatriz(Mag, M, N);
SetLength(Real, M, N);
SetLength(Imaginario, M, N);
aux:=2*pi;
for u:=0 to M-1 do
    for v:=0 to N-1 do
        begin
             ZeraMatriz(Real, M, N);
             ZeraMatriz(Imaginario, M, N);
             for x:=0 to M-1 do  
                 for y:=0 to N-1 do  
                    begin
                         Real[u,v]:=Real[u,v]+(Vagxy[x,y]*cos(aux*(((u*x)/M)+(v*y)/N)));
                         Imaginario[u,v]:=Imaginario[u,v]-(Vagxy[x,y]*sin(aux*(((u*x)/M)+(v*y)/N)));
                         //Form1.Memo.Lines.Add(IntToStr(Form1.Memo.Lines.Count)+'     Vag:  '+FloattoStr(Vagxy[x,y])+ 'x'+ InttoStr(x)+ 'y'+ InttoStr(y));
                    end;
              Mag[u,v]:=sqrt(Power(Real[u,v],2)+Power(Imaginario[u,v],2));
              //Form1.Memo.Lines.Add(IntToStr(Form1.Memo.Lines.Count)+'     Mag:  '+FloattoStr(Mag[u,v]));
        end;

IDFT 实现代码

M:=16; 
N:=16; 
aux:=2*pi;
SetLength(IMag, M, N);
ZeraMatriz(IMag, M, N);
SetLength(Real, M, N);
SetLength(Imaginario, M, N);
for x:=0 to M-1 do
    for y:=0 to N-1 do
        begin
             ZeraMatriz(Real, M, N);
             ZeraMatriz(Imaginario, M, N);
             for u:=0 to M-1 do  
                 for v:=0 to N-1 do  
                    begin
                         Real[x,y]:=Real[x,y]+(Mag[u,v]*cos(aux*(((u*x)/M)+(v*y)/N)));
                         Imaginario[x,y]:=Imaginario[x,y]+(Mag[u,v]*sin(aux*(((u*x)/M)+(v*y)/N)));
                    end;
             IMag[x,y]:=(sqrt(Power(Real[x,y],2)+Power(Imaginario[x,y],2)))/(M*N);
        end;

// shows image
k:=0;
for y := 0 to N-1 do
    for x := 0 to M-1 do
        begin
             Vag[k]:=IMag[x,y];
             k:=k+1;
        end;

问题分析

  1. 丢失相位信息:DFT仅保存了频率域的幅度Mag,丢弃了虚部Imaginario携带的相位信息。原始图像的还原需要幅度和相位共同作用——幅度决定频率分量的强度,相位决定分量的空间位置,仅用幅度无法还原原始信号的空间结构。
  2. IDFT计算逻辑错误:
    • IDFT输入应为DFT输出的完整复数(实部+虚部),而非仅幅度。
    • 原始图像是实数信号,IDFT计算后虚部应趋近于0,无需对实部虚部求平方根,直接取实部即可得到恢复的图像值。
  3. 循环冗余操作:DFT中每次计算u,v时都全局清零Real和Imaginario矩阵,这会导致之前计算的其他u,v值被覆盖,正确做法应为每次计算新的u,v时仅清零当前Real[u,v]和Imaginario[u,v]。

修复后的代码

修正后的DFT代码

var
i, j, k, M, N, u, v, x, y:integer; 
aux: extended; 
DFT_Real, DFT_Imag, Mag, IMag, Vagxy:TMatriz; 
Vag:TVetorE;
 
M:=16; 
N:=16; 
SetLength(DFT_Real, M, N);
SetLength(DFT_Imag, M, N);
SetLength(Mag, M, N);
ZeraMatriz(DFT_Real, M, N);
ZeraMatriz(DFT_Imag, M, N);
ZeraMatriz(Mag, M, N);
aux:=2*pi;

for u:=0 to M-1 do
    for v:=0 to N-1 do
        begin
             // 仅清零当前(u,v)的实部虚部,而非全局矩阵
             DFT_Real[u,v] := 0;
             DFT_Imag[u,v] := 0;
             for x:=0 to M-1 do  
                 for y:=0 to N-1 do  
                    begin
                         DFT_Real[u,v] := DFT_Real[u,v] + Vagxy[x,y] * cos(aux * ((u*x)/M + (v*y)/N));
                         DFT_Imag[u,v] := DFT_Imag[u,v] - Vagxy[x,y] * sin(aux * ((u*x)/M + (v*y)/N));
                    end;
              Mag[u,v] := sqrt(Power(DFT_Real[u,v],2) + Power(DFT_Imag[u,v],2));
        end;

修正后的IDFT代码

M:=16; 
N:=16; 
aux:=2*pi;
SetLength(IMag, M, N);
ZeraMatriz(IMag, M, N);
var
  IDFT_Real: extended;

for x:=0 to M-1 do
    for y:=0 to N-1 do
        begin
             IDFT_Real := 0;
             for u:=0 to M-1 do  
                 for v:=0 to N-1 do  
                    begin
                         // 使用DFT的完整复数分量计算,取实部累加
                         IDFT_Real := IDFT_Real + DFT_Real[u,v] * cos(aux * ((u*x)/M + (v*y)/N)) 
                                               + DFT_Imag[u,v] * sin(aux * ((u*x)/M + (v*y)/N));
                    end;
             // 归一化并赋值给恢复图像
             IMag[x,y] := IDFT_Real / (M*N);
        end;

// 输出图像(确保索引顺序正确)
k:=0;
for y := 0 to N-1 do
    for x := 0 to M-1 do
        begin
             Vag[k] := IMag[x,y];
             k := k+1;
        end;

关键修复点说明

  • 保存DFT的完整复数结果(DFT_Real和DFT_Imag),保留相位信息。
  • IDFT直接使用复数分量计算,利用欧拉公式展开后仅累加实部(因原始图像为实数)。
  • 移除不必要的全局矩阵清零操作,仅初始化当前计算的变量,提升效率并避免数据覆盖。
  • 归一化步骤放在实部累加之后,直接得到恢复的图像像素值。

内容的提问来源于stack exchange,提问作者Lara Anoni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:15:23