您的位置:首页 > 运维架构

凡哥OpenCV基础入门教程(跳一跳专题)-CH1.2_通过Matplotlib展示图片

2018-03-16 20:58 741 查看
原创作品,转载请注明出处!!

0. 概要

opencv读入的图片, 我们如何来显示它? Python科学计算里面有一个著名的可视化包, 名字叫做Matplotlib . 本期凡哥会教大家对opencv读取的图像进行颜色空间变换(cvtColor), 然后分别用matplotlib显示RGB图跟灰度图。

1. 引入matplotlib的包

引入
pyplot
并起别名为plt
1from matplotlib import pyplot as plt
使用
cv2
读入图片. 读入彩图.
1import cv2
2# 导入一张图像 模式为彩色图片
3img = cv2.imread('cat.jpg', cv2.IMREAD_COLOR)
显示图片
1plt.imshow(img)
隐藏画布的坐标系, 并展示图片.
1# 隐藏坐标系
2plt.axis('off')
3# 展示图片
4plt.show()

2. plt错把BGR当作RGB

如果你跟着凡哥一步步做, 你肯定可以得到下面这个阴森森的图片.

cat_wrong_rgb.png因为matploblib的图片格式, 默认是RGB格式的, 之前凡哥讲过opencv 因为历史原因, 读入的图片的格式是BGR的.所以,
R
通道变成了
B
通道,
B
通道变成了
R
通道, 所以才会这样.

3. 颜色空间的转换-cvtColor

如果我们要实现图片的正确读取, 就需要将图片的颜色空间进行转换. 需要用到opencv中的
cvtColor
函数.使用方法如下
1newImg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
传入的
img
就是源图像, 然后你要告诉
cvtColor
函数, 从哪个格式转变成另外哪种格式的图片.
2
在编程里经常被用作
to
的意思, to 转变为的意思.
COLOR_BGR2RGB
的含义是从BGR颜色空间转变为RGB颜色空间.那么如何才能知道opencv都支持哪些颜色空间的转换呢?大家不妨跟凡哥一起打开
ipython
的终端, 然后引入
cv2
模块, 敲入
cv2.COLOR_
然后按
Tab
键, ipython会提示,所有以cv2.COLOR_开头的变量, 哇, 好多诶, 不着急, 我们现在只需要用到其中几个. 凡哥好像经常说别着急, 慢慢学之类的话, 是不是? 学习真的急不得, 以前我就是这么急躁的一个人.欲速则不达. 凡哥还需要你再注意另外一个
cv2.COLOR_BGR2GRAY
就是将BGR格式的图片转变为灰度图.

0120_color_space_cvt.png

4. Matplotlib显示图片-正确演示

我们来看一下完整版本的程序.学员
@大漠沧澜
反馈说, 程序前一定要加一个
# -*- coding: utf-8 -*-
要不然打印汉语会出错.凡哥记住了, 之后的代码都会加一个头. ps: 凡哥的Linux上默认就是UTF-8编码, 给大家带来的不便很是抱歉.代码见
CH1.2_ImageDisplayByMatplotlib.py
1# -*- coding: utf-8 -*-
2import numpy as np
3import cv2
4# 引入Python的可视化工具包 matplotlib
5from matplotlib import pyplot as plt
6
7# 导入一张图像 模式为彩色图片
8img = cv2.imread('cat.jpg', cv2.IMREAD_COLOR)
9
10# plt.imshow(img)
11# 直接绘制 ndarray 颜色很诡异
12# 原因是opencv读取到的图片是BGR格式的,Matplotlib按照RGB格式解析的
13# 所以我们需要将颜色空间转换
14plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
15
16# 隐藏坐标系
17plt.axis('off')
18# 展示图片
19plt.show()
显示效果:

Screenshot_20171211_190042.png

5. 转变为灰度图并显示

按照之前我们的思路, 使用cvtColor 将色彩空间从BGR转变为灰度图, 不就好了吗 , 我们来试一下。
1# -*- coding: utf-8 -*-
2import numpy as np
3import cv2
4# 引入Python的可视化工具包 matplotlib
5from matplotlib import pyplot as plt
6
7# 导入一张图像 模式为彩色图片
8img = cv2.imread('cat.jpg', cv2.IMREAD_COLOR)
9
10# 将色彩空间转变为灰度图并展示
11gray  = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
12
13plt.imshow(gray)
14
15# 隐藏坐标系
16plt.axis('off')
17# 展示图片
18plt.show()


