OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现
一、问题 在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() 运行结果如下: 左边是原图,中间是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.imshow的显示结果,右边是plt.imshow的显示结果。显然,plt.imshow的结果出现了问题。 import cv2 import matplotlib.pyplot as plt #读入彩色图片 messi=cv2.imread('messi.jpg',1) #使用matplotlib.pyplot的imshow显示图片 plt.imshow(messi),plt.yticks([]) #隐藏坐标轴 plt.show() ##调换r、b通道,生成rgb顺序的图片并显示 b,g,r=cv2.split(messi) #通道的拆分 messi_rgb=cv2.merge((r,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文档才明白是咋回事。
大致的意思是说,cmap给出了标量值如何映射到颜色空间,并且对于RGB(A)图像此参数是忽略的;默认参数可查看 因此,为了解决该问题,使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() 运行结果为: 左边是cv2.imshow的显示结果,中间和右边的是plt.imshow的显示结果。 另外,cmap的值除了可以取默认参数及'gray'外,还有很多值可供我们选择,详细的说明在这里。其实这些东西了解下就行,等实际使用时,查阅下、试一试。根据需要选择合适的就可以了。
三、总结 由于OpenCV里的imshow和Matplotlib里的imshow的一些差异,在使用时主要是要注意两点: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |