Inverse fourier result is black and full of white dots

asked 2018-11-07 07:18:33 -0600

Hello all !

i am trying to learn about fourier transform , unfortunately i found problem when i'm trying to inverse the fourier output , here's the result i achieved

Inverse fourier result , i am using lenna image

function fourier(src){

  // get optimal size of DFT
let optimalRows = cv.getOptimalDFTSize(src.rows);
let optimalCols = cv.getOptimalDFTSize(src.cols);
let s0 = cv.Scalar.all(0);
let padded = new cv.Mat();
cv.copyMakeBorder(src, padded, 0, optimalRows - src.rows, 0,
            optimalCols - src.cols, cv.BORDER_CONSTANT, s0);

// use cv.MatVector to distribute space for real part and imaginary part
let plane0 = new cv.Mat();
padded.convertTo(plane0, cv.CV_32F);
let planes = new cv.MatVector();
let complexI = new cv.Mat();
let plane1 = new cv.Mat.zeros(padded.rows, padded.cols, cv.CV_32F);
planes.push_back(plane0);
planes.push_back(plane1);
cv.merge(planes, complexI);

// in-place dft transform
cv.dft(complexI, complexI);

// compute log(1 + sqrt(Re(DFT(img))**2 + Im(DFT(img))**2))
cv.split(complexI, planes);
cv.magnitude(planes.get(0), planes.get(1), planes.get(0));
let mag = planes.get(0);
let m1 = new cv.Mat.ones(mag.rows, mag.cols, mag.type());
cv.add(mag, m1, mag);
cv.log(mag, mag);

// crop the spectrum, if it has an odd number of rows or columns
let rect = new cv.Rect(0, 0, mag.cols & -2, mag.rows & -2);
mag = mag.roi(rect);

// rearrange the quadrants of Fourier image
// so that the origin is at the image center
let cx = mag.cols / 2;
let cy = mag.rows / 2;
let tmp = new cv.Mat();

let rect0 = new cv.Rect(0, 0, cx, cy);
let rect1 = new cv.Rect(cx, 0, cx, cy);
let rect2 = new cv.Rect(0, cy, cx, cy);
let rect3 = new cv.Rect(cx, cy, cx, cy);

let q0 = mag.roi(rect0);
let q1 = mag.roi(rect1);
let q2 = mag.roi(rect2);
let q3 = mag.roi(rect3);

// exchange 1 and 4 quadrants
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);

// exchange 2 and 3 quadrants
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);

// The pixel value of cv.CV_32S type image ranges from 0 to 1.
cv.normalize(mag, mag, 0, 1, cv.NORM_MINMAX);

cv.imshow('fourierTransform', mag);

//the inverse part

let inverseTransform = new cv.Mat();
cv.dft(mag,inverseTransform,cv.DFT_INVERSE|cv.DFT_REAL_OUTPUT);
let finalImage = new cv.Mat();
inverseTransform.convertTo(finalImage,cv.CV_8U); //converting back to final image ???
cv.imshow('fourierTransform', finalImage);

}

the fourier transform part code is from opencv fourier

and then i added the reverse function and convert it back to 8 bit image.

is there something i miss ?

edit retag flag offensive close merge delete

Comments

imho, if you normalize the magnitude to [0..1], you need to upscale your CV_8U image to [0.255], like:

inverseTransform.convertTo(finalImage,cv.CV_8U, 255);

also, what was used as src image ?

oh, and let's hope, the mag images is CV_32F, not CV_32S, as in your comment ;)

berak gravatar imageberak ( 2018-11-07 07:24:00 -0600 )edit

the image was lenna image . oh it was just a typo , the type that i used is 32_CF as you can see in the code above. i tried upscale image to 255 , the result is more or less the same (black and white dots all over the image)

winatawelly gravatar imagewinatawelly ( 2018-11-07 07:32:06 -0600 )edit

you can't use the mag image for an inverse dft (it's no more complex, and has undergone a lot of changes (mostly for visualization here) !)

you can try to invert the complexI image, if you do that, you'll get something like this back:

image description

berak gravatar imageberak ( 2018-11-07 07:58:51 -0600 )edit

This is interesting. Can someone please put a final code in an answer?

sjhalayka gravatar imagesjhalayka ( 2018-11-07 18:52:22 -0600 )edit
1

@sjhalayka -- the sample is only demonstrating some common operations in the time domain. there is no real "purpose" behind those

berak gravatar imageberak ( 2018-11-08 00:19:17 -0600 )edit