OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现


Posted in Python onNovember 25, 2019

一、问题

在Python里使用OpenCV时,一般是通过cv2.imread读入图片,然后用plt.imshow显示图片,但最近学习OpenCV时这样做的结果与预期的结果有较大的出入。查找资料后,才明白OpenCV里的imshow()和Matplotlib.pyplot的imshow()在使用上有一些区别,不注意的话很容易就会导致很奇怪的结果。

下面的示例代码及运行结果显示了这种差异:

import cv2
import matplotlib.pyplot as plt

#以灰度模式读入图片
messi=cv2.imread('messi.jpg',0)

#使用matplotlib.pyplot的imshow显示图片
plt.imshow(messi),plt.title('messi_plt')
plt.xticks([]),plt.yticks([]) #隐藏坐标轴
plt.show()

#使用opencv的imshow显示图片
cv2.imshow('messi_cv',messi)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下:

OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现

左边是原图,中间是cv2.imshow的显示结果,右边是plt.imshow的显示结果。很明显地看到,明明是读入灰度图,plt.imshow的结果却更像是张彩图,这显然是有问题的。

二、分析和解决办法

为了比较和分析OpenCV里imshow()和Matplotlib.pyplot里imshow()这两者的差异,下面分别对显示彩图以及显示灰度图这两种情况来进行说明。

彩色图

对于彩色图片,一般由R,G,B三个通道构成。然而,需要注意的是,OpenCV里彩色图片加载时是按照BGR的顺序,Matplotlib里彩色图片加载时是按照RGB的顺序。所以,当我们用cv2.imread读入图片,用cv2.imshow来显示时自然是不会出问题的,但若用plt.imshow来显示就会出现问题,如下面的结果所示。
这里省略示例代码(和上面的几乎相同,只是不要在cv2.imread里设置“0”这个参数即可),运行结果如下:

OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现

左边是原图,中间是cv2.imshow的显示结果,右边是plt.imshow的显示结果。显然,plt.imshow的结果出现了问题。
为了解决这个问题,方法很简单,就是将通道R和通道B的内容调换一下,再用plt.imshow显示时就正常了。下面给出该方法的示例代码:

import cv2
import matplotlib.pyplot as plt

#读入彩色图片
messi=cv2.imread('messi.jpg',1)

#使用matplotlib.pyplot的imshow显示图片
plt.imshow(messi),plt.title('messi_plt')
plt.xticks([]),plt.yticks([]) #隐藏坐标轴
plt.show()

##调换r、b通道,生成rgb顺序的图片并显示
b,g,r=cv2.split(messi) #通道的拆分
messi_rgb=cv2.merge((r,g,b)) #通道的融合
plt.imshow(messi_rgb),plt.title('messi_rgb_plt')
plt.xticks([]),plt.yticks([])
plt.show()

#使用opencv的imshow显示图片
cv2.imshow('messi_cv',messi)
cv2.waitKey(0)
cv2.destroyAllWindows()

灰度图

灰度图是单通道图片,按理说不会出现上面彩色图的那种问题,不管是用cv2.imshow显示还是用plt.imshow显示,结果都应该是一样的。然而,事实却并非如此(如最开始的示例所示)。我纠结了好久不知道原因是什么,一开始以为是opencv和matplotlib的版本不匹配,结果更新版本之后还是有这个问题。后来,去找来matplotlib的API文档才明白是咋回事。
matplotlib.pyplot.imshow函数里,有一个参数是cmap,API文档里给出的说明是:

cmap : str or Colormap, optional
The Colormap instance or registered colormap name used to map scalar data to colors. This parameter is ignored for RGB(A) data. Defaults to rcParams[“image.cmap”] = ‘viridis'.

大致的意思是说,cmap给出了标量值如何映射到颜色空间,并且对于RGB(A)图像此参数是忽略的;默认参数可查看rcParams[“image.cmap”]。链接转过去的文档是matplotlib的示例配置文档matplotlibrc,里面定义了各种变量的默认值(这也是为什么我们在调用matplotlib里的函数时,有些参数我们没给值也能正常运行的原因)。在这里能看到,cmap的默认值是viridis,这也就说明了在使用plt.imshow显示灰度图时出现问题的原因。

因此,为了解决该问题,使plt.imshow能正常地显示灰度图,方法也很简单,就是修改cmap的值为'gray'。示例代码如下:

import cv2
import matplotlib.pyplot as plt

#读入彩色图片
messi=cv2.imread('messi.jpg',0)

#使用opencv的imshow显示图片
cv2.imshow('messi_cv',messi)
cv2.waitKey(0)
cv2.destroyAllWindows()

#使用matplotlib.pyplot的imshow显示图片
#cmap使用默认值
plt.imshow(messi),plt.title('messi_camp_default')
plt.xticks([]),plt.yticks([]) #隐藏坐标轴
plt.show()

#使用matplotlib.pyplot的imshow显示图片
#cmap设置为'gray'
plt.imshow(messi,cmap='gray'),plt.title('messi_camp_gray')
plt.xticks([]),plt.yticks([]) #隐藏坐标轴
plt.show()

