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?
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.