DSPRelated.com
Forums

Scaling inverse result of FFT with FFTW

Started by Unknown January 18, 2007
Hi,

I have problems working with FFTW (www.fftw.org). I need to transform a
2-dimensional array into its fourier spectrum, modify some of the
coefficients and invert it back. It is part of a watermarking algorithm
for images that works in the fourier spectrum.

My code:

const int IMG_SIZE = 1024;
fftw_plan p;
fftw_complex *in, *out, *out2;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * IMG_SIZE *
IMG_SIZE);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * IMG_SIZE *
IMG_SIZE);
out2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * IMG_SIZE *
IMG_SIZE);

// fill the input array 'in' with values
...

// do the FFT
p = fftw_plan_dft_2d(IMG_SIZE, IMG_SIZE, in, out, FFTW_FORWARD,
FFTW_MEASURE);

fftw_execute(p);
fftw_destroy_plan(p);

// modify very few of 'out''s real and imaginary values
...

// invert FFT
p = fftw_plan_dft_2d(IMG_SIZE, IMG_SIZE, out, out2, FFTW_BACKWARD,
FFTW_MEASURE);

fftw_execute(p);
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
fftw_free(out2);

The values of 'in' are integers between 0 and 255 (the brightness of an
image's pixels). The results in 'out2' are very small values, not the
original values. I know that they are scaled in a way, but I have no
idea how to transform them to be between 0 and 255 again. I read
something about diving them by the array size (IMG_SIZE * IMG_SIZE, in
my case 1024*1024). But this does not help, they seem to be scaled
everything but linear.

An example:

Input values: 26, 28, 32, 29, 19, 12
Output values (after inverse FFT): -51441664, -52130816, -51351351,
-52323270, -53409792, -52888576

Even without manipulating the values they turn this way...

Any help would be appreciated :)

floppes@gmx.de wrote:
> The values of 'in' are integers between 0 and 255 (the brightness of an > image's pixels). The results in 'out2' are very small values, not the > original values. I know that they are scaled in a way, but I have no > idea how to transform them to be between 0 and 255 again. I read > something about diving them by the array size (IMG_SIZE * IMG_SIZE, in > my case 1024*1024). But this does not help, they seem to be scaled > everything but linear.
As described in the FFTW manual and FAQ, you do indeed have to divide by the IMG_SIZE^2 to get the inverse. If this is not working for you, probably you are initializing or reading the array incorrectly. Note also that you have to initialize the input array *after* creating the plan if you use FFTW_MEASURE, as explained in the manual and the FAQ. (However, if you are only computing the transform once, FFTW_MEASURE is not worth it and you should just use FFTW_ESTIMATE.)
stev...@alum.mit.edu schrieb:

> Note also that you have to initialize the input array *after* creating > the plan if you use FFTW_MEASURE, as explained in the manual and the > FAQ. (However, if you are only computing the transform once, > FFTW_MEASURE is not worth it and you should just use FFTW_ESTIMATE.)
Changing FFTW_MEASURE to FFTW_ESTIMATE did the trick :) Now I can divide the values by 1024^2 and get the correct results. Thanks a lot! Florian