Search code examples
javaopencvdft

Reconstruct image using inverse DFT and magnitude + phase matrices in OpenCV


Assuming the official DFT tutorial (using java bindings) https://docs.opencv.org/3.4/d8/d01/tutorial_discrete_fourier_transform.html I do the following:

    Mat complexI = new Mat();
    Core.merge(planes, complexI);         // Add to the expanded another plane with zeros
    Core.dft(complexI, complexI);         // this way the result may fit in the source matrix
    // compute the magnitude
    Core.split(complexI, planes);
    Mat magI = new Mat();
    Core.magnitude(planes.get(0), planes.get(1), magI);
    Mat phasI = new Mat();
    Core.phase(planes.get(0), planes.get(1), phasI);
    Mat newComplexI = new Mat();
    Core.merge(magI, phasI, newComplexI);
    complexI.get(0,0)[0] == newComplex.get(0,0)[0]; // FALSE

What is going on? Just breaking the complexI into magnitude and phase matrices and recomposing them produces a different matrix. If I do this test before the Core.dft call then it works fine. Is it because the Mat post-dft has floating point numbers and we lose on precision? The differences between complexI and newComplexI however are much larger than a phew decimals, sometimes in the thousands.

How can I properly reconstruct the image from the mag and phase matrices using inverse dft?


Solution

  • Would have deleted the question but it was upvoted, I guess someone else had the same question.

    This makes total sense, I just didn't think the problem enough before asking. The complexI is a 2 channel matrix representing the Re numbers in the first channel and the Im in the second channel. Split essentially gives 2 single-channel matrices with all the Re and Im numbers respectively. Using the magnitude function essentially computes sqrt(Re^2 + Im^2) which gives a totally different number from Re and Im. phase is similar but using the phase computation formula. Taking those 2 numbers (mag and phase) and putting them through merge simply generates a new 2-channel matrix where Re is now the mag numbers and Im is now the phase numbers, which have nothing to do with the original numbers this the newComplexI is totally different, as expected.

    In order to achieve what I was looking for, a call to polarToCart(mag, phase,...) function to get back the Re and Im values.