使用 np.fft.fft2 和 cv2.dft 再现相位谱。为什么结果不相似?

问题描述 投票:0回答:1

另一个问题是询问使用

cv2.dft
时获取幅度和相位谱的正确方法。

我的答案仅限于 numpy 方法,然后我认为使用 OpenCV 会更好。我目前正在尝试重现相同的结果,但我发现相位谱存在显着差异。

这是我的进口:

%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import cv2
im = np.zeros((50, 50), dtype = np.float32) # create empty array
im[2:10, 2:10] = 255 # draw a rectangle

numpy 示例和结果:


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")

OpenCV 示例和结果:

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")

如您所见,虽然幅度谱看起来相同(由于浮点运算,它有一些预期偏差),但相位谱看起来却明显不同。我仔细研究了一下,发现 OpenCV 通常返回从 0 到 2π 的相位,而

np.angle
返回从 -π 到 +π 的相位。但从 OpenCV 相位中减去 π 并不能纠正差异。

这可能是什么原因?是否有可能使用这两种方法获得几乎相同的相位,就像幅度一样?

python numpy opencv image-processing fft
1个回答
0
投票

鉴于

imFFTOpenCV
是一个 3D 数组,因为 OpenCV 不理解复数,
np.fft.fftshift(imFFTOpenCV)
将交换实平面和复平面。也就是说,移位发生在数组的所有 3 个维度中。

因此,在计算相位和幅度时,需要考虑这种交换:

magSpectrumOpenCV, phaseSpectrumOpenCV = cv2.cartToPolar(imFFTOpenCVShifted[:,:,1], imFFTOpenCVShifted[:,:,0])

或者,可能更易读,您可以告诉 NumPy 您想要移动哪些轴:

imFFTOpenCVShifted = np.fft.fftshift(imFFTOpenCV, axes=(0, 1))
© www.soinside.com 2019 - 2024. All rights reserved.