FFTW3 library for FFT instance of image

Normally use fftw_plan_dft_2d to perform FFT on the image

To use the fftw_plan_dft_2d function, you must first download and install the official library. When installing, pay attention to the different execution steps of the 64-bit system and the 32-bit system. I have been working for a long time.

Code block

Here is an example of the map pRefImg

    int nFFTRow=0;
    int nFFTCol=0;

    nFFTRow=nRefRow+nMaskRow-1;
    nFFTCol=nRefCol+nMaskCol-1;

    fftw_complex *pRefFFTIn= (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nFFTRow*nFFTCol);/ / Define the input of the FFT | | | fftw_complex * pRefFFTOut = (fftw_complex *) fftw_malloc (
    fftw_complex *pRefFFTOut= (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nFFTRow*nFFTCol);/ / Define the output of the FFT | | | fftw_plan p_for_ref;

    fftw_plan p_for_ref;//generate planp_for_ref = fftw_plan_dft_2d(nFFTRow, nFFTCol, pRefFFTIn, pRefFFTOut, FFTW_FORWARD, FFTW_ESTIMATE);/ / Just change FFTW_FORWARD to FFTW_BACKWARD is IFFT

    for (i=0; i<nFFTRow; i++)// Fill the expanded image with zeros{for (j=0; j<nFFTCol; j++) 
        {
            if ((i < nRefRow) && (j < nRefCol))
            {
                pRefFFTIn[i*nFFTCol+j][0]= (double)pRefImg[i][j];// real part, pRefImg is the reference picturepRefFFTIn[i*nFFTCol+j][1] = 0;// imaginary part}else
            {
                pRefFFTIn[i*nFFTCol+j][0] = 0;
                pRefFFTIn[i*nFFTCol+j][1] = 0;
            }
        }   

    }
    fftw_execute(p_for_ref); //Execute planfftw_destroy_plan(p_for_ref);if(pRefFFTIn!=NULL) fftw_free(pRefFFTIn);/ / release the memory

After executing this code, the array pRefFFTOut stores the transformed result. pRefFFTOut[...][0] saves the real part, and pRefFFTOut[...][1] saves the imaginary part.

It can be noticed that the input and output of 2dfft are two very long and long arrays. In fact, 1dfft is also performed inside the function. We tell the function how many rows and columns, the purpose is to let the function know how many points to fft. How many times to proceed.

FFT the image using the fftw_plan_dft_1d function

How to perform 2D FFT on an image by 1DFFT, it is very simple, only need to perform FFT on each line of the image, then transpose, then perform FFT on each line, and then transpose it.

Code block

The following is part of the interception


    fftw_complex *pRefFFTIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTRow*nFFTCol);
    for (i=0; i<nFFTRow; i++)/ / Expand the zero fill {for (j=0; j<nFFTCol; j++) 
        {
            if ((i < nRefRow) && (j < nRefCol))
            {
                pRefFFTIn[i*nFFTCol+j][0] = (double)pRefImg[i][j];/ / Input image | | | pRefFFTIn [i * nFFTCol + j] [
                pRefFFTIn[i*nFFTCol+j][1] = 0;
            }
            else
            {
                pRefFFTIn[i*nFFTCol+j][0] = 0;
                pRefFFTIn[i*nFFTCol+j][1] = 0;
            }
        }   
    }

    double **pRefFFTResult1_re = (double**)malloc(sizeof(double*)*nFFTRow);/ / Open up the storage array
    double **pRefFFTResult1_im = (double**)malloc(sizeof(double*)*nFFTRow);/ / Open up the storage array imaginary
    for(int i=0;i<nFFTRow;i++)                     
    {
        pRefFFTResult1_re[i] = (double*)malloc(sizeof(double)*nFFTCol);  
        pRefFFTResult1_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
    } 
    //First fft
    for (i=0; i<nFFTRow; i++)
    {
        fftw_complex *pRefFFTRowIn;
        fftw_complex *pRefFFTRowOut;
        pRefFFTRowIn  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTCol);
        pRefFFTRowOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTCol);
        fftw_plan p_for_ref1;
        p_for_ref1 = fftw_plan_dft_1d(nFFTCol, pRefFFTRowIn, pRefFFTRowOut, FFTW_FORWARD,FFTW_ESTIMATE);

        for (j=0;j<nFFTCol;j++)//row extract{
            pRefFFTRowIn[j][0] = pRefFFTIn[i*nFFTCol+j][0];
            pRefFFTRowIn[j][1] = pRefFFTIn[i*nFFTCol+j][1];
        }

        fftw_execute(p_for_ref1); 

        for (j=0;j<nFFTCol;j++)
        {
            pRefFFTResult1_re[i][j] = pRefFFTRowOut[j][0];
            pRefFFTResult1_im[i][j] = pRefFFTRowOut[j][1];
        }
        fftw_destroy_plan(p_for_ref1);
        / / release the memory
        if(pRefFFTRowIn!=NULL) fftw_free(pRefFFTRowIn);
        if(pRefFFTRowOut!=NULL) fftw_free(pRefFFTRowOut);
    }

    //Transpose
    double **pRefFFTResult1T_re = (double**)malloc(sizeof(double*)*nFFTRow);
    double **pRefFFTResult1T_im = (double**)malloc(sizeof(double*)*nFFTRow);
    for(int i=0;i<nFFTRow;i++)                     
    {
        pRefFFTResult1T_re[i] = (double*)malloc(sizeof(double)*nFFTCol);  
        pRefFFTResult1T_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
    } 
    for (i=0; i<nFFTRow; i++)
    {
        for (j=0; j<nFFTCol;j++)
        {
            pRefFFTResult1T_re[i][j] = pRefFFTResult1_re[j][i];
            pRefFFTResult1T_im[i][j] = pRefFFTResult1_im[j][i];
        }
    }

    //second fft
    double **pRefFFTResult_re = (double**)malloc(sizeof(double*)*nFFTRow);
    double **pRefFFTResult_im = (double**)malloc(sizeof(double*)*nFFTRow);
    for(int i=0;i<nFFTRow;i++)                 
    {
        pRefFFTResult_re[i] = (double*)malloc(sizeof(double)*nFFTCol);  
        pRefFFTResult_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
    } 

    for (i=0; i<nFFTRow; i++)
    {

        fftw_complex *pRefFFTColIn ;
        fftw_complex *pRefFFTColOut ;
        pRefFFTColIn  = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nFFTRow);
        pRefFFTColOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTRow);
        fftw_plan p_for_ref2;
        p_for_ref2 = fftw_plan_dft_1d(nFFTRow, pRefFFTColIn, pRefFFTColOut, FFTW_FORWARD,FFTW_ESTIMATE);

        for(j=0;j<nFFTCol;j++)//row extract{
            pRefFFTColIn[j][0] = pRefFFTResult1T_re[i][j];
            pRefFFTColIn[j][1] = pRefFFTResult1T_im[i][j];
        }

        fftw_execute(p_for_ref2); 

        for(j=0;j<nFFTCol;j++)
        {
            pRefFFTResult_re[i][j] = pRefFFTColOut[j][0];
            pRefFFTResult_im[i][j] = pRefFFTColOut[j][1];
        }
        fftw_destroy_plan(p_for_ref2);
        if(pRefFFTColIn!=NULL) fftw_free(pRefFFTColIn);
        if(pRefFFTColOut!=NULL) fftw_free(pRefFFTColOut);
    }

    //Transpose
    double **pRefFFTResultT_re = (double**)malloc(sizeof(double*)*nFFTRow);
    double **pRefFFTResultT_im = (double**)malloc(sizeof(double*)*nFFTRow);
    for(int i=0;i<nFFTRow;i++)                 
    {
        pRefFFTResultT_re[i] = (double*)malloc(sizeof(double)*nFFTCol);
        pRefFFTResultT_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
    } 
    for (i=0; i<nFFTRow; i++)
    {
        for (j=0; j<nFFTCol;j++)
        {
            pRefFFTResultT_re[i][j] = pRefFFTResult_re[j][i];//The real part of the final resultpRefFFTResultT_im[i][j] = pRefFFTResult_im[j][i];//The imaginary part of the final result}
    }

Program interpretation: 1. First, the picture to be transformed is filled with zero according to the input of one picture or two pictures; 2. Define the array to save the intermediate result and do the transpose transformation. Note that you need to define a double-dimensional array of double type at this time. You cannot directly define the array by using fftw_double in the library. 3. Perform the first fft 4. Save and transpose 5. Carry out the second fft 6. Save and transpose to get the final result There is a problem, the template matching after the above two methods are successful, but comparing the output data, the results obtained by the two methods are not the same, this is still to be discussed