Differences between DFT and FFT results (magnitude)
I want to get DFT
images in OpenCV.
Using a function DFT
, I can calculate it and then color it by calculating its magnitude (then apply a log and finally normalize it to paint values ββfrom 0 to 1).
My result for the next image is the result I will show you (with substitution to have lower frequencies in the center of the image):
However, if I compare it to the result, I end up using other tools like Halcon . This seems to be wrong for me, as it seems to have really "high" values ββ(the i (i) value of OpenCV DFT means:
I thought it might be for the following reasons:
- Difference between DFT (with OpenCV) and FFT (Halcon)
- The operations I perform to show the value in OpenCV.
The first one has a problem which is quite difficult for me to analyze, and OpenCV has no FFT function and Halcon has no DFT function (unless I'm wrong of course), so I cannot compare it directly.
The second one I have worked in the most time, but I still haven't found a reason if it's there.
Here is the code I am using to draw the value img
(which is my DFT image):
// 1.- To split the image in Re | Im values
Mat planes[] = {Mat_<float>(img), Mat::zeros(img.size(), CV_32F)};
// 2.- To magnitude + phase
split(img, planes);
// Calculate magnitude. I overwrite it, I know, but this is inside a function so it will be never used again, doesn't matter
magnitude(planes[0], planes[1], planes[0]);
// Magnitude Mat
Mat magI = planes[0];
// 3.- We add 1 to all them in order to perform the log
magI += Scalar::all(1); // switch to logarithmic scale
log(magI, magI);
// 4.- Swap the quadrants to center frequency
magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
int cx = magI.cols/2;
int cy = magI.rows/2;
Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-Right
Mat q2(magI, Rect(0, cy, cx, cy)); // Bottom-Left
Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right
// swap quadrants (Top-Left with Bottom-Right)
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
// swap quadrant (Top-Right with Bottom-Left)
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
// 5.- Normalize
// Transform the matrix with float values into a
// viewable image form (float between values 0 and 1).
normalize(magI, magI, 0, 1, CV_MINMAX);
// Paint it
imshow( "Magnitud DFT", magI);
So, to summarize: any idea on why I have this difference between the two ?
source to share
I'll summarize my comments in response.
When one thinks of a Fourier transform to operate in an inverse domain, the assumption is that doing the inverse transform will return the same function / vector / whatever. In other words, suppose that
This applies to many programs and libraries (e.g. Mathematica, Matlab / octave, Eigen / unsupported / FFT , etc.). However, with many libraries ( FFTW , KissFFT , etc.) this is not the case, and generally it is the scale
where is s
usually the number of elements ( m
) in the array to the power of something (should be 1, unless scaled in an inconsistent way in both transform and inverse). This is done in order to refrain from repeating all the elements m
that are multiplied by a scale that is often not important .
That being said, looking at the scale in the reverse domain, different libraries that scale transforms are free to use different scales for transform and inverse transform. Common scaling pairs for transform / inverse include { m^-1
, m
} and { m^-0.5
, m^0.5
}. Therefore, when comparing results from different libraries, we must be prepared for factors m
(scaled with m^-1
versus unscaled), m^0.5
(scaled m^-0.5
with versus unscaled and scaled with m^-1
versus m^-0.5
) or even other scales if different scaling factors are used ...
Note . This scale factor is not related to normalizing the array, so that all values [0,1]
or that the array norm is 1.
source to share