user553710
user553710

Reputation: 210

FFT scale power spectrum

I have problem to scale out power spectrum of image using FFT. The code is below

void spectrumFFT(Complex<double> *f, Complex<double> *output, int width, int height){

        Complex<double> *temp = new Complex<double>[width * height];
        Complex<double> *singleValue = new Complex<double>();            

        for(int j = 0; j < height; j++){
            for(int i = 0; i < width; i++){
                 singleValue = f[i + j * width];
                 Complex<double> tempSwap = singleValue->Mag();
                 // tempSwap assign Magnitude value from singleValue

                 temp[i + j * width] = tempSwap;                 
            }
         }

Let's say temp 1-D array is fill of magnitude value. What my problem is how to scale out min and max value of magnitude which range between [0 - 255).

Note : input *f is already calculated value of 2DFFT and *output value will be filled with min and max value of magnitude.

Any idea with programming?

Thank you,

Regards, Ichiro

Upvotes: 1

Views: 1614

Answers (1)

Mario
Mario

Reputation: 36487

Your question isn't 100% clear, so I might be off and this might be not what you're looking for - I'll do it in general, ignoring the value range you might actually get or use.

Assuming you've got the absolute minimum and the absolute maximum value, vmin and vmax and you'd like to scale the whole range to [0; 255] you can do this that way:

// move the lower end to 0
double mod_add = -vmin;
double mod_mul = 255 / (vmax + mod_add);

Now, to rearrange one value to the range we calculated:

double scaled = (value + mod_add) * mod_mul;

mod_add will move negative numbers/values to the positive range (where the absolute minimum will become 0) and mod_mul will scale the whole range (from absolute minimum to absolute maximum) to fit into [0; 255]. Without negative values you're able to skip mod_add obviously. If you'd like to keep 0 in center (i.e. at 127) you'll have to skip mod_add and instead use the absolute maximum of vmax and vmin and scale that to 127 instead of 255.


On a side note, I think you could simplify your loop a lot, possibly saving some processing time (might not be possible depending on other code being there):

const unsigned int num = width * height;
for (unsigned int i = 0; i < num; i++)
    temp[i] = f[i]->Mag();

Also, as mentioned by Oli in the comments, you shouldn't assign any value to singleValue in the beginning, as it's overwritten later on anyway.

Upvotes: 2

Related Questions