图像的读取与保存是图像处理或计算机视觉领域中最基本的操作,python中有众多的库支持图像的读取、显示与存储,常用的库包括 matplotlib、skimage 和 Pillow 库。使用时,首先测试测试是否安装了 skimage 和 PIL 库。如果没有安装,可以通过 Anaconda-prompt-pip install pillow 和 pip install scikit-image 进行安装。
本部分内容所用的数据放在百度网盘:
链接: https://pan.baidu.com/s/1DXKTofRWufhVpP_HEQKk9A 提取码: pl5u。
下载到本地,置于代码文件同级目录的新建文件夹“images”即可。
Pillow 是 Python 中较为基础的图像处理库,主要用于图像的基本处理,比如裁剪图像、调整图像大小和图像颜色处理等。与 Pillow 相比,OpenCV 和 Scikit-image 的功能更为丰富,所以使用起来也更为复杂,主要应用于机器视觉、图像分析等领域,比如众所周知的“人脸识别”应用 。
from PIL import Image
import matplotlib.pylab as plt
# 图像的读入
im = Image.open("images/parrot.png")
# 显示图像的宽和高,以及图像的颜色通道
print(im.width, im.height, im.mode, im.format, type(im))
plt.axis('off')
plt.imshow(im)
图片进入到内存中,参与运算的主要是矩阵。Pillow 库读取的图像对象无法直接进行数字运算,需要先将图像对象转化成 ndarray形式。图像像素值有两种取值范围,一种是0~255,一种是0~1.
import numpy as np
mat = np.array(im).astype('float')# 转化为 ndarray 形式(像素值为 uint8 类型),且像素值更改为浮点数
mat[0:10,0:10,0]
输出结果
array([[67., 68., 67., 67., 68., 67., 68., 68., 68., 68.],
[69., 68., 68., 68., 68., 68., 69., 68., 68., 68.],
[70., 71., 69., 67., 67., 69., 71., 71., 71., 69.],
[71., 71., 68., 66., 67., 70., 71., 72., 72., 71.],
[70., 69., 68., 67., 66., 69., 70., 71., 72., 71.],
[67., 69., 68., 68., 68., 69., 69., 70., 71., 71.],
[69., 70., 70., 70., 69., 68., 67., 69., 70., 70.],
[69., 69., 69., 70., 70., 68., 67., 67., 68., 68.],
[69., 69., 69., 69., 70., 68., 67., 67., 68., 70.],
[69., 69., 69., 69., 70., 70., 68., 68., 69., 72.]])
我们也可以将 ndarray 格式的矩阵转化成图像对象, 在对图像放缩的时候只有图像格式的数据才能操作, 通过自动插值的方式获得, 而矩阵很难轻松地进行放缩. 这种格式的转换需要用的 PIL.Image.fromarray() 完成此操作.
from skimage.io import imread
import matplotlib.pylab as plt
im = imread("images/parrot.png")
print(im.shape, im.dtype, type(im))
plt.figure(figsize=(10,10))
plt.imshow(im)
plt.axis('off')
plt.show()
sk-image 库读取的图像对象同样无法直接进行数字运算,需要先将图像对象转化成 ndarray形式。
import numpy as np
mat = np.array(im).astype('float')# 转化为 ndarray 形式(像素值为 uint8 类型),且像素值更改为浮点数
mat[0:10,0:10,0]
输出
array([[67., 68., 67., 67., 68., 67., 68., 68., 68., 68.],
[69., 68., 68., 68., 68., 68., 69., 68., 68., 68.],
[70., 71., 69., 67., 67., 69., 71., 71., 71., 69.],
[71., 71., 68., 66., 67., 70., 71., 72., 72., 71.],
[70., 69., 68., 67., 66., 69., 70., 71., 72., 71.],
[67., 69., 68., 68., 68., 69., 69., 70., 71., 71.],
[69., 70., 70., 70., 69., 68., 67., 69., 70., 70.],
[69., 69., 69., 70., 70., 68., 67., 67., 68., 68.],
[69., 69., 69., 69., 70., 68., 67., 67., 68., 70.],
[69., 69., 69., 69., 70., 70., 68., 68., 69., 72.]])
matplotlib.image 库中的 imread() 函数可以读取浮点 numpy ndarray 中的图像,像素值表示为 [0,1] 中的真值。
import matplotlib.pylab as plt
import matplotlib.image as mpimg
im = mpimg.imread("images/parrot.png")
print(im.shape,im.dtype,type(im))# 读入的图像包含R、G、B、alpha 四个通道,可通过 convert 进行其它格式的转换不能直接imshow输出
plt.figure(figsize=(10,10))
plt.imshow(im)
plt.axis('off')
plt.show()
利用 matplotlib.image 库读的图片本身就是 ndarray 类型,且像素点格式为浮点数,因此,无需额外进行数字格式的转换。
im[0:5,0:5,0]
输入结果
array([[0.2627451 , 0.26666668, 0.2627451 , 0.2627451 , 0.26666668],
[0.27058825, 0.26666668, 0.26666668, 0.26666668, 0.26666668],
[0.27450982, 0.2784314 , 0.27058825, 0.2627451 , 0.2627451 ],
[0.2784314 , 0.2784314 , 0.26666668, 0.25882354, 0.2627451 ],
[0.27450982, 0.27058825, 0.26666668, 0.2627451 , 0.25882354]],
dtype=float32)
注意:如需将图像保存在本地,可添加代码:im.save(‘本地文件夹路径’)即可,如im.save(“images/parrot_save.jpg”)