【问题标题】:Bug in 2D Fourier Transform implementation二维傅里叶变换实现中的错误
【发布时间】:2015-11-16 04:53:27
【问题描述】:

我正在尝试在 Matlab 中使用 1D DFT 的组合来实现 2D DFT。在将我的结果与 Matlab 的内置函数 (fft2) 进行比较时,我意识到我有以下问题:

  1. 虚部的符号正在反转。即 + 更改为 - ,反之亦然。
  2. 除第一行外,所有行均按降序排列。

此图显示了两个结果之间的比较。侧面的红色数字表示重新排序问题。

我的代码如下:

x = imread('img.png');
x = double(x);
x = x(1:12,1:5)

% FFT
Xw = complex(zeros(size(x)));
for row = 1:size(x,1)
    Xw(row,:) = fft(x(row,:));
end

for col = 1:size(x,2)
    Xw(:,col) = fft(Xw(:,col)');
end

有人可以指出我的问题出在哪里吗?谢谢

【问题讨论】:

    标签: matlab 2d fft dft


    【解决方案1】:

    ' 运算符用于复数转置,这意味着矩阵被转置并且取值的共轭。这意味着复数值的符号是相反的。对于实数,您不会注意到这一点,因为从技术上讲,虚部为零。

    您想改用.' 来保留虚部的符号,因为每行执行中间 FFT 会产生复数值。只使用' 会改变中间结果的虚部,这会给你错误的结果:

    for col = 1:size(x,2)
        Xw(:,col) = fft(Xw(:,col).');
    end
    

    顺便说一句,作为一个小提示,根本不需要转置结果的中间列。如果您提供单个向量,fft 将沿第一个非单个维度运行,因此使用转置是多余的。如果您根本不转置结果,它实际上会有所帮助:

    for col = 1:size(x,2)
        Xw(:,col) = fft(Xw(:,col));
    end
    

    这是一个例子。我生成了一个随机的 10 x 10 矩阵:

    rng(123);
    x = rand(10);
    

    使用您的代码纠正转置(并且在开头没有索引),我们得到:

    >> Xw
    
    Xw =
    
      Columns 1 through 5
    
      50.1429 + 0.0000i  -0.4266 - 0.2624i   0.8803 + 0.9311i  -0.0526 + 1.7067i   0.7187 + 0.7161i
       0.5066 - 2.4421i   2.7551 - 1.7421i  -1.9994 + 0.6052i   0.2891 + 3.4182i   0.5300 + 2.4417i
       0.1956 + 0.1790i   4.1461 + 1.9648i  -1.3781 - 1.0303i  -0.6872 - 1.0103i  -1.2184 - 0.5783i
      -0.3645 - 1.6193i  -1.8470 - 1.3445i   4.1555 + 0.7432i   2.3707 + 3.8265i  -1.9526 + 1.9464i
      -3.1136 - 0.3704i   2.4132 - 1.0795i  -0.2255 + 1.3062i   0.8436 - 0.5157i  -0.3493 - 0.9994i
      -1.5962 + 0.0000i  -0.3780 - 1.4055i   1.6242 - 0.4842i   0.4457 + 0.4718i  -0.1794 - 2.0014i
      -3.1136 + 0.3704i   0.0134 + 0.1267i   1.0630 + 1.4563i  -0.8864 - 0.3174i  -0.5720 + 1.3041i
      -0.3645 + 1.6193i   0.7028 + 0.2797i   0.1064 + 2.0705i   2.1644 + 0.1685i   0.3095 + 0.7426i
       0.1956 - 0.1790i   2.3511 + 2.1440i   0.7301 - 0.8264i  -1.1974 - 0.3794i  -2.4981 + 1.2363i
       0.5066 + 2.4421i  -3.5897 + 0.7444i   1.2191 - 3.6386i  -2.9659 - 1.6626i  -2.0339 + 0.0880i
    
      Columns 6 through 10
    
       2.0373 + 0.0000i   0.7187 - 0.7161i  -0.0526 - 1.7067i   0.8803 - 0.9311i  -0.4266 + 0.2624i
      -1.8782 - 0.9047i  -2.0339 - 0.0880i  -2.9659 + 1.6626i   1.2191 + 3.6386i  -3.5897 - 0.7444i
       2.3752 + 1.8811i  -2.4981 - 1.2363i  -1.1974 + 0.3794i   0.7301 + 0.8264i   2.3511 - 2.1440i
       4.5213 + 0.9237i   0.3095 - 0.7426i   2.1644 - 0.1685i   0.1064 - 2.0705i   0.7028 - 0.2797i
      -1.2259 + 2.1690i  -0.5720 - 1.3041i  -0.8864 + 0.3174i   1.0630 - 1.4563i   0.0134 - 0.1267i
       6.2411 + 0.0000i  -0.1794 + 2.0014i   0.4457 - 0.4718i   1.6242 + 0.4842i  -0.3780 + 1.4055i
      -1.2259 - 2.1690i  -0.3493 + 0.9994i   0.8436 + 0.5157i  -0.2255 - 1.3062i   2.4132 + 1.0795i
       4.5213 - 0.9237i  -1.9526 - 1.9464i   2.3707 - 3.8265i   4.1555 - 0.7432i  -1.8470 + 1.3445i
       2.3752 - 1.8811i  -1.2184 + 0.5783i  -0.6872 + 1.0103i  -1.3781 + 1.0303i   4.1461 - 1.9648i
      -1.8782 + 0.9047i   0.5300 - 2.4417i   0.2891 - 3.4182i  -1.9994 - 0.6052i   2.7551 + 1.7421i
    

    我还验证了此方法无需转置。您将获得与执行.' 相同的结果。现在,使用fft2,我们得到:

    >> Xw2 = fft2(x)
    
    Xw2 =
    
      Columns 1 through 5
    
      50.1429 + 0.0000i  -0.4266 - 0.2624i   0.8803 + 0.9311i  -0.0526 + 1.7067i   0.7187 + 0.7161i
       0.5066 - 2.4421i   2.7551 - 1.7421i  -1.9994 + 0.6052i   0.2891 + 3.4182i   0.5300 + 2.4417i
       0.1956 + 0.1790i   4.1461 + 1.9648i  -1.3781 - 1.0303i  -0.6872 - 1.0103i  -1.2184 - 0.5783i
      -0.3645 - 1.6193i  -1.8470 - 1.3445i   4.1555 + 0.7432i   2.3707 + 3.8265i  -1.9526 + 1.9464i
      -3.1136 - 0.3704i   2.4132 - 1.0795i  -0.2255 + 1.3062i   0.8436 - 0.5157i  -0.3493 - 0.9994i
      -1.5962 + 0.0000i  -0.3780 - 1.4055i   1.6242 - 0.4842i   0.4457 + 0.4718i  -0.1794 - 2.0014i
      -3.1136 + 0.3704i   0.0134 + 0.1267i   1.0630 + 1.4563i  -0.8864 - 0.3174i  -0.5720 + 1.3041i
      -0.3645 + 1.6193i   0.7028 + 0.2797i   0.1064 + 2.0705i   2.1644 + 0.1685i   0.3095 + 0.7426i
       0.1956 - 0.1790i   2.3511 + 2.1440i   0.7301 - 0.8264i  -1.1974 - 0.3794i  -2.4981 + 1.2363i
       0.5066 + 2.4421i  -3.5897 + 0.7444i   1.2191 - 3.6386i  -2.9659 - 1.6626i  -2.0339 + 0.0880i
    
      Columns 6 through 10
    
       2.0373 + 0.0000i   0.7187 - 0.7161i  -0.0526 - 1.7067i   0.8803 - 0.9311i  -0.4266 + 0.2624i
      -1.8782 - 0.9047i  -2.0339 - 0.0880i  -2.9659 + 1.6626i   1.2191 + 3.6386i  -3.5897 - 0.7444i
       2.3752 + 1.8811i  -2.4981 - 1.2363i  -1.1974 + 0.3794i   0.7301 + 0.8264i   2.3511 - 2.1440i
       4.5213 + 0.9237i   0.3095 - 0.7426i   2.1644 - 0.1685i   0.1064 - 2.0705i   0.7028 - 0.2797i
      -1.2259 + 2.1690i  -0.5720 - 1.3041i  -0.8864 + 0.3174i   1.0630 - 1.4563i   0.0134 - 0.1267i
       6.2411 + 0.0000i  -0.1794 + 2.0014i   0.4457 - 0.4718i   1.6242 + 0.4842i  -0.3780 + 1.4055i
      -1.2259 - 2.1690i  -0.3493 + 0.9994i   0.8436 + 0.5157i  -0.2255 - 1.3062i   2.4132 + 1.0795i
       4.5213 - 0.9237i  -1.9526 - 1.9464i   2.3707 - 3.8265i   4.1555 - 0.7432i  -1.8470 + 1.3445i
       2.3752 - 1.8811i  -1.2184 + 0.5783i  -0.6872 + 1.0103i  -1.3781 + 1.0303i   4.1461 - 1.9648i
      -1.8782 + 0.9047i   0.5300 - 2.4417i   0.2891 - 3.4182i  -1.9994 - 0.6052i   2.7551 + 1.7421i
    

    我们可以通过确保两个矩阵之间的所有元素差异都小于一个小的阈值来证明这两个是相等的......比如1e-10

    >> all(abs(Xw(:)-Xw2(:)) <= 1e-10) 
    
    ans =
    
         1
    

    带走消息

    永远不要使用' 进行转置......永远。 Luis Mendo 是这一事实的坚定拥护者。

    【讨论】:

    • 感谢您抽出宝贵的时间来回答和清楚的解释。您的解决方案是正确的。
    • @ganninu93 很高兴。我认识到这个错误,因为我多年前做过类似的事情。很高兴我能帮上忙,祝你好运!
    • @ganninu93 我已经编辑了我的帖子。事实证明,您根本不需要转置列。
    • @ganninu93 您好,您不接受我的回答有什么原因吗?没用吗?
    • 非常感谢 :) 保重!
    猜你喜欢
    • 2017-04-10
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多