Python中的图像处理第1章基本的图像操作和处理本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的Python工具包,并介绍用于读取图像、图像转换和缩放、计算导数、画图和保存结果等的基本工具。这些工具的使用将贯穿本书的剩余章节。1.1PIL:Python图像处理类库PIL(PythonImagingLibraryPython,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。PIL是免费的,可以从下载。利用PIL中的函数,我们可以从大多数图像格式的文件中读取数据,然后写入最常见的图像格式文件中。PIL中最重要的模块为Image。要读取一幅图像,可以使用:fromPILimportImagepil_im=Image.open('empire.jpg')上述代码的返回值pil_im是一个PIL图像对象。图像的颜色转换可以使用convert()方法来实现。要读取一幅图像,并将其转换成灰度图像,只需要加上convert('L'),如下所示:pil_im=Image.open('empire.jpg').convert('L')在PIL文档中有一些例子,参见。这些例子的输出结果如图1-1所示。图1-1:用PIL处理图像的例子1.1.1转换图像格式通过save()方法,PIL可以将图像保存成多种格式的文件。下面的例子从文件名列表(filelist)中读取所有的图像文件,并转换成JPEG格式:fromPILimportImageimportosforinfileinfilelist:outfile=os.path.splitext(infile)[0]+.jpgifinfile!=outfile:try:Image.open(infile).save(outfile)exceptIOError:printcannotconvert,infilePIL的open()函数用于创建PIL图像对象,save()方法用于保存图像到具有指定文件名的文件。除了后缀变为“.jpg”,上述代码的新文件名和原文件名相同。PIL是个足够智能的类库,可以根据文件扩展名来判定图像的格式。PIL函数会进行简单的检查,如果文件不是JPEG格式,会自动将其转换成JPEG格式;如果转换失败,它会在控制台输出一条报告失败的消息。本书会处理大量图像列表。下面将创建一个包含文件夹中所有图像文件的文件名列表。首先新建一个文件,命名为imtools.py,来存储一些经常使用的图像操作,然后将下面的函数添加进去:importosdefget_imlist(path):返回目录中所有JPG图像的文件名列表return[os.path.join(path,f)forfinos.listdir(path)iff.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()方法将该区域放回去,具体实现如下:region=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.2Matplotlib我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib是个很好的类库,具有比PIL更强大的绘图功能。Matplotlib可以绘制出高质量的图表,就像本书中的许多插图一样。Matplotlib中的PyLab接口包含很多方便用户创建图像的函数。Matplotlib是开源工具,可以从免费下载。该链接中包含非常详尽的使用说明和教程。下面的例子展示了本书中需要使用的大部分函数。1.2.1绘制图像、点和线尽管Matplotlib可以绘制出较好的条形图、饼状图、散点图等,但是对于大多数计算机视觉应用来说,仅仅需要用到几个绘图命令。最重要的是,我们想用点和线来表示一些事物,比如兴趣点、对应点以及检测出的物体。下面是用几个点和一条线绘制图像的例子:fromPILimportImagefrompylabimport*#读取图像到数组中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-2:Matplotlib绘图示例。带有坐标轴和不带坐标轴的包含点和一条线段的图像在绘图时,有很多选项可以控制图像的颜色和样式。最有用的一些短命令如表1-1、表1-2和表1-3所示。使用方法见下面的例子:plot(x,y)#默认为蓝色实线plot(x,y,'r*')#红色星状标记plot(x,y,'go-')#带有圆圈标记的绿线plot(x,y,'ks:')#带有正方形标记的黑色虚线表1-1:用PyLab库绘图的基本颜色格式命令颜色'b'蓝色'g'绿色'r'红色'c'青色'm'品红'y'黄色'k'黑色'w'白色