Forums

2D FFTW Inverse FFT does not give original image when /n

Started by adam3914 January 20, 2009
I have what I have to assume is a stupid mistake on my part.  I am able to
take the fft of an image and get back the half of the transformed image as
I should.  When I try to do a inverse fft on the data from the fft I get
really big numbers like 10^71 size numbers.  When I would expect to get my
original image times 640*480, the size of my image.  My first question is
do I have to create the other half of the fft to pass to the inverse fft?
Or do I need to scale the transformed data before doing an inverse fft?
Thanks For any help.
Adam

My code


double * image=(double *) malloc(640*480*sizeof(double));
fftw_complex * out2d=(fftw_complex *)
malloc(640*480*sizeof(fftw_complex));
fftw_complex * out2c=(fftw_complex *)
malloc(640*480*sizeof(fftw_complex));

p2d = fftw_plan_dft_r2c_2d(480, 640, image,out2d,FFTW_MEASURE );
c2c = fftw_plan_dft_2d(480, 640, out2d,out2c, FFTW_BACKWARD,FFTW_MEASURE
);
fftw_execute(p2d);
fftw_execute(c2c);



Well, I don't use FFTW, so I can't help you with your code.  But what
caught my eye was:

>take the fft of an image and get back the half of the transformed image as >I should.
??? A 2D FFT on a 640x480 real input array (with zero valued imaginary parts) results in a 640x480 complex output array. And that output array has certain symmetry properties to it that differ from the 1D FFT case (i.e.: for 1D, you have upper/lower half conjugates - for 2D, it's a little more complicated). Are you presuming that you only need half of the outputs, as would be the case if you only want the positive frequency outputs for a 1D FFT on real inputs? As for the inverse, you asked if you have to "create the other half of the FFT ...." So I'm kind of presuming that perhaps you're thinking about this as if it were the same as the 1D case, and it isn't. For a 640x480 2D FFT, forward or inverse, you should have a 640x480 array that can hold complex numbers. For a real image on the input side, your imaginary inputs should be zero. Your transformed result will be 640x480 complex (with non-zero imaginary parts). To do the inverse, you should be starting out with a 640x480 complex input. And yes, if your FFT is unscaled, then you should definitely scale by dividing each output by the NxM size of the array at some place in the processing. I usually do it after the forward and before the inverse. Overflow is just way to easy to get when doing 2 or higher dimensional FFTs, especially for integer processing. Kevin
On Jan 20, 7:41&#2013266080;pm, "adam3914" <a...@lle.rochester.edu> wrote:
> I have what I have to assume is a stupid mistake on my part. &#2013266080;I am able to > take the fft of an image and get back the half of the transformed image as > I should. &#2013266080;When I try to do a inverse fft on the data from the fft I get > really big numbers like 10^71 size numbers. &#2013266080;When I would expect to get my > original image times 640*480, the size of my image. &#2013266080;My first question is > do I have to create the other half of the fft to pass to the inverse fft? > Or do I need to scale the transformed data before doing an inverse fft? > Thanks For any help. > Adam > > My code > > double * image=(double *) malloc(640*480*sizeof(double)); > fftw_complex * out2d=(fftw_complex *) > malloc(640*480*sizeof(fftw_complex)); > fftw_complex * out2c=(fftw_complex *) > malloc(640*480*sizeof(fftw_complex)); > > p2d = fftw_plan_dft_r2c_2d(480, 640, image,out2d,FFTW_MEASURE ); > c2c = fftw_plan_dft_2d(480, 640, out2d,out2c, FFTW_BACKWARD,FFTW_MEASURE > ); > fftw_execute(p2d); > fftw_execute(c2c);
You may consult FFTW based plugin for Image Apprentice. Here's the link: http://www.adislindia.com/pdn.html or alternately (direct link) http://divyarathore.googlepages.com/fftwpluginforimageapprentice.htm In addition, a plugin along with source code that does Gaussian High Pass Filtering using convolution (utilizes FFTW and my plugin) is there as well: http://www.adislindia.com/login/pluginlinks.php regards, Divya Rathore www.adislindia.com/people/~divya/index.htm
>On Jan 20, 7:41=A0pm, "adam3914" <a...@lle.rochester.edu> wrote: >> I have what I have to assume is a stupid mistake on my part. =A0I am
able=
> to >> take the fft of an image and get back the half of the transformed image
a=
>s >> I should. =A0When I try to do a inverse fft on the data from the fft I
ge=
>t >> really big numbers like 10^71 size numbers. =A0When I would expect to
get=
> my >> original image times 640*480, the size of my image. =A0My first
question =
>is >> do I have to create the other half of the fft to pass to the inverse
fft?
>> Or do I need to scale the transformed data before doing an inverse
fft?
>> Thanks For any help. >> Adam >> >> My code >> >> double * image=3D(double *) malloc(640*480*sizeof(double)); >> fftw_complex * out2d=3D(fftw_complex *) >> malloc(640*480*sizeof(fftw_complex)); >> fftw_complex * out2c=3D(fftw_complex *) >> malloc(640*480*sizeof(fftw_complex)); >> >> p2d =3D fftw_plan_dft_r2c_2d(480, 640, image,out2d,FFTW_MEASURE ); >> c2c =3D fftw_plan_dft_2d(480, 640, out2d,out2c,
FFTW_BACKWARD,FFTW_MEASUR=
>E >> ); >> fftw_execute(p2d); >> fftw_execute(c2c); > > >You may consult FFTW based plugin for Image Apprentice. Here's the >link: >http://www.adislindia.com/pdn.html >or alternately (direct link) >http://divyarathore.googlepages.com/fftwpluginforimageapprentice.htm > >In addition, a plugin along with source code that does Gaussian High >Pass Filtering using convolution (utilizes FFTW and my plugin) is >there as well: >http://www.adislindia.com/login/pluginlinks.php > >regards, >Divya Rathore >www.adislindia.com/people/~divya/index.htm >
I figured out that if I use the complex input fftw method it works just fine. So now I pass in a complex image with the complex parts all zero, and everything works fine.
On Jan 21, 11:35&#2013266080;pm, "adam3914" <a...@lle.rochester.edu> wrote:


> I figured out that if I use the complex input fftw method it works just > fine. &#2013266080;So now I pass in a complex image with the complex parts all zero, > and everything works fine.
Cool. Glad to know you solved it.