另外question人询问如何在使用cv2.dft时获得幅度和相位谱的正确方法.

我的回答仅限于麻木的方法,然后我想使用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")

Numpy results

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 results

正如您所看到的,虽然幅度谱看起来相同(由于浮点运算,它有一些预期的偏差),但相位谱看起来有很大的不同.我深入研究了一下,发现OpenCV通常返回从0到2π的阶段,而np.angle返回从-π到+π的阶段.不过,从opencv阶段减go π并不能纠正差异.

这可能是什么原因呢?有没有可能用这两种方法得到几乎相同的相位,就像震级一样?

推荐答案

假设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))

Python相关问答推荐

Pythind 11无法弄清楚如何访问tuple元素

TARete错误:类型对象任务没有属性模型'

根据不同列的值在收件箱中移动数据

什么相当于pytorch中的numpy累积ufunc

将图像拖到另一个图像

当从Docker的--env-file参数读取Python中的环境变量时,每个\n都会添加一个\'.如何没有额外的?

把一个pandas文件夹从juyter笔记本放到堆栈溢出问题中的最快方法?

在pandas中使用group_by,但有条件

形状弃用警告与组合多边形和多边形如何解决

根据列值添加时区

在Python中,从给定范围内的数组中提取索引组列表的更有效方法

在嵌套span下的span中擦除信息

跳过嵌套JSON中的级别并转换为Pandas Rame

交替字符串位置的正则表达式

如何在Gekko中使用分层条件约束

pandas:在操作pandora之后将pandora列转换为int

如果有2个或3个,则从pandas列中删除空格

有没有办法在不先将文件写入内存的情况下做到这一点?

在我融化极点数据帧之后,我如何在不添加索引的情况下将其旋转回其原始形式?

Seaborn散点图使用多个不同的标记而不是点