您的当前位置:首页正文

Python图像处理类库

2023-02-14 来源:好走旅游网


Python图像处理类库(PIL)

本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的Python 工具包,并介绍用于读取图像、图像转换和缩放、计算导数、画图和保存结果等的基本工具。

1.1 PIL:Python图像处理类库

PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能, 以及大量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。PIL 是免费的,可以从http://www.pythonware.com/products/pil/ 下载。

利用PIL 中的函数,我们可以从大多数图像格式的文件中读取数据,然后写入最常见的图像格式文件中。PIL 中最重要的模块为Image。要读取一幅图像,可以使用:

from PIL import Image

pil_im = Image.open('empire.jpg')

上述代码的返回值pil_im 是一个PIL 图像对象。

图像的颜色转换可以使用convert() 方法来实现。要读取一幅图像,并将其转换成灰度图像,只需要加上convert('L'),如下所示:

pil_im = Image.open('empire.jpg').convert('L')

在PIL 文档中有一些例子, 参见

http://www.pythonware.com/library/pil/handbook/ index.htm。这些例子的输出结果如图1-1 所示。

1.1.1 转换图像格式

通过save() 方法,PIL 可以将图像保存成多种格式的文件。下面的例子从文件名列表(filelist)中读取所有的图像文件,并转换成JPEG 格式:

from PIL import Image

import os

for infile in filelist:

outfile = os.path.splitext(infile)[0] + \".jpg\"

if infile != outfile:

try:

Image.open(infile).save(outfile)

except IOError:

print \"cannot convert\

PIL 的open() 函数用于创建PIL 图像对象,save() 方法用于保存图像到具有指定文件名的文件。除了后缀变为“.jpg”,上述代码的新文件名和原文件名相同。PIL 是个足够智能的类库,可以根据文件扩展名来判定图像的格式。PIL 函数会进行简单的检查,如果文件不是JPEG 格式,会自动将其转换成JPEG 格式;如果转换失败, 它会在控制台输出一条报告失败的消息。

下面将创建一个包含文件夹中所有图像文件的文件名列表。首先新建一个文件,命名为imtools.py,来存储一些经常使用的图像操作,然后将下面的函数添加进去:

import os

def get_imlist(path):

\"\"\" 返回目录中所有JPG 图像的文件名列表\"\"\"

return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')]

现在,回到PIL。

1.1.2 创建缩略图

使用PIL 可以很方便地创建图像的缩略图。thumbnail() 方法接受一个元组参数(该参数指定生成缩略图的大小),然后将图像转换成符合元组参数指定大小的缩略图。例如,创建最长边为128 像素的缩略图,可以使用下列命令:

pil_im.thumbnail((128,128))

1.1.3 复制和粘贴图像区域

使用crop() 方法可以从一幅图像中裁剪指定区域:

box = (100,100,400,400)

region = pil_im.crop(box)

该区域使用四元组来指定。四元组的坐标依次是(左,上,右,下)。PIL 中指定坐标系的左上角坐标为(0,0)。我们可以旋转上面代码中获取的区域,然后使用paste() 方法将该区域放回去,具体实现如下:

regionregion = region.transpose(Image.ROTATE_180)

pil_im.paste(region,box)

1.1.4 调整尺寸和旋转

要调整一幅图像的尺寸,我们可以调用resize() 方法。该方法的参数是一个元组, 用来指定新图像的大小:

out = pil_im.resize((128,128))

要旋转一幅图像,可以使用逆时针方式表示旋转角度,然后调用rotate() 方法:

out = pil_im.rotate(45)

上述例子的输出结果如图1-1 所示。最左端是原始图像,然后是灰度图像、粘贴有旋转后裁剪图像的原始图像,最后是缩略图。

1.2 Matplotlib

我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib 是个很好的类库,具有比PIL 更强大的绘图功能。Matplotlib 可以绘制出高质量的图表,就像本书中的许多插图一样。Matplotlib 中的PyLab 接口包含很多方便用户创建图像的函数。Matplotlib 是开源工具,可以从http://matplotlib.sourceforge.net/ 免费下载。该链接中包含非常详尽的使用说明和教程。下面的例子展示了本书中需要使用的大部分函数。

1.2.1 绘制图像、点和线

尽管Matplotlib 可以绘制出较好的条形图、饼状图、散点图等,但是对于大多数计算机视觉应用来说,仅仅需要用到几个绘图命令。最重要的是,我们想用点和线来表示一些事物,比如兴趣点、对应点以及检测出的物体。下面是用几个点和一条线绘制图像的例子:

from PIL import Image

from pylab import *

# 读取图像到数组中

im = array(Image.open('empire.jpg'))

# 绘制图像

imshow(im)

# 一些点

x = [100,100,400,400]

y = [200,500,200,500]

