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

2 c filtering fft fftw

我使用fftw_plan_dft_2d(). 据我了解,输出表示复数的二维数组(x)。

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

如果我想应用高通滤波器,我该怎么做?我尝试了下面的代码,但是当我做反向 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;
        }
   }
Run Code Online (Sandbox Code Playgroud)

IKa*_*agh 5

FFT 计算什么?

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

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

的结果 fftw_plan_dft_2d()

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

FFTW 的输出与通常绘制的 DC 分量 ( 0Hz ) 通常位于图像中心的图形形成对比,如下所示,并且频率随着远离中心而呈放射状增加。

                                                                       典型 FFT 输出

应用于 FFT 输出以使其直流分量居中的典型方法是使用称为 的函数fftshift()。它在MATLABOctave 中定义,并在 StackOverflow 上讨论了将转换C/C++ 的问题

对 FFT 输出应用高通滤波器

应用后,将fftshift()高通(或任何其他类型的)滤波器应用于 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在旁边

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