运行结果为:

OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现

左边是cv2.imshow的显示结果,中间和右边的是plt.imshow的显示结果。

另外,cmap的值除了可以取默认参数及'gray'外,还有很多值可供我们选择,详细的说明在这里。其实这些东西了解下就行,等实际使用时,查阅下、试一试。根据需要选择合适的就可以了。

注:
1.关于matplotlib里的imshow函数更详细的说明在这里。
2.关于matplotlib.matplotlibrc文档更详细的说明在这里。
3.如果想查看或编辑自己电脑里的matplotlibrc文件,可使用此命令matplotlib.matplotlib_fname()获取路径。

三、总结

由于OpenCV里的imshow和Matplotlib里的imshow的一些差异,在使用时主要是要注意两点:
1.显示彩色图时,要把b、r通道调换一下。
2.显示灰度图时,记得设置cmap的值为'gray'。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 基础学习第二弹 类属性和实例属性
Aug 27 Python
使用django-suit为django 1.7 admin后台添加模板
Nov 18 Python
Python实现的下载8000首儿歌的代码分享
Nov 21 Python
Python 读写文件和file对象的方法(推荐)
Sep 12 Python
简述Python2与Python3的不同点
Jan 21 Python
python2.7 安装pip的方法步骤(管用)
May 05 Python
Python实现的北京积分落户数据分析示例
Mar 27 Python
python 读txt文件,按‘,’分割每行数据操作
Jul 05 Python
python 使用递归的方式实现语义图片分割功能
Jul 16 Python
Python爬虫入门教程02之笔趣阁小说爬取
Jan 24 Python
Pycharm 跳转回之前所在页面的操作
Feb 05 Python
python和anaconda的区别
May 06 Python
Python解析json代码实例解析
Nov 25 #Python
python实现差分隐私Laplace机制详解
Nov 25 #Python
python3实现弹弹球小游戏
Nov 25 #Python
python数据化运营的重要意义
Nov 25 #Python
python实现拉普拉斯特征图降维示例
Nov 25 #Python
python模块hashlib(加密服务)知识点讲解
Nov 25 #Python
Python3如何对urllib和urllib2进行重构
Nov 25 #Python
You might like
PHP脚本的10个技巧(1)
2006/10/09 PHP
简化php模板页面中分页代码的解析
2009/02/06 PHP
PHP在引号前面添加反斜杠(PHP去除反斜杠)
2013/09/28 PHP
php反射应用示例
2014/02/25 PHP
PHP中设置一个严格30分钟过期Session面试题的4种答案
2014/07/30 PHP
php 无限级分类 获取顶级分类ID
2016/03/13 PHP
PHP图像处理 imagestring添加图片水印与文字水印操作示例
2020/02/06 PHP
判断客户端浏览器是否安装了Flash插件的多种方法
2010/08/11 Javascript
腾讯UED 漂亮的提示信息效果代码
2011/09/12 Javascript
eval的两组性能测试数据
2012/08/17 Javascript
JS获取网页属性包括宽、高等等
2014/04/03 Javascript
node.js实现多图片上传实例
2014/06/03 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
Jquery代码实现图片轮播效果(一)
2015/08/12 Javascript
js鼠标点击图片切换效果代码分享
2015/08/26 Javascript
关注jquery技巧提高jquery技能(前端开发必学)
2015/11/02 Javascript
微信小程序 websocket 实现SpringMVC+Spring+Mybatis
2017/08/04 Javascript
nodejs基于express实现文件上传的方法
2018/03/19 NodeJs
[01:15:45]DOTA2上海特级锦标赛B组小组赛#1 Alliance VS Spirit第一局
2016/02/26 DOTA
[01:02]DOTA2辉夜杯决赛日 CDEC.Y对阵VG赛前花絮
2015/12/27 DOTA
Python自动化构建工具scons使用入门笔记
2015/03/10 Python
简单介绍Python中的filter和lambda函数的使用
2015/04/07 Python
Python实现可获取网易页面所有文本信息的网易网络爬虫功能示例
2018/01/15 Python
python 获取指定文件夹下所有文件名称并写入列表的实例
2018/04/23 Python
wxPython绘图模块wxPyPlot实现数据可视化
2019/11/19 Python
多个python文件调用logging模块报错误
2020/02/12 Python
如何使用python记录室友的抖音在线时间
2020/06/29 Python
Html5新特性用canvas标签画多条直线附效果截图
2014/06/30 HTML / CSS
夏威夷航空官网:Hawaiian Airlines
2016/09/11 全球购物
美国Jeep配件购物网站:Morris 4×4 Center
2019/05/01 全球购物
小学教研工作制度
2014/01/15 职场文书
工程材料采购方案
2014/05/18 职场文书
车辆管理制度范本
2015/08/05 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书
Vue中foreach数组与js中遍历数组的写法说明
2021/06/05 Vue.js
MySQL Server层四个日志的实现
2022/03/31 MySQL