图像代表我在 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
来重新缩放一些数据。该数据中有 0
,np.log(0)
的结果是 -inf
。
您可以通过几种不同的方式解决此问题。最简单的选择是将 product
中的所有 -inf
值替换为 0
。创建 product
后,如果添加以下行:
product[np.isneginf(product)] = 0
然后当您绘制 product
时,它会像您预期的那样出现黑带:
深入研究
这就是您在 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
,正如您预期的那样。但是,如果您尝试直接绘制星等,您最终会得到一个非常暗的图,显示不多:
这是因为 Matplotlib 会在选择颜色时缩放数据,使图像数组中的最小值为黑色,最大值为白色。这里的问题是 magnitude
中的最大值比几乎所有其他值都大得多。因此,您会得到一些白色像素(靠近中心),而其他所有像素都接近黑色。
您可以通过将 vmax=1000
传递给您使用的 imshow
函数,使 magnitude
图显示更多的底层细节绘制图像。这为颜色图设置了一个明确的最大数据值:
这远非理想,因为这意味着图像的很大一部分显示为完全饱和的白色,而不管其底层细节如何。
实际上,您已经在代码中对这个问题进行了更好的修复:使用 np.log
以 magnitude
重新缩放数据。此重新缩放的结果 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/