【图像处理】Image类基础使用方法
前言
修改自CSDN博客,完整内容见:
Python图像库PIL的类Image及其方法介绍Image类介绍
Image类是PIL中的核心类,你有很多种方式来对它进行初始化,比如从文件中加载一张图像,处理其他形式的图像,或者是从头创造一张图像等。Image模块操作的基本方法都包含于此模块内。
使用Image类的注意事项
Pillow
由于PIL仅支持到Python 2.7,加上年久失修,于是一群志愿者在PIL的基础上创建了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用Pillow。
如果安装了Anaconda,Pillow就已经可用了。否则,需要在命令行下通过pip安装:
$ pip install pillow
调用方法
# python2
import Image
# python3
from PIL import Image
智能补全问题
python是动态强类型语言,IDE无法判断Image.open(“file.png”)的返回值类型,无法根据参数类型自动补全。
这个问题有以下解决方法:
- 类型注释:加上
# type: Image.Image
img = Image.open('file.png') # type: Image.Image
- 使用
isinstance
进行指定img = Image.open('file.png') assert isinstance(img, Image.Image)
- 指定类型
img = Image.open('f15.png') """:type: Image.Image"""
Image类属性
size
size
记录图像的尺寸,按照像素数计算。它的返回值为宽度和高度的二元组(width, height)
。
<imname>.size -> (width,height)
im = Image.open("3d.jpg")
print(im.size) # 打印图像尺寸
format
format
属性标识了图像来源格式,如果图像没有读取文件,它的值就是None
。
<imname>.format -> string or None
im = Image.open("3d.jpg")
print(im.format) # 打印出格式信息
mode
mode
标识图像的模式。
<imname>.mode -> string
im = Image.open("3d.jpg")
print(im.mode) # 打印出模式信息
常见的图像模式如下表:
Modes | Description |
---|---|
1 | 1位像素,黑白图像,存成8位像素 |
L | 8位像素,黑白 |
P | 9位像素,使用调色板映射到任何其他模式 |
RGB | 3*8位像素,真彩 |
RGBA | 4*8位像素,真彩+透明通道 |
CMYK | 4*8位像素,印刷四色模式或彩色印刷模式 |
YCbCr | 3*8位像素,色彩视频格式 |
I | 32位整型像素 |
F | 33位浮点型像素 |
palette
palette
记录颜色调色板表格。如果图像的模式是“P”,则返回Image Palette类的实例;否则,将为None。
<imname>.palette -> palette or None
info
info
存储图像相关数据的字典。
文件句柄使用该字典传递从文件中读取的各种非图像信息。大多数方法在返回新的图像时都会忽略这个字典;因为字典中的键并非标准化的,对于一个方法,它不知道自己的操作如何影响这个字典。如果用户需要这些信息,需要在方法open()
返回时保存这个字典。
<imname>.info -> dictionary
Image类方法
new
new()
使用给定的变量mode和size生成新的图像。
Image.new(mode,size) -> image
Image.new(mode, size,color) -> image
size
是给定的宽/高二元组,这是按照像素数来计算的。
对于单通道图像,变量color
只给定一个值;对于多通道图像,变量color
给定一个元组(每个通道对应一个值)。
在版本1.1.4及其之后,用户也可以用颜色的名称,比如给变量color
赋值为"red"
。如果没有对变量color
赋值,图像内容将会被全部赋值为0(为黑色)。
如果变量color
是空,图像将不会被初始化,即图像的内容全为0。这对向该图像复制或绘制某些内容是有用的。
# 创建128*128全红图像
n_im= Image.new("RGB", (128, 128), "#FF0000")
open
要从文件加载图像,使用open()
函数:
Image.open(file) -> image
from PIL import Image
im = Image.open('./3d.jpg') # 打开当前路径下的3d.jpg文件
im.show() # 显示图片
save
save()
方法可以用于保存文件,使用给定的文件名保存图像:<imname>.save(outfile,format,options)
如果变量format
缺省,如果可能的话,则从文件名称的扩展名判断文件的格式。该方法返回为空。
关键字options
为文件编写器提供一些额外的指令。如果编写器不能识别某个选项,它将忽略它。用户可以使用文件对象代替文件名称。在这种情况下,用户必须指定文件格式。
文件对象必须实现了seek()
、tell()
和write()
方法,且其以二进制模式打开。如果方法save()
因为某些原因失败,这个方法将产生一个异常(通常为IOError
异常)。如果发生了异常,该方法也有可能已经创建了文件,并向文件写入了一些数据。如果需要的话,用户的应用程序可以删除这个不完整的文件。
# save()可以用于转换文件类型
im = Image.open("3d.jpg")
im.save("3d.png") # 将"3d.jpg"保存为3d.png"
getpixel
getpixel()
返回给定位置的像素值。
<imname>.getpixel(xy) -> value or tuple
如果图像为多通道,则返回一个元组。该方法执行比较慢;如果用户需要使用python处理图像中较大部分数据,可以使用像素访问对象load()
,或者方法getdata()
。
im = Image.open("3d.jpg")
print(im.getpixel((0,0)))
load
load()
为图像分配内存并从文件中加载它(或者从源图像)。正常情况下,用户不需要调用这个方法,因为在第一次访问图像时,Image类会自动地加载打开的图像。
目前的版本,方法load()返回一个用于读取和修改像素的像素访问对象。 这个访问对象像一个二维队列,如:
pix = im.load()
print(pix[x, y]) # 读取pix中的像素
pix[x, y] = value # 修改pix中的像素
getdata
getdata()
以包含像素值的sequence对象形式返回图像的内容。
<imname>.getdata() -> sequence
这个sequence对象是扁平的,以便第一行的值直接跟在第零行的值后面,等等。
这个方法返回的sequence对象是PIL内部数据类型,它只支持某些sequence操作,包括迭代和基础sequence访问。使用list(im.getdata())
,将它转换为普通的sequence。
sequence对象的每一个元素对应一个像素点的R、G和B三个值。
im = Image.open("3d.jpg")
sequ = im.getdata()
l_sequ = list(sequ)
corp
corp()
从当前的图像中返回一个矩形区域的拷贝。
变量box
是一个四元组,定义了左、上、右和下的像素坐标,用来表示在原始图像中截取的位置坐标。
如box = (100,100,200,200)
就表示在原始图像中以左上角为坐标原点,截取一个100*100(像素为单位)的图像,为方便理解,如下为示意图box = (b1,a1,b2,a2)
。
im = Image.open("3d.jpg")
box = (20, 30, 300, 200) # 确定拷贝区域大小
region = im.crop(box) # 将im表示的图片对象拷贝到region中,大小为box
copy
copy()
可以拷贝这个图像。如果用户想粘贴一些数据到这张图,可以使用这个方法,但是原始图像不会受到影响。
<imname>.copy() -> image
# im_copy和im完全相同
im = Image.open("3d.jpg")
im_copy = im.copy()
paste
paste()
将一张图粘贴到另一张图像上。
<imname>.paste(image,box)
变量box
或者是一个给定新图片中插入图像所在区域的左上角坐标的2元组,或者是定义了左,上,右和下像素坐标的4元组,或者为空(与(0,0)一样)。
如果给定4元组,被粘贴的图像的尺寸必须与区域尺寸一样。如果模式不匹配,被粘贴的图像将被转换为当前图像的模式。
im = Image.open("3d.jpg")
box=[0,0,100,100]
im_crop = im.crop(box)
im.paste(im_crop, (100,100)) #(100,100)为im用于粘贴im_corp的区域的左上角像素坐标
im.paste(im_crop, (400,400,500,500))
convert
convert()
将当前图像转换为其他模式,并且返回新的图像。
<imname>.convert(mode) -> image
当从一个调色板图像转换时,这个方法通过这个调色板来转换像素。如果不对变量mode
赋值,该方法将会选择一种模式,在没有调色板的情况下,使得图像和调色板中的所有信息都可以被表示出来。
<imname>.convert(mode,matrix) -> image
使用转换矩阵将一个“RGB”图像转换为“L”或者“RGB”图像。变量matrix
为4或者16元组。
# 使用P模式转换图像
im = Image.open("3d.jpg")
new_im = im.convert('P')
# 使用自定义矩阵转换图像
im = Image.open("3d.jpg")
rgb2xyz = (0.412453,0.357580, 0.180423, 0,
0.212671,0.715160, 0.072169, 0,
0.019334,0.119193, 0.950227, 0 )
new_im = im.convert("L", rgb2xyz)
blend
blend()
使用给定的两张图像及透明度变量alpha
,插值出一张新的图像。这两张图像必须有一样的尺寸和模式。
Image.blend(image1,image2, alpha) -> image
合成公式为:$out = image1 (1.0 - alpha) + image2 (alpha)$
若变量alpha
为0.0,返回第一张图像的拷贝。若变量alpha
为1.0,将返回第二张图像的拷贝。对变量alpha
的值无限制。
from PIL import Image
im1 = Image.open("3d.jpg")
im2 = Image.open("3dd.jpg")
im = Image.blend(im1, im2, 0.40)
fliter
fliter()
返回一个使用给定滤波器处理过的图像的拷贝。
<imname>.filter(filter) -> image
fliter()
具体参考图像滤波在ImageFilter
模块的应用。在该模块中,预先定义了很多增强滤波器,可以通过filter()
函数使用。
预定义滤波器包括:BLUR、CONTOUR、DETAIL、EDGE_ENHANCE、EDGE_ENHANCE_MORE、EMBOSS、FIND_EDGES、SMOOTH、SMOOTH_MORE、SHARPEN。其中BLUR就是均值滤波,CONTOUR找轮廓,FIND_EDGES边缘检测,使用该模块时,需先导入。
from PIL import Image
from PIL import ImageFilter # 调取ImageFilter
imgF = Image.open("3d.jpg")
bluF = imgF.filter(ImageFilter.BLUR) # 均值滤波
conF = imgF.filter(ImageFilter.CONTOUR) # 找轮廓
edgeF = imgF.filter(ImageFilter.FIND_EDGES) # 边缘检测