Python环境Pillow( PIL )图像处理工具使用解析
前言
由于笔者近期的研究课题与图像后处理有关,需要通过图像处理工具对图像进行变换和处理,进而生成合适的训练图像数据。该系列文章即主要记录笔者在不同的环境下进行图像处理时常用的工具和库。在Python环境下,对图像的处理笔者主要使用Pillow库,主要操作包括对图像的读取、存储和变换等。实际应用中,Pillow中提供的Image模块适合对图像整体进行变换处理操作。
注:以下介绍仅包括对应模块和函数的基础用法,故而在介绍时省略了部分参数和选项,更完备的用法和介绍可参考Pillow的官方文档。
安装
用户可通过pip直接安装Pillow,更多安装方式可以参见这里。
pipinstallPillow#安装pillow
使用
在日常应用过程中,使用最多的是Pillow提供的Image模块,其提供了包括图像存储、变换以及一系列的相关处理功能。Pillow使用Image对象来表示图像对象并基于其定义图像的属性信息以及可针对其进行的操作,后续即主要介绍通过Image对象可进行的图像操作。在Python中使用时,用户首先需从PIL中导入对应的Image模块。
fromPILimportImage#通过Image进行图像处理相关的操作
图像读取与存储
通过Image提供的open方法读取图像,其以指定的文件名为参数,返回值为对应图像的Image对象,后续即可针对图像对应的Image对象进行操作。
im=Image.open("test.png")#open方法以图像名(或图像对象)为参数,返回一个Image对象
通过Image对象的save方法存储图像对象,其使用存储目标文件名为参数,也可通过format参数指定存储文件的格式。
im.save("test.png")#im为Image对象,其被保存至test.png,不指定format参数时,该方法通过文件后缀推测文件类型 im.save("test.jpg",format="JPEG")#以JPEG格式保存Image对象im至文件test.jpg中
基本属性
图像对应的Image对象具备基本属性。用户可以通过这些属性获得图像最基本的信息,Image对象的完整属性信息可以查看这里。
im.filename#Image对象im对应的文件/路径名 im.mode#Image对象图像数据的解释方式,如灰度图为“L”,彩色图为“RGB”等 im.size#返回图像的尺寸信息,为(width,height)格式的元祖
图像类型转换
不同的图像数据具有不同的图像格式,进而拥有不同的组织数据的方式。对于RGB图像而言,图像拥有R、G、B三个通道,像素数据由三个对应三通道的8bit数据组成;对于黑白图像而言,其每个像素由一个8bit字节表示等等。在打开图像时,open方法会自动解析图像的格式,用户可通过Image对象的mode属性获得图像的状态。
Image对象可通过convert方法进行图像类型间的转换,其使用转换的目标类型的字符串为参数,返回转换后的Image对象,常见的类型包括RGB(真彩)、L(黑白)、YCbCr(视频图像)、HSV(色调饱和度亮度彩色空间)。
data=im.convert("L")#获得RGB图像im的灰度图
与numpy数组的转换
在程序中,一般使用图像对应的Image对象进行图像相关的操作,针对图像数据本身的计算处理一般将Image对象的数据转换为numpy数据后进行,处理完成之后的numpy数据再被转换为Image对象进行保存。
a.将Image对象转换为numpy数组
使用numpy.asarray方法(不唯一,可参见Arraycreationroutines)将Image对象的数据转换为numpy数组,进而可以对其进行计算处理。转换后numpy数组的数据类型根据Image数据对象本身的数据类型推断获得,使用时也可使用numpy.asarray的dtype参数指定转换后的数据类型。
im=Image.open("test.png")#打开图像test.png,并获得其对应的Image对象 data=numpy.asarray(im)#将Image对象im的数据转换为numpy数组的形式,data即为可供运算的numpy数组 data=numpy.asarray(im,dtype=np.uint8)#转换图像数据为numpy数组,并指定其类型为np.uint8
b.将numpy数组转换为Image对象
对于numpy数据形式的图像数据(通过数据处理或其他途径获得),可通过Image.fromarray方法将已有的numpy图像数据转换为Image对象。
im=Image.fromarray(data)#data为numpy数组,im为转换获得的Image对象
注意,在使用Image.fromarray方法时可能会出现报错raiseTypeError("Cannothandlethisdatatype"),这是由于待转换的numpy数据类型可能并不符合Image对象所需的数据类型(一般为8bit无符号值),解决方法是在转换前先将numpy数组的数据类型转换为np.uint8.
im=Image.fromarray(data.astype(np.uint8))#将numpy数组的数据类型转换为np.uint8后再转换为Image对象
常用操作
裁剪图像——crop
可以使用crop方法获得图像的指定部分。crop方法以指定(左,上,右,下)切割位置的元祖来定义待分割的图像部分,可以理解为定义的是切割获得的矩形的左上角和右下角位置的坐标。在PIL所支持的坐标系统中,坐标的(0,0)为图像的左上角,注意(0,0)指向的不是左上角的第一个像素,而是该像素位置前的位置,后续所有的坐标均为像素间的空隙位置,而不是指向像素。也就是说,第一个像素被(0,0)和(0,1)两个坐标左右包围。
part=im.crop((0,0,100,100))#截取获得图像im左上角大小为100×100像素的矩形图像
通道处理——split/getchannel
split方法将图像数据按通道分离,其返回值为包含各个通道分离数据的元组tuple,如对于RGB图像而言,其被分成R、G、B三个通道的数据。
R,G,B=im.split()#im为真彩色Image对象,其被分为独立的R、G、B通道信息
getchannel方法以图像的通道的索引或字符名字为参数,返回包含有对应通道数据的L类型的图像(即为黑白模式)。
R=im.getchannel(0)#获得RGB图像的第一个通道的数据,即R通道信息 R=im.getchannel("R")#同上
缩放图像——resize
resize方法以缩放目标图像大小的元祖(Width,Heigth)为参数,通过指定的采样方法将图像缩放为指定的图像大小。其支持采样的方法包括PIL.Image.NEAREST、PIL.Image.BILINEAR、PIL.Image.BICUBIC等,resize支持的全部采样方式见文档。注意,以上采样方法的全名为PIL.Image.xxxx,但实际上由于之前已经使用fromPILimportImage导入了Image这个模块名,故而后续可以直接使用Image.xxxx的形式调用上述方法,反之,在未导入模块名时需使用完整的名称来使用上述方法,下同。
data=im.resize((100,100))#将im对应的Image对象缩放为100×100的大小,默认采用PIL.Image.NEAREST方法 data=im.resize((100,100),Image.BICUBIC)#使用PIL.Image.BICUBIC方法进行采样
翻转图像——rotate/transpose
通过rotate方法旋转图像,rotate方法以旋转的角度为参数,将图像顺时针中心旋转对应的度数,并返回对应的Image对象。注意,通过rotate方法进行旋转时,结果图像是中心旋转后图像在源图像大小范围内被截取的部分,其他部分为填充。如大小为宽×高200*100的图像,经过90度旋转后,其大小仍为200*100,图像内容为旋转后的理论为100*200的图像与原200*100区域的重合部分,其余部分为填充。
rotate方法可以指定expand参数为1,此时生成的新图像为完整包含有旋转后图像内容的最小矩形大小(空白处为填充),如上例中,图像经过90度旋转后,获得的新图像的大小即为100*200。更多介绍见Image.rotate.
data=im.rotate(90)#将图像顺时针旋转90度 data=im.rotate(90,expand=1)#将图像顺时针旋转90度,同时保留图像的完整内容
在某些图像训练的数据生成中,将图像进行90度为单位的旋转、上下或左右翻转是更为常见的操作。此时可以使用transpose方法,transpose以翻转方式为参数,返回经过翻转后的图像,其支持的参数如下所示。
PIL.Image.FLIP_LEFT_RIGHT#左右翻转图像 PIL.Image.FLIP_TOP_BOTTOM#上下翻转图像 PIL.Image.ROTATE_90 PIL.Image.ROTATE_180 PIL.Image.ROTATE_270#顺时针旋转对应度数 PIL.Image.TRANSPOSE#类似于左右翻转后再逆时针旋转图像90度 PIL.Image.TRANSVERSE#类似与左右翻转后再顺时针旋转图像90度
可以直接使用上述参数对图像进行变换,transpose方法返回变换后的完整图像(由于是90度倍数的变换,也不存在空白区域)。
data=im.transpose(Image.FLIP_LEFT_RIGHT)#获得im图像经过左右旋转后的数据
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。