Python用于数字图像处理时,常用的一个第三方库是PIL,全称为:Python Imaging Library。 PIL由Fredrik Lundh和一些志愿者开发,是Python平台一个功能较强而简单易用的图像处理库,但好像只能支持到Python 2.7版。后来Alex Clark和一些志愿者开发了PIL的一个Fork(大概为 “克隆”的意思),创建了兼容 Python 3 的Pillow。“Pillow is the friendly PIL fork”,这是[1]的第一句。
在图像处理方面,Pillow包含了基本的功能,包括点操作、用卷积核进行过滤、色彩空间转换等。 该库也支持图像的大小调整、旋转和任意仿射变换。 还可以通过直方图方法从图像中提取一些统计信息,用于自动对比度增强和全局统计分析。
本文是笔者学习和练习Pillow的笔记,软件环境是Windows10,PyCharm社区版和Jupyter Lab。主要内容来自文献 [1-2],并参考了[3]-[8]等文献。
注意,安装Pillow 之前,必须先卸载 PIL,具体的安装和升级方法可参见[1]中的Installation。
Pillow库包含基本的图像处理功能,包括点操作、使用一组内置卷积核进行过滤以及色彩空间转换。 该库还支持图像大小调整、旋转和任意仿射变换。 有一种直方图方法允许您从图像中提取一些统计信息。 这可用于自动对比度增强和全局统计分析。
PIL中最重要的类是 Image 类,在一个同名的模块中定义。可以通过多种方式创建此类的实例,例如从图像文件加载图像,处理其他图像,或创建新图像。 从图像文件加载图像时要使用 Image 模块中的 open() 函数:
>>> from PIL import Image
>>> im = Image.open("hopper.ppm")
如果成功,此函数将返回一个 Image 对象。 您现在可以使用实例属性来检查文件内容:
>>> print(im.format, im.size, im.mode)
PPM (512, 512) RGB
其中,format 属性用来标识图像来源,如果图像并不是从文件中读取的则其值为 None;size 属性是一个包含宽度和高度(以像素为单位)的 2 元数组; mode 属性给出图像中通道的数量和像素类型等信息。 常见的模式有“L”(亮度)用于灰度图像,“RGB”用于真彩色图像,“CMYK”用于印前图像。
如果无法打开文件,则会引发 OSError 异常。一旦有了 Image 类的实例,就可以使用该类的方法来处理和操作图像。 例如,让我们显示刚刚加载的图像:
>>> im.show()
PIL支持多种图像文件格式。 从磁盘读取文件,应使用 Image 对象的 open()方法,保存文件则用 save() 方法。在这两个方法中,绝对路径和相对路径都可以使用。
--------------------------------------------------------
例1
from PIL import Image
im = Image.open("./雪山草原.jpg") # 使用相对路径
print(im.size, im.mode, im.format, type(im))
# (532, 492) RGB JPEG
im.show()
---------------------------------------------------------
雪山草原.jpg 雪山草原_gray.png
例2
im_g = im.convert('L') # 把例1的jpg彩色图像im转换成黑白灰度图像im_g
print(im_g.size, im_g.mode, im_g.format, type(im_g))
# (532, 492) L None
#保存im_g,这里使用了绝对路径。我们使用扩展名 .png,使得文件被保存为png格式的文件。
im_g.save('D:\PYthon\pythonProject\Py-ImagePro\配套代码\雪山草原_gray.png')
# 打开并显示雪山草原_gray.png
imm = Image.open("./雪山草原_gray.png")
print(imm.size, imm.mode, imm.format, type(imm))
# (532, 492) L PNG
imm.show()
----------------------------------------------------------
注1:save() 可以接收第二个参数,用于指定文件格式。使用非标准扩展名时,必须以这种方式指定格式。
----------------------------------------------------------
例3 把im_g保存为'JPEG'格式的图像文件: 雪山草原_gray.pm
im_g = im.convert('L') # 把例1的png彩色图像im转换成黑白灰度图像im_g然后保存到文件夹,
im_g.save('./雪山草原_gray.pm', 'JPEG')
imm = Image.open("./雪山草原_gray.pm")
print(imm.size, imm.mode, imm.format, type(imm))
# (532, 492) L JPEG
imm.show()
-------------------------------------------------------------
由于扩展名为pm,Windows的照片软件不能识别此文件,但仍可用IE打开,如上图。
将文件转换为 JPEG
例4 用法参见例6
--------------------------------------------------
import os, sys
from PIL import Image
for infile in sys.argv[1:]:
f, e = os.path.splitext(infile)
outfile = f + ".jpg"
if infile != outfile:
try:
with Image.open(infile) as im:
im.save(outfile)
except OSError:
print("cannot convert", infile)
----------------------------------------------
创建 JPEG 缩略图
例5 用法参见例6 ,sys.argv[1:]参见注3。
-----------------------------------
import os, sys
from PIL import Image
size = (128, 128)
for infile in sys.argv[1:]:
outfile = os.path.splitext(infile)[0] + ".thumbnail"
if infile != outfile:
try:
with Image.open(infile) as im:
im.thumbnail(size)
im.save(outfile, "JPEG")
except OSError:
print("cannot create thumbnail for", infile)
--------------------------------------
注2,除非确实需要,PIL不会加载所有的图像数据。打开文件时,它会先读取文件头以确定文件格式并提取解码文件所需的模式、大小和其他属性等信息。
例6 为两个图像文件创建缩略图,在命令窗口中操作
1)当前文件夹没有.thumbnail文件,但有4个.jpg图像文件如下:
---------------------------------------------------
D:\PYthon\pythonProject\Py-ImagePro\配套代码>dir *.jpg
2021/08/10 17:34 147,512 face.jpg
2021/06/01 18:23 70,780 hill.jpg
2021/06/08 16:12 24,958 messi.jpg
2021/08/10 17:35 22,177 parrot.jpg
4 个文件 265,427 字节
2)我们在当前目录建立了一个文件test.py,其内容就是例5中的语句;
3)在当前目录执行语句 python test.py face.jpg hill.jpg 如下
D:\PYthon\pythonProject\Py-ImagePro\配套代码>python test.py face.jpg hill.jpg
4)可以看到当前目录刚刚新增了两个thumbnail文件
D:\PYthon\pythonProject\Py-ImagePro\配套代码>dir *.thumbnail
D:\PYthon\pythonProject\Py-ImagePro\配套代码 的目录
2021/08/22 11:42 4,061 face.thumbnail
2021/08/22 11:42 1,458 hill.thumbnail
2 个文件 5,519 字节
---------------------------------------------------------------------------
注3, sys.argv其实就是一个元组,里边的项为用户输入的参数。注意参数是从程序外部输入的,而与代码本身无关。将程序保存后从外部来运行并列出参数,就可以看到它的效果。参见例6。
识别图像文件
例7 用法参见例6,该程序可用于判别一组文件是否图像文件
--------------------------------------
import sys
from PIL import Image
for infile in sys.argv[1:]:
try:
with Image.open(infile) as im:
print(infile, im.format, f"{im.size}x{im.mode}")
except OSError:
pass
----------------------------------------------
3 剪切、粘贴与合并Cutting, pasting, and merging images
Image 类包含操作图像中的区域的方法。 从图像中提取子矩形可用crop() 方法。
(待续)