python中的PIL库介绍
【时间】2018.10.19
【题目】python中的PIL库介绍
【参考链接】https://www.cnblogs.com/lyrichu/p/9124504.html
概述
PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了。其官方主页为:PIL。
一、简单实用Image函数--图像的打开,保存与显示
1.1、图片的打开
函数:open(filename,mode)(打开一张图像)。
从文件加载图像,用Image函数的open方法
>>> from PIL import Image
>>> im = Image.open("autumn.jpg")
如果成功,这个函数将返回一个图像对象,格式为JpegImageFile。
现在您可以使用实例属性来检查文件内容及相关属性。
>>> print(im.format, im.size, im.mode)
JPEG (1000, 727) RGB
-
format属性识别图形的源,若图片不是从文件读取的将显示None;
-
size属性是一个包含宽度和高度的二元数组(以像素为单位);
-
mode属性定义了图像中波段的数量和名称,以及像素类型和深度,常见的模式是“L”(亮度)用于灰度图像,“RGB”用于真正的彩色图像,以及“CMYK”用于预压图像
1.2、图片的保存
函数:save(filename,format)(保存指定格式的图像)
>>> im.save("autumn.jpg",'png')
上面的代码将图像重新保存成png格式。
1.3图片的显示
函数:show()
>>> im.show() #显示刚刚加载的图像
show()的标准版本不是很有效,因为它将图像保存到一个临时文件中,并调用xv实用程序来显示图像。如果你没有安装xv,它甚至不会工作。但是,当它确实起作用时,它对于调试和测试非常方便。
例子:创建图片的缩略图
im = Image.open('bossimg.jpg')
print im.format,im.size,im.mode
size = (30,40)
im.thumbnail(size) #大小是元组长和宽
im.save('boss.png','PNG') #以png格式保存缩略图
二、常用的图像处理
2.1 创建缩略图
函数: thumbnail(size,resample)
>>> im.thumbnail((50,50),resample=Image.BICUBIC)
>>> im.show()
上面的代码可以创建一个指定大小(size)的缩略图,需要注意的是,thumbnail方法是原地操作,返回值是None。第一个参数是指定的缩略图的大小,第二个是采样的,有Image.BICUBIC,PIL.Image.LANCZOS,PIL.Image.BILINEAR,PIL.Image.NEAREST这四种采样方法。默认是Image.BICUBIC。
注意:会在原图改变
2.2裁剪矩形区域
函数:crop(box)
>>> im = Image.open("autumn.jpg","r")
>>> box = (100,100,200,200)
>>> region = im.crop(box)
>>> region.show()
上面的代码在im图像上裁剪了一个box矩形区域,然后显示出来。box是一个有四个数字的元组(upper_left_x,upper_left_y,lower_right_x,lower_right_y),分别表示裁剪矩形区域的左上角x,y坐标,右下角的x,y坐标,规定图像的最左上角的坐标为原点(0,0),宽度的方向为x轴,高度的方向为y轴,每一个像素代表一个坐标单位。crop()返回的仍然原Image对象。
注意:不会在原图改变
2.3图像翻转或者旋转
函数:transpose(method)
>>> im_rotate_180 = im.transpose(Image.ROTATE_180)
>>> im_rotate_180.show()
上面的代码将im逆时针旋转180°,然后显示出来,method是transpose的参数,表示选择什么样的翻转或者旋转方式,可以选择的值有:
- Image.FLIP_LEFT_RIGHT,表示将图像左右翻转
- Image.FLIP_TOP_BOTTOM,表示将图像上下翻转
- Image.ROTATE_90,表示将图像逆时针旋转90°
- Image.ROTATE_180,表示将图像逆时针旋转180°
- Image.ROTATE_270,表示将图像逆时针旋转270°
- Image.TRANSPOSE,表示将图像进行转置(相当于顺时针旋转90°)
- Image.TRANSVERSE,表示将图像进行转置,再水平翻转(这点存在疑问
注意:不会在原图改变
2.4 将一个图像粘贴到另一个图像
函数:paste(region,box,mask)
>>> im.paste(region,(100,100),None)
>>> im.show()
上面的代码将region图像粘贴到左上角为(100,100)的位置。region是要粘贴的Image对象,box是要粘贴的位置,可以是一个两个元素的元组,表示粘贴区域在原图im中的左上角坐标,也可以是一个四个元素的元组,表示左上角和右下角的坐标。如果是四个元素元组的话,box的size必须要和region的size保持一致,否则将会被convert成和region一样的size。mask一般是在RGBA格式(PNG格式)的图像,用于指定透明区域,将底图显示出来,它会根据mask图像的a通道指定透明区域。具体而言,在该掩码中,值255表示粘贴图像在该位置是不透明的(也就是说,粘贴的图像应该被使用)。值0表示粘贴的图像是完全透明的。中间值表示不同级别的透明性。例如,粘贴一个RGBA图像并使用它作为掩码会粘贴图像的不透明部分,而不是它的透明背景。
补充: 可以用以下语句创建mask:mask = im.point(lambda i: expression and 255) ,其中expression是一个表达式,如i<100,表示图像im的像素值小于100时,取Flase(0),否则取255.
注意:会在原图改变
2.5.颜色通道分离
函数:split()
>>> r,g,b = im.split()
>>> r.show()
>>> g.show()
>>> b.show()
split()方法可以原来图像的各个通道分离,比如对于RGB图像,可以将其R,G,B三个颜色通道分离。
2.6.颜色通道合并
函数:merge(mode,channels)
>>> im_merge = Image.merge("RGB",[b,r,g])
merge方法和split方法是相对的,其将多个单一通道的序列合并起来,组成一个多通道的图像,mode是合并之后图像的模式,比如"RGB",channels是多个单一通道组成的序列。
2.7.改变图像尺寸大小
函数:resize(size,resample,box)
>>> im_resize_box = im.resize((100,100),box = (0,0,50,50))
>>> im_resize_box.show()
resize方法可以将原始的图像转换大小,size是转换之后的大小,resample是重新采样使用的方法,仍然有Image.BICUBIC,PIL.Image.LANCZOS,PIL.Image.BILINEAR,PIL.Image.NEAREST这四种采样方法,默认是PIL.Image.NEAREST,box是指定的要resize的图像区域,是一个用四个元组指定的区域(含义和上面所述box一致)。若指定box,就是对box指定的区域进行尺寸变化。
注意:不会在原图改变
2.8.改变图像的mode即格式
函数:convert(mode,matrix,dither,palette,colors)(mode转换)
>>> im_L = im.convert("L")
>>> im_L.show()
>>> im_rgb = im_L.convert("RGB")
>>> im_rgb.show()
>>> im_L.mode
'L'>>> im_rgb.mode
'RGB'
convert方法可以改变图像的mode,一般是在'RGB'(真彩图)、'L'(灰度图)、'CMYK'(压缩图)之间转换。上面的代码就是首先将图像转化为灰度图,再从灰度图转化为真彩图。值得注意的是,从灰度图转换为真彩图,虽然理论上确实转换成功了,但是实际上是很难恢复成原来的真彩模式的(不唯一)。
2.9.应用过滤器
函数:filter(filter)
>>> from PIL import ImageFilter
>>> im_blur = im.filter(ImageFilter.BLUR)
>>> im_blur.show()
>>> im_find_edges = im.filter(ImageFilter.FIND_EDGES)
>>> im_find_edges.show()
filter方法可以将一些过滤器操作应用于原始图像,比如模糊操作,查找边、角点操作等。filter是过滤器函数,在PIL.ImageFilter函数中定义了大量内置的filter函数,比如BLUR(模糊操作),GaussianBlur(高斯模糊),MedianFilter(中值过滤器),FIND_EDGES(查找边)等。上面得到原始图像dog.jpg,find_edges.jpg以及blur.jpg从左到右如下图1所示:
2.10.对图像像素操作
函数:point(lut,mode)
>>> im_point = im.point(lambda x:x*1.5)
>>> im_point.save("im_point.jpg")
point方法可以对图像进行单个像素的操作,上面的代码对point方法传入了一个匿名函数(lut),表示将图像的每个像素点大小都乘以0.5(实现将图片整体变暗),mode是返回的图像的模式,默认是和原来图像的mode是一样的。下图是原来的person.jpg和point操作之后的im_point.jpg之间的对比。
2.11.图像增强
函数:ImageEnhance()
from PIL import Image , ImageEnhance
im = Image.open("F:\\test\\image1\\person.jpg")
brightness = ImageEnhance.Brightness(im)
im_brightness = brightness.enhance(1.5)
contrast = ImageEnhance.Contrast(im)
im_contrast = contrast.enhance(1.5)
im_brightness.save("./image1/im_brightness.jpg")
im_contrast.save("./image1/im_contrast.jpg")
ImageEnhance是PIL下的一个子类,主要用于图像增强,比如增加亮度(Brightness),增加对比度(Contrast)等。上面的代码将原来图像的亮度增加50%,将对比度也增加了50%。
2.12.处理图像序列(如gif图像)
函数:ImageSequence()
下面的代码可以遍历gif图像中的所有帧,并分别保存为图像。
1)使用迭代器的方式
>>> from PIL import ImageSequence
>>> from PIL import Image
>>> gif = Image.open("pipixia.gif")
>>> for i,frame in enumerate(ImageSequence.Iterator(gif),1):
... if frame.mode == 'JPEG':
... frame.save("%d.jpg" %i)
... else:
... frame.save("%d.png" % i)
2)使用seek(index)函数一帧一帧读取gif
>>> index = 0>>> while 1:
... try:
... gif.seek(index)
... gif.save("%d.%s" %(index,'jpg' if gif.mode == 'JPEG' else 'png'))
... index += 1... except EOFError:
... print("Reach the end of gif sequence!")
... break
上面的代码在读取到gif的最后一帧之后,会throw 一个 EOFError,所以我们只要捕获这个异常就可以了。