Search code examples
cudafftcufft

Not the same image after cuda FFT and iFFT


I'm trying to preform an FFT -> ramp filtering -> iFFT on a 2D image with CUDA. First, as a test I tried to do FFT and iFFt without any filters. After the FFT andthe iFFT the image seems the same, but before the operation the image pixel values were between 0-255 and after the FFT and iFFT the image contains ~10^7 values.

The test image contains float numbers, and the dimensions are 512 x 360. I preform the fft with my "cuffSinogram" function, and the iFFT with the "cuInversefftSinogram" function. These are the two function what I wrote:

#define NX 512 
#define NY 360

void cufftSinogram(cufftComplex* d_complex_Sinogram, float* d_real_sinogram){ 

cufftHandle plan; 


/* Create a 2D FFT plan. */ 
if (cufftPlan2d(&plan, NX, NY, CUFFT_R2C) != CUFFT_SUCCESS){ 
    fprintf(stderr, "CUFFT Error: Unable to create plan\n"); return;    
} 

if (cufftExecR2C(plan, (cufftReal*)d_real_sinogram, d_complex_Sinogram) != CUFFT_SUCCESS){ 
    fprintf(stderr, "CUFFT Error: Unable to execute plan\n"); return;   
} 

if (cudaDeviceSynchronize() != cudaSuccess){ 
    fprintf(stderr, "Cuda error: Failed to synchronize\n"); return; 
}   

cufftDestroy(plan);} 




void cuInversefftSinogram(float* d_real_sinogram, cufftComplex* d_complex_Sinogram){


cufftHandle plan; 


/* Create a 2D FFT plan. */ 
if (cufftPlan2d(&plan, NX, NY, CUFFT_C2R)  != CUFFT_SUCCESS){ 
    fprintf(stderr, "CUFFT Error: Unable to create plan\n"); return;    
} 

if (cufftExecC2R(plan, d_complex_Sinogram, d_real_sinogram) != CUFFT_SUCCESS){ 
    fprintf(stderr, "CUFFT Error: Unable to execute plan\n"); return;   
} 

if (cudaDeviceSynchronize() != cudaSuccess){ 
    fprintf(stderr, "Cuda error: Failed to synchronize\n"); return; 
}   

cufftDestroy(plan);} 

One original and modified tiff image can be found here (I suggest, to open with imageJ)


Solution

  • CUDA FFT->IFFT sequences require that you divide the resultant values by the number of elements in the transform, if you want to return back to the original data.

    From the documentation:

    cuFFT performs un-normalized FFTs; that is, performing a forward FFT on an input data set followed by an inverse FFT on the resulting set yields data that is equal to the input, scaled by the number of elements. Scaling either transform by the reciprocal of the size of the data set is left for the user to perform as seen fit.