Reputation:
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
Reputation: 6187
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.
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.
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.
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;
}
}
}
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