实战 | 用Python做图像处理(一)

2018 年 5 月 23 日 七月在线实验室

Python中有好多工具包应用于图像处理当中,这一节(基本的图像操作和处理)作为入门章节,首先来介绍Python中最基本的几个工具包,也希望读者可以在之后自行练习。

PIL:Python图像处理类库



PIL(Python Imaging Library)为图像处理类库,它为Python提供了基本的图像处理功能和基本操作。PIL中最重要的模块又是Image,下面,我们就来讲一讲Image模块的一些用法。

读取一幅图像:



我们用Image模块中的open()方法实现

首先强调一点就是对于PNG、BMP和JPG等不同格式的彩色图像之间的互相转换都可以通过Image模块来完成,具体来说,在打开这些图像时,PIL会将它们解码为三通道的“RGB”图像。用户可以基于这个“RGB”图像,对其进行处理。

from PIL import Image #从PIL包中导入Image模块
image = Image.open('test.jpg') #读取名为test的图片

这是test.jpg图片

通过上述代码,我们的返回值image就是一个PIL对象,当我们需要对一幅图像进行各种操作时,首先都要通过上述代码读取目标图像。

上述代码的运行结果实际上为:

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=1000x1436 at 0x1826BF51D68>

怎样才能将它变为可视化的图像呢?

我们需要调用matplotlib.pyplot函数集合的 imshow() 和show()方法,完整代码为:

from PIL import Image
import matplotlib.pyplot as plt
image = Image.open('test.jpg')
plt.imshow(image)
plt.show()# 需要调用show()方法,不然图像只会在内存中而不显示出来

结果如下图所示:

将图像转换为灰度图像



 我们使用convert()方法来实现图像的灰度转化

Convert()函数会根据传入参数的不同将图片变成不同的模式,通过相关资料我们知道PIL中有九种不同模式。分别为1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。

模式“1”为二值图像,非黑即白。但是它每个像素用8个bit表示,0表示黑,255表示白。

模式L”为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。在PIL中,从模式“RGB”转换为“L”模式是按照下面的公式转换的:

L = R * 299/1000 + G * 587/1000+ B * 114/1000

模式“P”为8位彩色图像,它的每个像素用8个bit表示,其对应的彩色值是按照调色板查询出来的。

模式“RGBA”为32位彩色图像,它的每个像素用32个bit表示,其中24bit表示红色、绿色和蓝色三个通道,另外8bit表示alpha通道,即透明通道。

模式“CMYK”为32位彩色图像,它的每个像素用32个bit表示。模式“CMYK”就是印刷四分色模式,它是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。

模式“YCbCr”为24位彩色图像,它的每个像素用24个bit表示。YCbCr其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。人的肉眼对视频的Y分量更敏感,因此在通过对色度分量进行子采样来减少色度分量后,肉眼将察觉不到的图像质量的变化。

模式“RGB”转换为“YCbCr”的公式如下:

Y= 0.257*R+0.504*G+0.098*B+16
Cb = -0.148*R-0.291*G+0.439*B+128
Cr = 0.439*R-0.368*G-0.071*B+128

模式“I”为32位整型灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“I”模式是按照下面的公式转换的:

I = R * 299/1000 + G * 587/1000 + B * 114/1000

模式“F”为32位浮点灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“F”模式是按照下面的公式转换的:

F = R * 299/1000+ G * 587/1000 + B * 114/1000

我们以灰度图像为例,将目标图像转换成灰度图像,由上可知,我们要给convert()方法传入参数“L”,具体代码如下:

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm

image = Image.open('test.jpg')  # 读取名为test的图片
image_gray = image.convert("L")  # 将图片转换为灰度图像
data = np.array(image_gray)

plt.imshow(data, cmap=cm.gray)
plt.show()

绘制出的灰度图像为:

我们也可以用一行代码

image = Image.open(‘test.jpg’).convert(“L”)

代替上面的两行注释代码。

在上述代码中我们引入了matplotlib.cm模块和numpy模块。

cm是colormap的缩写,这个模块提供了大量的colormaps,用于注册新的colormaps,并通过名称获得一个colormap,以及用于添加颜色映射功能的mixin类。

而在绘制灰度图像的imshow()方法给cmap传入了cm.gray参数。cmap:代表颜色图谱(colormap), 默认绘制为RGB(A)颜色空间。

为什么调取灰度图像加了这么一行代码呢?原因在于如果是彩色图像,上面的方法没有任何问题,但是如果是灰度图像,用上面的语句就不能正确显示,主要是没有加调色板。

