user827329
user827329

Reputation:

How to apply frequency filter on fftw output

I get the 2d FFTW output of an image using fftw_plan_dft_2d(). As I understand it, the output represents a 2D array (width x height) of complex numbers.

Can someone please explain to me how exactly I should interpret this array? What does each point represent? And what does the value of each point represent?

If I wanted to apply a high-pass filter, how would I do that? I tried the code below, but all I get is overlapped shifted image when I do reverse 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;
        }
   }

Upvotes: 2

Views: 1747

Answers (1)

IKavanagh
IKavanagh

Reputation: 6187

What Does the FFT Compute?

The FFT converts an image in the spatial domain (x and y) to the frequency domain. In the spatial domain each point represents a pixel and its magnitude represents the colour of the pixel. Whereas, in the frequency domain each point represents a frequency and its magnitude is the contribution of that frequency to the image. The strength of the magnitude determines the strength of the contribution of that frequency.

Another way of looking at the FFT is that it decomposes an image into sine and cosine components of varying frequencies.

Result of fftw_plan_dft_2d()

When you apply the 2D FFT to an image with fftw_plan_dft_2d() and fftw_execute() the resulting output will be the frequency spectrum of the image. The DC component corresponding to 0Hz will be present in out[0] whilst the high frequency component will be present in out[N-1] where N = n x m and n is the number of pixels in the x-direction and m is the number of pixels in the y-direction.

The output of FFTW is in contrast to what would be typically graphed where the DC component (0Hz) is typically positioned at the center of the image, as below, and the frequencies increase radially as you travel away from the centre.

                                                                       Typical FFT Output

The typical method applied to the output of an FFT to center its DC component is to use a function called fftshift(). It is defined in MATLAB or Octave and has a discussion on converting it to C/C++ on StackOverflow.

Applying High Pass Filter to FFT Output

After applying fftshift() it becomes trivial to apply a high pass (or any other type of) filter to the FFT output. A high pass filter will only allow high frequencies through and can be implemented trivially with

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;
        }
    }
}

Aside

FFTW computes an unnormalised FFT and IFFT so when you are performing the IFFT you need to multiply by a factor of 1/N to get back to the original image.

Upvotes: 5

Related Questions