如何在fftw输出上应用频率滤波器

时间:2015-09-19 05:10:04

标签: c filtering fft fftw

我使用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;
        }
   }

1 个答案:

答案 0 :(得分:3)

FFT计算什么?

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

另一种观察FFT的方法是将图像分解为不同频率的正弦和余弦分量。

fftw_plan_dft_2d()

的结果

将2D FFT应用于fftw_plan_dft_2d()fftw_execute()的图像时,结果输出将是图像的频谱。对应于 0H z的DC分量将出现在out[0]中,而高频分量将出现在out[N-1]中,其中 N = nxm 和< em> n 是 x 方向的像素数, m y - 方向的像素数

FFTW的输出与通常绘制的图形形成鲜明对比,其中DC分量( 0Hz )通常位于图像的中心,如下所示,并且频率随着您的径向增加远离市中心。

Typical FFT Output

应用于FFT输出以使其DC分量居中的典型方法是使用称为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 才能返回到原始图像。