I am struggling on the result of FFTW applied on image.
I can do the Fourier transform and inverse Fourier transform on image, I am sure the two functions are working. Now I am trying to analyze the result of Fourier transform and try to apply a filter on it, etc.
Currently I am confusing on the FT result. As I know the the zero-frequency should be on the top-left corner. I should shift it to the image center if I want to check frequency friendly. There are at least two way I have tested. one method is described on the FFTW FAQ webpage, all the pixels in the image were multiplied by (-1)^(i + j) before Fourier transform, where i, and j are the pixel's index.
image was multiplied by (-1)^(i+j)
, then its magnitude is
but actually ,it should be like this (which I did in imagej) Fourier transform in imagej:
I also tried using my code to switch them after calculating its magnitude, but got the similar wrong result.
void ftShift2D(double * d, int w, int h)
{
int nw = w/2;
int nh = h/2;
if ( w%2 != 0) {nw++;}
if ( h%2 != 0) {nh++;}
printf("%d, %d\n", nw, nh);
for (int i = 0; i < nh ; i++)
{
for(int j = 0; j < nw; j++)
{
int t1 = i * w + j;
int t2 = (i + nh + 1) * w + j + nw;
swapXY<double>(d[t1], d[t2]);
}
for (int k = nw; k < w; k++)
{
int t1 = i * w + k;
int t2 = (i + nh + 1 ) * w + k - nw;
swapXY<double>(d[t1], d[t2]);
}
}
}
I understood the layout of FT result in FFTW, as is described in their website. I also checked the output, this layout can be confirmed, only top half have data, the rest is 0. therefore, it seems explain why the two methods used above cannot work. I am trying to design new method to shift the zero-frequency to image center. could you give me a better way to do it?
I insist on this, aim to use the filter, it will be easier to understand. if the zero-frequency did not be shifted to center, could you guys give me another suggestion that I can, for example, apply a high Gaussian filter on it in frequency domain.
thanks a lot.
the input image is:
The FT and IFT code are
void Imgr2c(double * d, fftw_complex * df, int w, int h)
{
fftw_plan p = fftw_plan_dft_r2c_2d(h, w, d, df, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void Imgc2r(fftw_complex * in, double * ftReverse, int w, int h)
{
fftw_plan p = fftw_plan_dft_c2r_2d(h, w, in, ftReverse, FFTW_ESTIMATE);
fftw_execute(p);
int l = w * h;
for (int i = 0; i < l; i++)
{
ftReverse[i] /= l;
}
fftw_destroy_plan(p);
}
[Edit by Spektre]
This is how it should more or less look like:
wrap
but without input image we can only guess. Also your result looks like with invalid formatting... I assume your imaginary part is half of image and the rest is real part but the width does not match as you image is skewed ... – SpektreDFFT
2.|C|
(power or absolute value) 3.wrap
. You need to play with the slider to set desired brightness of the result. So You most likely misinterpret the format of the subresult somwhere. I do not use FFTW but check for the organization of the in/out images how exactly theRe
andIm
are stored and how are you using them. PS image must be bmp and you need to click on it in the file selector first to make it work ... – Spektre