OpenCV与Matplotlib imshow显示差异及通道处理方案

咖啡半糖
咖啡半糖
发布时间:2026-10-13 | 4人浏览过
原创

本文分析OpenCV与Matplotlib在图像显示上的核心差异。OpenCV以BGR顺序读取彩色图,直接plt.imshow会导致颜色失真,需手动交换通道;灰度图因默认cmap为'viridis'会显示伪彩色,需设置cmap='gray'。文章提供具体代码解决通道转换与灰度映射问题。

OpenCV与Matplotlib显示差异概述

一、问题

在Python开发中,通常使用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.imread中的“0”参数即可),运行结果如下:


左侧为原图,中间为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()

灰度图像cmap参数设置

灰度图

灰度图像为单通道图像,理论上不应出现上述彩色图那样的通道顺序问题,无论使用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()

运行结果为:


左侧为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 相关产品和应用

全部下载

专题列表