fftw 将零频移到图像中心

fftw shift zero-frequency to image center

我正在努力研究应用于图像的 FFTW 结果。

我可以对图像进行傅里叶变换和傅里叶逆变换,我相信这两个函数都能正常工作。现在我正在尝试分析傅里叶变换的结果并尝试对其应用过滤器等

目前我对 FT 结果感到困惑。据我所知,零频率应该在左上角。如果我想检查频率是否友好,我应该将它移到图像中心。我至少测试了两种方法。 FFTW FAQ 网页上描述了一种方法,图像中的所有像素在傅里叶变换之前都乘以 (-1)^(i + j),其中 i 和 j 是像素的索引。

图像乘以(-1)^(i+j),则其大小为

但实际上,它应该是这样的(我在imagej中做的)imagej中的傅立叶变换:

我也试过在计算出它的大小后用我的代码来切换它们,但得到了类似的错误结果。

void ftShift2D(double * d, int w, int h)
{

    int nw = w/2;
    int nh = h/2;
    if ( w%2 != 0) {nw++;}
    if ( h%2 != 0) {nh++;}

        printf("%d, %d\n", nw, nh);
        for (int i = 0; i < nh ; i++)
        {
                for(int j = 0; j < nw; j++)
                {
                        int t1 = i * w + j;
                        int t2 = (i + nh + 1) * w + j + nw;
                        swapXY<double>(d[t1], d[t2]);
                }

                for (int k = nw; k < w; k++)
                {
                        int t1 = i  * w + k;
                        int t2 = (i + nh + 1 ) * w + k - nw;
                        swapXY<double>(d[t1], d[t2]);
                }
        }
}

我了解 FFTW 中 FT 结果的布局,如他们网站中所述。 我也检查了输出,这个布局可以确认,只有上半部分有数据,其余为0。因此,似乎解释了为什么上面使用的两种方法不起作用。我正在尝试设计新方法将零频率移动到图像中心。你能给我一个更好的方法吗?

我坚持这个,旨在使用过滤器,这样会更容易理解。如果零频没有移到中心,你们能不能给我另一个建议,比如我可以在频域上对其应用高斯滤波器。

非常感谢。

输入图像是:

FT和IFT代码为

    void Imgr2c(double * d, fftw_complex * df, int w, int h)
{
        fftw_plan p = fftw_plan_dft_r2c_2d(h, w, d, df, FFTW_ESTIMATE);
        fftw_execute(p);

        fftw_destroy_plan(p);

}


void Imgc2r(fftw_complex * in, double * ftReverse, int w, int h)
{
        fftw_plan p = fftw_plan_dft_c2r_2d(h, w, in, ftReverse, FFTW_ESTIMATE);
        fftw_execute(p);

        int l = w * h;
        for (int i = 0; i < l; i++)
        {
                ftReverse[i] /= l;
        }

        fftw_destroy_plan(p);
}

[Spektre 编辑]

大致应该是这样的:

你可能想看看我是怎么做到的: https://github.com/kvahed/codeare/blob/master/src/matrix/ft/DFT.hpp 完成这项工作的功能在底部。如果有任何问题,请随时与我私下联系。

我找到我的问题了!我没有深入了解FFTW中DFT的输出布局。经过一些测试,我发现宽度尺寸应该w/2+∀1,而高度尺寸没有改变。执行 FT、IFT 和移动原点的代码没有问题。我需要做的是在尝试访问时更改维度。

magnitude after DFT

magnitude after shifting the origin 干杯,

药网