0
votes

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

umg

but actually ,it should be like this (which I did in imagej) Fourier transform in imagej:

img

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:

img

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:

img

2
see What should be the input and output for an FFT image transformation? what you want to do is most likely just the 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 ...Spektre
I try to upload the input image but I cannot, because the my reputation is not enough. the input image is 256x256, I did the FT mainly though the code, fftw_plan p = fftw_plan_dft_r2c_2d(h, w, d, df, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p);user1532868
I have updated the description of my question, and add the link to the input image, or you download it here, 1drv.ms/i/s!AtUbFjG0KnVcjSoCg5pMzYmP3jMNuser1532868
When I put it into my app (link is in the answer I linked in my first comment) then I got werry similar to your result when I do 1. DFFT 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 the Re and Im 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
As I know, the FT result in FFTW, is a two double data type (fft_complex), one for real, and another one for imaginary. it based on the row-major order, it means I guess first do the FT on row, and then column. because redundancy data, the row length of result is about half of the input image, but the column length is the same. most importantly all the data are stored in a one-dimensional array. therefore, these rows in result are adjacent, and they located on the consecutive memory. but anyway I still cannot figure it out.user1532868

2 Answers

0
votes

You may want to check out how I did it here: https://github.com/kvahed/codeare/blob/master/src/matrix/ft/DFT.hpp The functions doing the job are at the bottom. If there are any issues, feel free to contact me personally.

0
votes

I found what is my problem! I did not understand the output layout of DFT in FFTW deeply. After some tests, I found the the dimension in width should w/2 + 1, and the dimension in height did not changed. the code to do FT, IFT, and shift the origin have no problem. what I need to do is changing the dimension when try to access it.

magnitude after DFT

magnitude after shifting the origin Cheers,

Yaowang