# 使用红色星状标记绘制点

plot(x,y,'r*')

# 绘制连接前两个点的线

plot(x[:2],y[:2])

# 添加标题,显示绘制的图像

title('Plotting: \"empire.jpg\"')

show()

上面的代码首先绘制出原始图像,然后在x 和y 列表中给定点的x 坐标和y 坐标上绘制出红色星状标记点,最后在两个列表表示的前两个点之间绘制一条线段(默认为蓝色)。

该例子的绘制结果如图1-2 所示。show() 命令首先打开图形用户界面(GUI),然后新建一个图像窗口。该图形用户界面会循环阻断脚本,然后暂停,直到最后一个图像窗口关闭。在每个脚本里,你只能调用一次show() 命令,而且通常是在脚本的结尾调用。注意,在PyLab 库中,我们约定图像的左上角为坐标原点。

图像的坐标轴是一个很有用的调试工具;但是,如果你想绘制出较美观的图像,加上下列命令可以使坐标轴不显示:

axis('off')

上面的命令将绘制出如图1-2 右边所示的图像。

在绘图时,有很多选项可以控制图像的颜色和样式。最有用的一些短命令如表1-1、表1-2 和表1-3 所示。使用方法见下面的例子:

plot(x,y) # 默认为蓝色实线

plot(x,y,'r*') # 红色星状标记

plot(x,y,'go-') # 带有圆圈标记的绿线

plot(x,y,'ks:') # 带有正方形标记的黑色虚线

表1-1:用PyLab库绘图的基本颜色格式命令

表1-2:用PyLab库绘图的基本线型格式命令

表1-3:用PyLab库绘图的基本绘制标记格式命令

1.2.2 图像轮廓和直方图

下面来看两个特别的绘图示例:图像的轮廓和直方图。绘制图像的轮廓(或者其他二维函数的等轮廓线)在工作中非常有用。因为绘制轮廓需要对每个坐标[x, y] 的像素值施加同一个阈值,所以首先需要将图像灰度化:

from PIL import Image

from pylab import *

# 读取图像到数组中

im = array(Image.open('empire.jpg').convert('L'))

# 新建一个图像

figure()

# 不使用颜色信息

gray()

# 在原点的左上角显示轮廓图像

contour(im, origin='image')

axis('equal')

axis('off')

像之前的例子一样,这里用PIL 的convert() 方法将图像转换成灰度图像。

图像的直方图用来表征该图像像素值的分布情况。用一定数目的小区间(bin)来指定表征像素值的范围,每个小区间会得到落入该小区间表示范围的像素数目。该(灰度)图像的直方图可以使用hist() 函数绘制:

figure()

hist(im.flatten(),128)

show()

hist() 函数的第二个参数指定小区间的数目。需要注意的是,因为hist() 只接受一维数组作为输入,所以我们在绘制图像直方图之前,必须先对图像进行压平处理。flatten() 方法将任意数组按照行优先准则转换成一维数组。图1-3 为等轮廓线和直方图图像。

1.2.3 交互式标注

有时用户需要和某些应用交互,例如在一幅图像中标记一些点,或者标注一些训练数据。PyLab 库中的ginput() 函数就可以实现交互式标注。下面是一个简短的例子:

from PIL import Image

from pylab import *

im = array(Image.open('empire.jpg'))

imshow(im)

print 'Please click 3 points'

x = ginput(3)

print 'you clicked:',x

show()

上面的脚本首先绘制一幅图像,然后等待用户在绘图窗口的图像区域点击三次。程序将这些点击的坐标[x, y] 自动保存在x 列表里。

http://book.51cto.com/art/201406/442222.htm

1.3 NumPy

NumPy(http://www.scipy.org/NumPy/)是非常有名的Python 科学计算工具包,其中包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。NumPy 中的数组对象几乎贯穿用于本书的所有例子中1 数组对象可以帮助你实现数组中重要的操作,比如矩阵乘积、转置、解方程系统、向量乘积和归一化, 这为图像变形、对变化进行建模、图像分类、图像聚类等提供了基础。

注1: PyLab 实际上包含NumPy 的一些内容,如数组类型。这也是我们能够在1.2 节使用数组类型的原因。

NumPy 可以从http://www.scipy.org/Download 免费下载,在线说明文档(http://docs. scipy.org/doc/numpy/)包含了你可能遇到的大多数问题的答案。

1.4 SciPy

SciPy(http://scipy.org/) 是建立在NumPy 基础上, 用于数值运算的开源工具包。SciPy 提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及对我们来说最重要的图像处理功能。接下来,本节会介绍SciPy 中大量有用的模块。SciPy 是个开

源工具包,可以从http://scipy.org/Download 下载。

因篇幅问题不能全部显示,请点此查看更多更全内容