除此之外,我们可以用一行代码plt.gray()来代替上述代码这样写会使代码看上去更加简洁。

NumPy是一个非常有名的 Python 科学计算工具包,其中包含了大量有用的工具,比如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。在显示灰度图像时array()方法将图像转换成NumPy的数组对象,图片得以显示,否则会出现AttributeError的错误。 

转换图像的格式



 通过save()方法,PIL可以将图像保存成多种格式的文件,当传入不同的扩展名时,它会根据扩展名自动转换图像的格式。 

from PIL import Image

image = Image.open("smallpi.jpg")  # 打开jpg图像文件
image.save("smallpi.png")  # 保存图像,并转换成png格式

下面程序从文件名列表(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’, infile)

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

创建缩略图



使用PIL可以很方便地创建图像的缩略图,thumbnail()方法接受一个一元组参数,然后将图像转换成符合元组参数指定大小的缩略图。例如:

image.thumbnail((128,128))

thumbnail函数接受一个元组作为参数,分别对应着缩略图的宽高,在缩略时,函数会保持图片的宽高比例。如果输入的参数宽高和原图像宽高比不同,则会依据最小对应边进行原比例缩放。 
比如: 
一张图片为300*420大小的图片 
当参数为(200,200)时,生成的缩略图大小为71*100,保持原图的宽高比

裁剪图像区域



使用PIL中的crop()方法可以从一幅图像中裁剪指定区域,该区域使用四元组来指定,四元组的坐标依次是(左,上,右,下)PIL中指定坐标系的左上角坐标为(0,0)。

具体代码为:

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

image = Image.open('test.jpg')
box = (500, 500, 1000, 1000)
region = image.crop(box)
data = np.array(region)
plt.imshow(data)
plt.show()

得到的结果为:

调整尺寸和旋转



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

out = image.resize((32,32))

结果为下图所示:

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

out = image.rotate(45)

结果为下图所示:

《机器学习 第九期》从零到机器学习实战项目,提供GPU&CPU双云平台,作业考试1V1批改(优秀学员内推BAT等);点击文末“阅读原文”了解详情

登录查看更多
25

相关内容

图像处理(image processing),用计算机对图像进行分析,以达到所需结果的技术。又称影像处理。图像处理一般指数字图像处理。数字图像是指用工业相机、摄像机、扫描仪等设备经过拍摄得到的一个大的二维数组,该数组的元素称为像素,其值称为灰度值。
【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
85+阅读 · 2020年6月28日
【实用书】Python机器学习Scikit-Learn应用指南,247页pdf
专知会员服务
255+阅读 · 2020年6月10日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
330+阅读 · 2020年3月17日
《深度学习》圣经花书的数学推导、原理与Python代码实现
【经典书】Python计算机视觉编程,中文版,363页pdf
专知会员服务
136+阅读 · 2020年2月16日
【电子书】Flutter实战305页PDF免费下载
专知会员服务
20+阅读 · 2019年11月7日
实战 | 用Python做图像处理(三)
七月在线实验室
15+阅读 · 2018年5月29日
实战 | 用Python做图像处理(二)
七月在线实验室
17+阅读 · 2018年5月25日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
A Survey on Bayesian Deep Learning
Arxiv
60+阅读 · 2020年7月2日
Arxiv
5+阅读 · 2019年11月22日
Nocaps: novel object captioning at scale
Arxiv
6+阅读 · 2018年12月20日
Arxiv
21+阅读 · 2018年8月30日
Arxiv
7+阅读 · 2018年6月19日
Arxiv
3+阅读 · 2017年12月14日
VIP会员
相关VIP内容
【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
85+阅读 · 2020年6月28日
【实用书】Python机器学习Scikit-Learn应用指南,247页pdf
专知会员服务
255+阅读 · 2020年6月10日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
330+阅读 · 2020年3月17日
《深度学习》圣经花书的数学推导、原理与Python代码实现
【经典书】Python计算机视觉编程,中文版,363页pdf
专知会员服务
136+阅读 · 2020年2月16日
【电子书】Flutter实战305页PDF免费下载
专知会员服务
20+阅读 · 2019年11月7日
相关资讯
实战 | 用Python做图像处理(三)
七月在线实验室
15+阅读 · 2018年5月29日
实战 | 用Python做图像处理(二)
七月在线实验室
17+阅读 · 2018年5月25日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
相关论文
Top
微信扫码咨询专知VIP会员