一、PIL简介
PIL(Python Imaging Library)是Python平台上图像处理标准库,功能强大,使用简单。PIL默认仅支持到Python2.7,如果要支持Python3.x版本,必须使用兼容PIL的新版本–Pillow,Pillow中加入了相比于PIL更多的新特性。
官方文档:
• PIL官网:http://effbot.org/zone/pil-index.htm • PIL支持版本文档:http://www.pythonware.com/products/pil/ • Pillow官网:https://python-pillow.org/ • Pillow文档:https://pillow.readthedocs.io/en/stable/ • Pillow Github网址:https://github.com/python-pillow/Pillow
Pillow 安装方式(以Pillow 5.2.0版本为例):
- 方法1、
pip install Pillow==5.2.0
- 方法2、
conda install -c anaconda pillow==5.2.0
默认情况下,Anaconda中是默认会安装最新版本的Pillow或者PIL的。
查看当前PIL或Pillow版本:
PIL 和Pillow 的兼容:
基本上PIL模块中的代码在Pillow中都是一样的,主要有以下两个方面需要特别注意:
1、PIL中直接使用Image模块,在Pillow中需要使用from PIL import Image
导入对应模块。
2、PIL中可以直接使用_imaging模块,在Pillow中该模块的名字更换为
core,也就是必须使用如下导入命令:from PIL.Image import core as _imaging
二、图像基本概念及处理方式
基本概念
- 图像(Image):图像是位图(bitmap), 它包含的信息是用像素来度量的。对图像的描述与分辨率和色彩的种类数有关,分辨率与色彩位数越大,占用存储空间就越大,图像也就越清晰。
- 像素(Pixel):是指在由一个数字序列表示的图像中的一个最小单位。
- 图像分辨率(Image Resolution):是指在单位英寸中所包含的像素点数目。
- 图像深度(Image Depth):是指存储每个像素所用的位数。图像深度用来确定彩色图像的每个像素可能有的颜色数或者确定灰度图像的每个像素可能有的灰度级数。
- 图像高度(Image Height):是指图像的竖向高度,也就是竖向的像素点数目。
- 图像宽度(Image Width):是指图像的横向高度,也就是横向的像素点数目。
- 图像采样(Image Sampling):是指对图像空间的离散化。采样的实质是指用多少点来描述一副图像,每一个点就叫做像素点,一副图像就被采样成有限个像素点构成的集合。
- 图像通道(Image Channel):又叫做颜色通道,表示每个像素点对应多少个像素值。常见的图像通道有RGB、HSV。
• RGB:R表示红色通道,G表示绿色通道,B表示蓝色通道。
• HSV:H表示色调(Hue),S表示饱和度(Saturation),V表示强度(Intensity)。 - 黑白图像:图像的每个像素只能是黑或者白,没有中间值,也叫做二值图像 ,二值图像的像素值只有0.0(黑色)和1.0(白色)或者0(黑色)和255(白色)。
- 灰度图像:图像的每个像素信息是有一个量化的灰度级来描述的,没有彩色信息。灰度图像的每个像素有一个0(黑色)到255(白色)之间的亮度值。
- 彩色图像:图像的每个像素信息由RGB三原色构成的,其中RGB是由不同的灰度级来描述的.
常规处理方式
- 几何变换(Geometric Transformations):包括放大、缩小、旋转等
- 颜色处理(Color):包括颜色空间的转化、亮度以及对比度的调节、颜色修正等。
- 图像合成(Image Composite):多个图像的加、减、组合、拼接等。
- 降噪(Image Denoising):对二维图像的去噪滤波器或者信号处理技术。
- 边缘检测(Edge Detection):进行边缘或者其它局部特征提取。
- 分割(Image Segmentation):依据不同的标准,将二维图像分割成为不同的区域。
- 图像增强(Image Enhancement):依据某种方式,增加图像数据的训练数据。
三、图像基本操作
在PIL中,提供了常见的绝大多数的图像处理的基本方式,主要包括:旋转、缩放、数据增强、剪切、填充、粘贴、合并、过滤等操作,详细API使用可见如下链接:https://pillow.readthedocs.io/en/5.2.x/reference/Image.html 常用的主要有4个模块(module):Image,ImageEnhance,ImageFilter,ImageOps
1、图像读写操作
from PIL import Image
# 读取图像,创建Image对象
img = Image.open('a.bmp')
# 图像可视化
img.show()
# 图像保存:可保存为不同名称或格式
img.save('b.png')
2、图像处理
将图像的Image对象转换为numpy数组进行处理
import numpy as np
from PIL import Image
img = Image.open('a.png') # 创建Image对象
img_arr = np.array(img) # 将Image对象转换为numpy数组
print(img_arr.shape)
img_arr = img_arr[206:306, 206:306, :] # 图像截取
img2 = Image.fromarray(img_arr, 'RGB') # 根据指定数组对象创建一个Image对象
img2.show()
图像的基本信息:
- format:图像格式,png、bmp等
- size:图像大小,(宽度,高度),单位是像素
- mode:图像类型,RGB是彩色图像,L是灰度图像…
更多mode信息:
https://pillow.readthedocs.io/en/5.2.x/handbook/concepts.html#modes
from PIL import Image, ImageFilter, ImageEnhance, ImageOps
# 读取图像
img = Image.open('a.png')
# 查看图像的基本信息
print((img.format, img.size, img.mode))
# 1. 图像转换为灰度图像
img1 = img.convert("L")
# img1.show() # 显示图像
# 2. 将灰度图像转换为黑白图像,即二值化图像。
像素点的值大于某个值的时候设置为白色,小于某个值的时候设置为黑色
img2 = img1.point(lambda i: 255 if i > 252 else 0)
# 3. 反转图像,一般只对灰度图像做(255->0, 0->255, 128->127)
img3 = img1.point(lambda i: 255 - i)
# 4. 大小缩放:resize
img4 = img.resize((1024, 700))
img5 = img.resize((32, 32))
# 5. 图像的旋转
# 30度表示逆时针旋转30度,负值表示顺时针旋转
# expand: 旋转之后的图像大小是否发生变化,设置为True,表示变化,
并且对于多余的位置使用fillcolor给定的颜色填充,默认为False,表示截断
img6 = img.rotate(30, expand=True, fillcolor=(255, 255, 255))
# 6. 转置(左右内容或者上下的内容调换)
img7 = img.transpose(Image.FLIP_TOP_BOTTOM)
# 注意:旋转180度和上下转置是不同的,转置前后的图像是关于某个轴对称的。
# 7. 裁切
# box:(left, upper, right, lower)也就是一个矩行的左上角和右下角的像素点的坐标
box = (200, 80, 380, 225) # 左上角为坐标原点
img8 = img.crop(box)
# 8. 图像的分裂和组合
r, g, b = img8.split() # r,g,b是像素值
img9 = Image.merge('RGB', (b, g, r))
# 9. 粘贴
img10 = img.copy()
img10.paste(img9, box)
# 10. 数据增强
# 方式一:使用point对像素点的值进行操作
img11 = img.point(lambda i: i * 1.5)
# 方式二:直接分裂像素值,然后分别对不同通道的像素点进行处理
r, g, b = img.split()
r = r.point(lambda i: i * 1.2)
g = g.point(lambda i: i * 1.0 if i == 255 else i * 0.5)
img12 = Image.merge(img.mode, (r, g, b))
# 方式三:直接使用PIL中的API做数据增强
# https://pillow.readthedocs.io/en/5.2.x/reference/ImageEnhance.html
# 平衡度、亮度、对比度、清晰度....
enhance = ImageEnhance.Contrast(img) # Contrast是对比度
img13 = enhance.enhance(factor=1.5) # factor>1 表示加强
img13.show()