0120_cat_gray_wrong.png天啊噜, 这个更恐怖了, 我们来打印一下图片的信息。
1def print_img_info(img):
2    print("================打印一下图像的属性================")
3    print("图像对象的类型 {}".format(type(img)))
4    print(img.shape)
5    print("图像宽度: {} pixels".format(img.shape[1]))
6    print("图像高度: {} pixels".format(img.shape[0]))
7    # GRAYScale 没有第三个维度哦, 所以这样会报错
8    # print("通道: {}".format(img.shape[2]))
9    print("图像分辨率: {}".format(img.size))
10    print("数据类型: {}".format(img.dtype))
1print_img_info(gray)
这里是图片信息
1图像对象的类型 <class 'numpy.ndarray'>
2(182, 277)
3图像宽度: 277 pixels
4图像高度: 182 pixels
5图像分辨率: 50414
6数据类型: uint8
可以看到, 不同与彩色图, grascale没有第三个维度, 是一个扁平的二维矩阵。 我们选择灰度图的部分, 打印出来看一下。
1print("打印图片局部")
2print(gray[100:105, 100:105])
roi图片像素点格式如下。
1打印图片局部
2[[221 221 221 221 219]
3 [220 220 220 220 219]
4 [219 219 219 219 218]
5 [219 219 219 219 218]
6 [214 215 215 216 216]]

6. 给matplotlib添加cmap 显示灰度图

为什么我们给matplotlib传入一个矩阵,matplotlib却傻傻的分不清颜色, 不能转变为我们想要的灰度图呢?原因在于, 我们需要给matplotlib给定一个颜色映射函数。也就是从数值转变为颜色的映射。我们称之为
color map
, 在matplotlib里面简称为
cmap
.所有的颜色阈值, 可以在matplotlib的文档里看到:color example code: colormaps_reference.py

0120_colormaps_reference_02.png
1# Have colormaps separated into categories:
2# http://matplotlib.org/examples/color/colormaps_reference.html 3cmaps = [('Perceptually Uniform Sequential', [
4            'viridis', 'plasma', 'inferno', 'magma']),
5         ('Sequential', [
6            'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
7            'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
8            'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
9         ('Sequential (2)', [
10            'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
11            'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
12            'hot', 'afmhot', 'gist_heat', 'copper']),
13         ('Diverging', [
14            'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
15            'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
16         ('Qualitative', [
17            'Pastel1', 'Pastel2', 'Paired', 'Accent',
18            'Dark2', 'Set1', 'Set2', 'Set3',
19            'tab10', 'tab20', 'tab20b', 'tab20c']),
20         ('Miscellaneous', [
21            'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
22            'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg', 'hsv',
23            'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar'])]
我们这里需要用到其中一个均衡组里面的
gray
颜色映射。 其中最黑代表
0
, 最亮代表
255
凡哥喜欢在教程里堆很多图片, 可以帮助大家理解。

0120_colormapManip_03.png关键语句
1# 需要添加colormap 颜色映射函数为gray
2plt.imshow(gray, cmap="gray")
完整版本的程序
CH1.2_ImageDisplayByMatplotlib_Grayscale.py
1# -*- coding: utf-8 -*-
2import numpy as np
3import cv2
4# 引入Python的可视化工具包 matplotlib
5from matplotlib import pyplot as plt
6
7def print_img_info(img):
8    print("================打印一下图像的属性================")
9    print("图像对象的类型 {}".format(type(img)))
10    print(img.shape)
11    print("图像宽度: {} pixels".format(img.shape[1]))
12    print("图像高度: {} pixels".format(img.shape[0]))
13    # GRAYScale 没有第三个维度哦, 所以这样会报错
14    # print("通道: {}".format(img.shape[2]))
15    print("图像分辨率: {}".format(img.size))
16    print("数据类型: {}".format(img.dtype))
17
18# 导入一张图像 模式为彩色图片
19img = cv2.imread('cat.jpg', cv2.IMREAD_COLOR)
20
21# 将色彩空间转变为灰度图并展示
22gray  = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
23
24# 打印图片信息
25# print_img_info(gray)
26
27# 打印图片的局部
28# print("打印图片局部")
29# print(gray[100:105, 100:105])
30
31# plt.imshow(gray)
32# 需要添加colormap 颜色映射函数为gray
33plt.imshow(gray, cmap="gray")
34
35# 隐藏坐标系
36plt.axis('off')
37# 展示图片
38
39plt.show()
40# 你也可以保存图片, 填入图片路径就好
41# plt.savefig("cat_gray_01.png")
然后我们显示一下效果。

Screenshot_20171211_190317.png

7. 课后作业

本期凡哥介绍使用
matplotlib
显示cv2读入的照片就到此结束了。给大家留一个小作业, 如果我们不使用
cvtColor
函数, 如何使用numpy的函数完成从BGR到RGB颜色格式的转换呢?再次重复一下, 如果你不了解numpy, 请看凡哥写的numpy教程。你需要花一些时间, 掌握这些操作。Numpy快速入门-凡哥带你玩转Python科学计算 因为凡哥在给大家教授python-opencv, 而在python-opencv读入一个图片对象就是numpy的ndarray类型, 所以凡哥有必要在这里给大家讲解一下numpy的一些基础操作. 同时还会介绍numpy中两个重要的概念全局函数与广播. 最后凡哥还介绍了numpy下面的两个包, linalg线形代数计算包与random随机生成包.另外一种显示图片的方法, 是opencv自带的
HighGUI
, 凡哥下次课程会给大家讲解.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息