FFT频谱中的0是白色的?,为什么?开放式CV

2024-04-29 01:51:09 发布

您现在位置:Python中文网/ 问答频道 /正文

enter image description here

这张图片代表了我在openCV练习中使用Fourier变换所做的工作。这是一个消除周期性噪音的练习。我正在检测产生噪音的波段,并用一个遮罩将其删除。如您所见,我使用的是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


Tags: fftimgshiftnpback图片代表cv2
1条回答
网友
1楼 · 发布于 2024-04-29 01:51:09

解决方案

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

你可以用几种不同的方法来解决这个问题。最简单的选择是将product中的所有-inf值替换为0。创建product之后,如果添加以下行:

product[np.isneginf(product)] = 0

然后,当您绘制product时,它将具有黑色带,如您所预期的:

enter image description here

深潜

下面是您在product中得到-inf的原因。这是代码中创建product的行:

^{pr2}$

如果我们把它分成两行,我们就可以知道发生了什么:

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

magnitude有{}的谱带,如你所料。但是,如果您尝试直接绘制震级图,最终会得到一个非常暗的图,但不会显示太多:

enter image description here

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

通过将vmax=1000传递给用于绘制图像的imshow函数,可以使magnitude的绘图显示更多的底层细节。这将为colormap设置显式的最大数据值:

enter image description here

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

实际上,在代码中已经有了更好的解决方法:使用np.log重新缩放magnitude中的数据。重新缩放的结果是product数组的所有值将更加接近。这有利于您在绘制product时看到图像中的细节。但是,您在这里遇到的问题是0的对数是无穷大的:

^{4}$

因此,在magnitude中的0带成为product中的{}带。Matplotlib处理这些-inf值,方法是将它们着色为与输入数组中的最大值相同的颜色(例如白色)。这样,您就得到了在绘制的product图像中看到的白色条纹。在

相关问题 更多 >