OpenCV阈值分割,Matplotlib绘制Trunc方法分割的结果不合预期

Matplotlib显示Trunc和TOZERO_INV阈值分割结果不合预期

笔者在学习到OpenCV的阈值分割时,试图用Matplotlib显示分割以后的图片。
阈值分割方法

我用于处理的图片如图:
用于处理的图片

使用THRESH_TRUNC模式分割,代码如下:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('gradient.jpg', 0)

ret, th = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)

plt.figure(figsize=(8, 6), dpi=100)
plt.imshow(th, 'gray')

预期呈现的图片如图:
预期呈现的图片

然而输出结果并不符合我的预期——
输出结果

经检查发现,以灰度图模式读入、再用THRESH_TRUNC或THRESH_TOZERO_INV模式处理后,都会产生类似的不合预期的结果;而以彩色图模式读入文件作同样处理,产生的结果就是符合预期的:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('gradient.jpg', 0)

ret, th = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
plt.figure(figsize=(8, 6), dpi=100)

plt.imshow(th, 'gray')

再次运行,产生了符合预期的结果。

事后笔者分析认为,问题出在matplotlib不能区别灰度图与二维数组,误将我们的灰度图当作二维数组处理,从而导致了错误的结果。具体分析如下——

因为一个彩色图像传入opencv处理成灰度图,从opencv的角度无非就是把一个三维数组通过计算转换成另一个二维数组;但是matplotlib并不会把二维数组当作灰度图,所以把这个“灰度图”给matplotlib绘制的时候,它绘制的其实是这个二维数组的可视化图像,这样matplotlib画出的图像就有可能和opencv画出来的不一样。笔者画图的时候调了一下matplotlib的colorbar,发现cmap设置成’gray’时,它默认把二维数组的元素取值的最大值设置为白色 ,最小值设置为黑色,证实了我的猜测:
调出colorbar,终于露出了马脚
(使用其他分割方法也存在这样的问题,只是其他分割方式分割完毕后数组元素的取值范围为[0, 255],正好避免了这样的问题。)

鉴于此,建议各位以后再使用matplotlib绘图时不应直接在自己的程序内把图像转换为灰度图,否则有可能产生错误的绘图结果。笔者建议通过其他软件将彩色图转化为灰度图后再以彩色图模式传入matplotlib绘图。

参考资料:http://codec.wang/#/opencv/start/06-image-thresholding
OpenCV官方文档
matplotlib官方文档

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值