python - FFT 频谱中的 0 是白色的?,为什么? - 开放式简历

标签 python numpy opencv

enter image description here

图像代表我在 openCV 练习中使用傅里叶变换所做的事情。这是一个消除周期性噪声的练习。我正在检测发出噪音的波段,并使用 mask 将其删除。如您所见,我正在使用掩码从 dft_shift 中生成产品。我假设它的乘积为 0,我的问题是:如果该值为 0,为什么那条线是白色的???

代码:

dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)    #calcula la transf. Fourier 
dft_shift = np.fft.fftshift(dft) #proyecta los cuadrantes de la imagen 
dft_shift = dft_shift*mask2
f_ishift = np.fft.ifftshift(dft_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

完整脚本 Here

最佳答案

解决方案

如果打印出 product 图像数组中的值,您会发现白色带中的所有像素实际上都具有 -inf 的值,不是 0。在您的代码中,作为创建 product 过程的一部分,您使用 np.log 来重新缩放一些数据。该数据中有 0np.log(0) 的结果是 -inf

您可以通过几种不同的方式解决此问题。最简单的选择是将 product 中的所有 -inf 值替换为 0。创建 product 后,如果添加以下行:

product[np.isneginf(product)] = 0

然后当您绘制 product 时,它会像您预期的那样出现黑带:

enter image description here

深入研究

这就是您在 product 中以 -inf 结尾的原因。这是您的代码中创建 product 的行:

product = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))

如果我们把它分成两行,我们就能弄清楚发生了什么:

magnitude = cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1])
product = 20*np.log(magnitude)

magnitude 沿波段有 0,正如您预期的那样。但是,如果您尝试直接绘制星等,您最终会得到一个非常暗的图,显示不多:

enter image description here

这是因为 Matplotlib 会在选择颜色时缩放数据,使图像数组中的最小值为黑色,最大值为白色。这里的问题是 magnitude 中的最大值比几乎所有其他值都大得多。因此,您会得到一些白色像素(靠近中心),而其他所有像素都接近黑色。

您可以通过将 vmax=1000 传递给您使用的 imshow 函数,使 magnitude 图显示更多的底层细节绘制图像。这为颜色图设置了一个明确的最大数据值:

enter image description here

这远非理想,因为这意味着图像的很大一部分显示为完全饱和的白色,而不管其底层细节如何。

实际上,您已经在代码中对这个问题进行了更好的修复:使用 np.logmagnitude 重新缩放数据。此重新缩放的结果 product 数组的所有值将更接近。这样做的好处是,您可以在绘制 product 时看到图像中的细节。然而,你在这里遇到的问题是 0 的对数是无穷大:

print(np.log(0))
# this outputs
# -inf

因此,magnitude 中的 0 波段成为 product 中的 -inf 波段。 Matplotlib 处理这些 -inf 值的方法是将它们着色为与输入数组中的最大值相同的颜色(即白色)。因此,您会得到在绘制的 product 图像中看到的白色 strip 。

关于python - FFT 频谱中的 0 是白色的?,为什么? - 开放式简历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53693330/

相关文章:

python - 在 Django 管理命令中读取文件

python - 如何理解 Python 中 `None or False` 、 `False or None` 、 `None and False` 、 `False and None` 的结果?

c++ - 使用 opencv : VideoCapture 内存泄漏

c++ - 使用 NuGet 包将带有 Cuda 的 OpenCV 添加到 Visual Studio 程序中?

python - 无模式对话框 tkinter

python - 使用 Python "with"语句进行 ogr.open(file)

python - emacs-jedi 没有找到 numpy 完成

python - 平移/旋转 2D 点以改变视角

python - 求更高效的python numpy ravel+reshape

opencv - Adaboost 级联 TPR 和 FPR