【问题标题】:How to apply frequency filter on fftw output如何在 fftw 输出上应用频率滤波器
【发布时间】:2015-09-19 05:10:03
【问题描述】:

我使用fftw_plan_dft_2d() 获得图像的 2d FFTW 输出。据我了解,输出表示复数的二维数组 (width x height)。

有人可以向我解释一下我应该如何解释这个数组吗?每个点代表什么?而每个点的值代表什么?

如果我想应用高通滤波器,我该怎么做?我尝试了下面的代码,但是当我执行反向 FFT 时,我得到的只是重叠的移位图像。

for (y = 0; y < height; y++)
{
    for (x = 0; x < width; x++)
    {
        xx = ABS(x - width / 2);
        yy = ABS(y - height / 2);
        if (sqrt(xx * xx + yy * yy) > width / 2)
        {
            fft[y * width + x][0] = 0;
            fft[y * width + x][1] = 0;
        }
   }

【问题讨论】:

    标签: c filtering fft fftw


    【解决方案1】:

    FFT 计算什么?

    FFT 将空间域(xy)中的图像转换为频域。在空间域中,每个点代表一个像素,其大小代表像素的颜色。而在频域中,每个点都代表一个频率,其大小是该频率对图像的贡献。幅度的强度决定了该频率的贡献强度。

    查看 FFT 的另一种方式是将图像分解为不同频率的正弦和余弦分量。

    fftw_plan_dft_2d() 的结果

    当您将 2D FFT 应用于具有 fftw_plan_dft_2d()fftw_execute() 的图像时,结果输出将是图像的频谱。对应于 0Hz 的直流分量将出现在 out[0] 中,而高频分量将出现在 out[N-1] 中,其中 N = n x mn 是 x 方向的像素数,my 方向的像素数。

    FFTW 的输出与通常绘制的图形相反,其中直流分量 (0Hz) 通常位于图像的中心,如下所示,并且频率随着您的使用呈放射状增加远离中心。

                                                                        

    应用于 FFT 输出以使其直流分量居中的典型方法是使用称为 fftshift() 的函数。它在MATLABOctave 中定义,并有一个discussion on convertingC/C++ on StackOverflow

    对 FFT 输出应用高通滤波器

    应用fftshift() 后,将高通(或任何其他类型的)filter 应用到 FFT 输出变得很简单。高通滤波器只允许高频通过,并且可以通过

    轻松实现
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            int index = i + j*m;
    
            double x = i*dx;
            double y = i*dy;
    
            if (sqrt(x*x + y*y) < radius) { // All frequencies in radius deleted
                fft[index][0] = 0;
                fft[index][1] = 0;
            }
        }
    }
    

    一边

    FFTW 计算非标准化 FFT 和 IFFT,因此当您执行 IFFT 时,您需要乘以 1/N 的因数才能返回原始图像。

    【讨论】:

    • fftshift()。这就是我所缺少的!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-05-28
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2016-02-08
    • 1970-01-01
    • 2018-10-19
    相关资源
    最近更新 更多