前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python图像处理库-PIL获取图像的数值矩阵

Python图像处理库-PIL获取图像的数值矩阵

作者头像
触摸壹缕阳光
发布2021-04-07 11:32:26
2.1K0
发布2021-04-07 11:32:26
举报

上一小节已经介绍了如何安装 PIL 以及 Image 类的简单使用,比如从当前路径下加载名为 shiliu.jpg 的图像。

代码语言:javascript
复制
from PIL import Image

img = Image.open(r'./shiliu.jpg')
print(type(img)) # 返回Image对象
# <class 'PIL.JpegImagePlugin.JpegImageFile'>

print(img.format) # 图像的格式
# JPEG
print(img.size) # 图像的尺寸
# (1920, 1920)
print(img.mode) # 图像的模式
# RGB

我们知道 RGB 图像实际上是由三个相同形状的数值矩阵横向拼接而成的,数值矩阵中的每个元素值的范围为 (0, 255)。

RGB 图像(不同模式的数值矩阵排列可能不同)每个像素点呈现的颜色由三个数值矩阵对应位置的三个值决定,可以用一个三元组来表示,比如图示中的像素点 A 表示为 RGB(255, 0, 255),像素点 B 表示为 RGB(127, 255, 0)。换句话说,图像中的每个像素点由三元组中的三个值决定,大家比较熟悉的纯红色表示为 RGB(255, 0, 0),纯黑色表示为 RGB(0, 0, 0),纯白色表示为 RGB(255, 255, 255)

如何获取这些数值矩阵呢?PIL 提供了 PIL.Image.getdata(band = None) 方法,用来获取 Image 对象中的这些数值矩阵。getdata() 函数返回的是包含图像像素内容的 ImagingCore 对象(类似序列的一个对象),此时的 ImagingCore 对象是一个 PIL 内部的数据类型。我们可以使用 list(img.getdata()) 将其转换成 Python 的 list 对象。

代码语言:javascript
复制
from PIL import Image

img = Image.open(r'./shiliu.jpg')

print(type(img.getdata()))
# <class 'ImagingCore'>

print(list(img.getdata())) # 转换为list类型
# [(76, 67, 70), (64, 55, 58), (59, 50, 53), (59, 50, 53), (56, 47, 50) ...]

getdata() 函数会将图像的像素点逐行地进行拼接,每一个像素点用 RGB 三元组表示(图像为 RGB 模式时)。

代码语言:javascript
复制
pixel_width, pixel_height = img.size[0], img.size[1]
pixel = pixel_width * pixel_height

print(pixel)
# 3686400
print(len(list(img.getdata())))
# 3686400

图像的像素点与通过 getdata() 函数返回的像素点个数相同。

如果只想获取 RGB 图像三个通道中的某一个通道,可以为 getdata() 函数指定 band 参数:

  • band = None 时(默认),返回图像所有通道的像素点;
  • band = 0 时,返回第一个通道的数值,即 RGB 中的 R 通道;
  • band = 1 时,返回第二个通道的数值,即 RGB 中的 G 通道;
  • band = 2 时,返回第三个通道的数值,即 RGB 中的 B 通道;
代码语言:javascript
复制
print(list(img.getdata())) # 返回图像所有通道的像素点
# [(76, 67, 70), (64, 55, 58), (59, 50, 53), (59, 50, 53), (56, 47, 50) ...]

print(list(img.getdata(band = 0))) # 返回第一个通道的数值
# [76, 64, 59, 59, 56 ...]
print(list(img.getdata(band = 1))) # 返回第二个通道的数值
# [67, 55, 50, 50, 47 ...]
print(list(img.getdata(band = 2))) # 返回第三个通道的数值
# [70, 58, 53, 53, 50 ...]

getdata() 函数会将 RGB 图像的像素点(用三元组表示)逐行地进行拼接,而指定 band 参数,返回单个通道的数值同样也是逐行进行拼接的,只不过此时不是像素点而是单个数值。简单来说,就是将对应通道的数值矩阵逐行进行拼接。

有了这些逐行拼接的像素点或单个数值,接下来可以对这些像素点或数值进行一系列的操作。

这种获取和操作图像像素的方式比较麻烦,并且在深度学习中,图像完整的数值矩阵可能更为常用。其实我们可以直接将 Image 对象转换为熟悉的 NumPy 数组,然后直接通过 NumPy 中的函数来获取和操作图像像素。

代码语言:javascript
复制
import numpy as np

img_array = np.asarray(img)
print(img_array.shape)
# (1920, 1920, 3)

想要获取单个通道,只需要对数组进行索引。

代码语言:javascript
复制
print(img_array[:, :, 0].shape) # R通道的数值矩阵
# (1920, 1920)
print(img_array[:, :, 1].shape) # G通道的数值矩阵
# (1920, 1920)
print(img_array[:, :, 2].shape) # B通道的数值矩阵
# (1920, 1920)

将 Image 对象转换为 NumPy 数组,我们可以不调用 Image 对象的 show() 函数来显示图像,可以直接通过 Matplotlib 模块显示图像(避免调用 Image 类对象的 show() 方法出现效率等问题) 。

代码语言:javascript
复制
import matplotlib.pyplot as plt

plt.imshow(img_array)
plt.show()
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档