python - FFT频谱中的0是白色的?,为什么?- OpenCV
问题描述
该图像代表了我在 openCV 练习中使用傅里叶变换所做的事情。这是一个消除周期性噪声的练习。我正在检测产生噪音的波段,并用面具将其删除。正如你所看到的,我正在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])
完整的脚本在这里
解决方案
解决方案
如果您打印出product
图像数组中的值,您会发现白色条带中的所有像素实际上的值都是-inf
,而不是0
。在您的代码中,作为创建过程的一部分,product
您可以使用np.log
重新调整某些数据。该数据中有0
',结果np.log(0)
是-inf
。
您可以通过几种不同的方式解决此问题。最简单的选择是将所有-inf
值product
替换为0
. 创建后product
,如果添加以下行:
product[np.isneginf(product)] = 0
那么当您绘制product
它时,它将有黑色条带,就像您预期的那样:
深潜
这就是您最终以-inf
in结尾的原因product
。这是您的代码中创建的行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 会在选择颜色时缩放您的数据,以便图像数组中的最小值为黑色,最大值为白色。这里的问题是 in 中的最大值magnitude
远大于几乎所有其他值。因此,您会得到几个白色像素(靠近中心),而其他每个像素都被染成几乎黑色。
您可以通过传递给用于绘制图像的函数来使绘图magnitude
显示更多的底层细节。这为颜色图设置了一个明确的最大数据值:vmax=1000
imshow
这远非理想,因为这意味着图像的很大一部分显示为完全饱和的白色,而不管其底层细节如何。
实际上,您已经在代码中为这个问题提供了更好的解决方案:您在magnitude
using中重新调整数据np.log
。这种重新缩放的结果,product
数组,将使其所有值更接近。这有利于您在绘图时看到图像中的精细细节product
。但是,您在这里遇到的问题是 0 的日志是无穷大的:
print(np.log(0))
# this outputs
# -inf
因此, in 的带成为in0
的带。Matplotlib通过将它们着色为与输入数组中的最大值相同的颜色(即白色)来处理这些值。因此,您会得到您在绘制的图像中看到的白色带。magnitude
-inf
product
-inf
product
推荐阅读
- javascript - 除非我刷新,否则 React 侧边栏菜单项不会更新活动状态
- javascript - React:子组件中的陈旧道具
- python - 使用networkx计算模块化
- node.js - 无法将 Uint8List/ 缓冲区图像上传到服务器 http 颤振
- google-cloud-platform - gcloud alpha 监控策略创建 --policy-from-file 抛出错误“必须在过滤器中指定对“resource.type”的限制”
- python - 将 bytearray 转换为 array.array('B')
- amazon-web-services - 我可以只在 CodeBuild 中构建应用程序一次,然后使用构建矩阵对其运行并行赛普拉斯测试吗?
- java - Jackson YAML 使用父对象和对象数组进行解析
- javascript - 悬停时显示地图标记
- javascript - 如何通过 Node + Express + Mongoose 中的单选按钮传递布尔值?