Another question was asking about the correct way of getting magnitude and phase spectra while using cv2.dft
.
My answer was limited to the numpy approach and then I thought that using OpenCV for this would be even nicer. I am currently trying to reproduce the same results but I am seeing significant differences in the phase spectrum.
Here are my imports:
%matplotlib notebookimport matplotlib.pyplot as pltimport numpy as npimport cv2im = np.zeros((50, 50), dtype = np.float32) # create empty arrayim[2:10, 2:10] = 255 # draw a rectangle
The numpy example and results:
imFFTNumpy = np.fft.fft2(im)imFFTNumpyShifted = np.fft.fftshift(imFFTNumpy)magSpectrumNumpy = np.abs(imFFTNumpyShifted)phaseSpectrumNumpy = np.angle(imFFTNumpyShifted)fig, ax = plt.subplots(nrows = 1, ncols = 3)ax[0].imshow(im)ax[1].imshow(magSpectrumNumpy)ax[2].imshow(phaseSpectrumNumpy)plt.suptitle("Using Numpy np.fft.fft2 and np.abs/ np.angle")
The OpenCV example and results:
imFFTOpenCV = cv2.dft(im, flags=cv2.DFT_COMPLEX_OUTPUT)imFFTOpenCVShifted = np.fft.fftshift(imFFTOpenCV)magSpectrumOpenCV, phaseSpectrumOpenCV = cv2.cartToPolar(imFFTOpenCVShifted[:,:,0], imFFTOpenCVShifted[:,:,1])fig, ax = plt.subplots(nrows = 1, ncols = 3)ax[0].imshow(im)ax[1].imshow(magSpectrumOpenCV)ax[2].imshow(phaseSpectrumOpenCV)plt.suptitle("Using OpenCV cv2.dft and cv2.cartToPolar")
As you can see, while the magnitude spectrum looks the same (it has some expected deviations due to floating-point arithmetic), the phase spectrum looks significantly different. I dug around a bit and found out that OpenCV usually returns phase from 0 to 2π, whereas np.angle
returns the phase from -π to +π. Subtracting π from the OpenCV phase does not correct difference though.
What could be the reason for this? Is it possible to get almost identical phase using both approaches, just like with magnitude?