0

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)

loz
  • 71
  • 2
  • 12
  • 1
    vote to close. SO expects: "*Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers*. See: [How to create a Minimal, Complete, and Verifiable example.](http://stackoverflow.com/help/mcve) " Also FFT->IFFT in CUFFT requires you to [scale the result](http://docs.nvidia.com/cuda/cufft/index.html#cufft-transform-directions) (down) by # of elements to get the original data back. – Robert Crovella Jul 30 '14 at 10:58
  • 1
    It might be that all you need to do is divide your results by by (512*360). – Robert Crovella Jul 30 '14 at 11:00
  • Thank you, that was the problem. – loz Jul 30 '14 at 11:43

1 Answers1

3

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.

Robert Crovella
  • 143,785
  • 11
  • 213
  • 257