由于笔者近期的研究课题与图像后处理有关,需要通过图像处理工具对图像进行变换和处理,进而生成合适的训练图像数据。该系列文章即主要记录笔者在不同的环境下进行图像处理时常用的工具和库。在 Python 环境下,对图像的处理笔者主要使用 Pillow 库,主要操作包括对图像的读取、存储和变换等。实际应用中,Pillow 中提供的 Image 模块适合对图像整体进行变换处理操作。

注:以下介绍仅包括对应模块和函数的基础用法,故而在介绍时省略了部分参数和选项,更完备的用法和介绍可参考 Pillow 的官方文档。

安装

用户可通过 pip 直接安装 Pillow,更多安装方式可以参见这里。

pip install Pillow #安装 pillow

使用

在日常应用过程中,使用最多的是 Pillow 提供的 Image 模块,其提供了包括图像存储、变换以及一系列的相关处理功能。Pillow 使用 Image 对象来表示图像对象并基于其定义图像的属性信息以及可针对其进行的操作,后续即主要介绍通过 Image 对象可进行的图像操作。在 Python 中使用时,用户首先需从 PIL 中导入对应的 Image 模块。

from PIL import Image #通过 Image 进行图像处理相关的操作

图像读取与存储

通过 Image 提供的 open 方法读取图像,其以指定的文件名为参数,返回值为对应图像的 Image 对象,后续即可针对图像对应的 Image 对象进行操作。

im = Image.open( "test.png" ) #open 方法以图像名(或图像对象)为参数,返回一个 Image 对象

通过 Image 对象的 save 方法存储图像对象,其使用存储目标文件名为参数,也可通过 format 参数指定存储文件的格式。

im.save( "test.png" ) #im 为 Image 对象,其被保存至 test.png,不指定 format 参数时,该方法通过文件后缀推测文件类型

im.save( "test.jpg" , format="JPEG") #以 JPEG 格式保存 Image 对象 im 至文件 test.jpg 中

基本属性

图像对应的 Image 对象具备基本属性。用户可以通过这些属性获得图像最基本的信息,Image 对象的完整属性信息可以查看这里。

im.filename #Image 对象 im 对应的文件/路径名

im.mode #Image 对象图像数据的解释方式,如灰度图为 “L”,彩色图为 “RGB”等

im.size #返回图像的尺寸信息,为( width , height ) 格式的元祖

图像类型转换

不同的图像数据具有不同的图像格式,进而拥有不同的组织数据的方式。对于 RGB 图像而言,图像拥有 R、G、B 三个通道,像素数据由三个对应三通道的 8 bit 数据组成;对于黑白图像而言,其每个像素由一个 8 bit 字节表示等等。在打开图像时,open 方法会自动解析图像的格式,用户可通过 Image 对象的 mode 属性获得图像的状态。

Image 对象可通过 convert 方法进行图像类型间的转换,其使用转换的目标类型的字符串为参数,返回转换后的 Image 对象,常见的类型包括 RGB(真彩)、L(黑白)、YCbCr(视频图像)、HSV(色调饱和度亮度彩色空间)。

data = im.convert( "L" ) #获得 RGB 图像 im 的灰度图

与 numpy 数组的转换

在程序中,一般使用图像对应的 Image 对象进行图像相关的操作,针对图像数据本身的计算处理一般将 Image 对象的数据转换为 numpy 数据后进行,处理完成之后的 numpy 数据再被转换为 Image 对象进行保存。

a. 将 Image 对象转换为 numpy 数组

使用 numpy.asarray 方法( 不唯一,可参见 Array creation routines )将 Image 对象的数据转换为 numpy 数组,进而可以对其进行计算处理。转换后 numpy 数组的数据类型根据 Image 数据对象本身的数据类型推断获得,使用时也可使用 numpy.asarray 的 dtype 参数指定转换后的数据类型。

im = Image.open( "test.png" ) #打开图像 test.png ,并获得其对应的 Image 对象

data = numpy.asarray( im ) #将 Image 对象 im 的数据转换为 numpy 数组的形式,data 即为可供运算的 numpy 数组

data = numpy.asarray( im, dtype=np.uint8 )#转换图像数据为 numpy 数组,并指定其类型为 np.uint8

这里注意,对于 RGB 彩色图像而言,Image 对象的 size 参数为二元组 ( width,  height ),而将其转换为 numpy 数组后,数组的形状参数 shape 为 ( height, width, channel ),其中 channel = 3. 若是灰度图像,则转换后的 shape 为( height, width ) .而在 Pytorch 等深度学习框架中,进行卷积的输入对象的特征一般为 ( Batch, Channel, Height, Width ) 的形式,故而在使用不同的数据类型时,需要注意上述不同的数据组织方式,。

b.将 numpy 数组转换为 Image 对象

对于 numpy 数据形式的图像数据( 通过数据处理或其他途径获得 ),可通过 Image.fromarray 方法将已有的 numpy 图像数据转换为 Image 对象。根据前面的介绍, Image.fromarray 方法将格式为 ( height, width, channel ) 的数据转换为对应的 Image 对象,其 size 属性为 ( width, height ) 的形式.在使用时需要注意不同维度数据的含义。

im = Image.fromarray( data ) #data 为 numpy 数组,im 为转换获得的 Image 对象

注意,在使用 Image.fromarray 方法时可能会出现报错 raise TypeError("Cannot handle this data type"), 这是由于待转换的 numpy 数据类型可能并不符合 Image 对象所需的数据类型( 一般为 8 bit 无符号值 ),解决方法是在转换前先将 numpy 数组的数据类型转换为 np.uint8 .

im = Image.fromarray( data.astype( np.uint8 ) ) #将 numpy 数组的数据类型转换为 np.uint8 后再转换为 Image 对象

常用操作

裁剪图像——crop

可以使用 crop 方法获得图像的指定部分。crop 方法以指定 ( 左,上,右,下 ) 切割位置的元祖来定义待分割的图像部分,可以理解为定义的是切割获得的矩形的左上角和右下角位置的坐标( 同样为 width, height 的形式)。在 PIL 所支持的坐标系统中,坐标的( 0 , 0 ) 为图像的左上角,注意 ( 0 , 0 ) 指向的不是左上角的第一个像素,而是该像素位置前的位置,后续所有的坐标均为像素间的空隙位置,而不是指向像素。也就是说,第一个像素被 ( 0 , 0 ) 和 ( 0 , 1 ) 两个坐标左右包围。

part = im.crop( ( 0 , 0 , 100 , 100 ) ) #截取获得图像 im 左上角大小为 100 × 100 像素的矩形图像

通道处理——split / getchannel

split 方法将图像数据按通道分离,其返回值为包含各个通道分离数据的元组tuple,如对于 RGB 图像而言,其被分成 R、G、B 三个通道的数据。

R, G, B = im.split() #im 为真彩色 Image 对象,其被分为独立的 R、G、B 通道信息

getchannel 方法以图像的通道的索引或字符名字为参数,返回包含有对应通道数据的 L 类型的图像( 即为黑白模式 )。

R = im.getchannel( 0 ) #获得 RGB 图像的第一个通道的数据,即 R 通道信息

R = im.getchannel( "R") #同上

缩放图像——resize

resize 方法以缩放目标图像大小的元祖( Width, Heigth ) 为参数,通过指定的采样方法将图像缩放为指定的图像大小。其支持采样的方法包括 PIL.Image.NEAREST、PIL.Image.BILINEAR、PIL.Image.BICUBIC 等,resize 支持的全部采样方式见文档。注意,以上采样方法的全名为 PIL.Image.xxxx,但实际上由于之前已经使用 from PIL import Image 导入了 Image 这个模块名,故而后续可以直接使用 Image.xxxx 的形式调用上述方法,反之,在未导入模块名时需使用完整的名称来使用上述方法,下同。

data = im.resize( ( 100, 100 ) ) #将 im 对应的 Image 对象缩放为 100×100 的大小,默认采用 PIL.Image.NEAREST 方法

data = im.resize( ( 100, 100 ), Image.BICUBIC ) #使用 PIL.Image.BICUBIC 方法进行采样

翻转图像——rotate/transpose

通过 rotate 方法旋转图像,rotate 方法以旋转的角度为参数,将图像顺时针中心旋转对应的度数,并返回对应的 Image 对象。注意,通过 rotate 方法进行旋转时,结果图像是中心旋转后图像在源图像大小范围内被截取的部分,其他部分为填充。如大小为宽×高 200 * 100 的图像,经过 90 度旋转后,其大小仍为 200 * 100 ,图像内容为旋转后的理论为 100 * 200 的图像与原 200 * 100 区域的重合部分,其余部分为填充。

rotate 方法可以指定 expand 参数为 1 ,此时生成的新图像为完整包含有旋转后图像内容的最小矩形大小( 空白处为填充),如上例中,图像经过 90 度旋转后,获得的新图像的大小即为 100 * 200。更多介绍见 Image.rotate.

data = im.rotate( 90 ) #将图像顺时针旋转 90 度

data = im.rotate( 90 , expand=1 ) #将图像顺时针旋转 90 度,同时保留图像的完整内容

在某些图像训练的数据生成中,将图像进行 90 度为单位的旋转、上下或左右翻转是更为常见的操作。此时可以使用 transpose 方法,transpose 以翻转方式为参数,返回经过翻转后的图像,其支持的参数如下所示。

PIL.Image.FLIP_LEFT_RIGHT #左右翻转图像

PIL.Image.FLIP_TOP_BOTTOM #上下翻转图像

PIL.Image.ROTATE_90

PIL.Image.ROTATE_180

PIL.Image.ROTATE_270#顺时针旋转对应度数

PIL.Image.TRANSPOSE #类似于左右翻转后再逆时针旋转图像 90 度

PIL.Image.TRANSVERSE #类似与左右翻转后再顺时针旋转图像 90 度

可以直接使用上述参数对图像进行变换,transpose 方法返回变换后的完整图像( 由于是 90 度倍数的变换,也不存在空白区域 )。

data = im.transpose( Image.FLIP_LEFT_RIGHT ) #获得 im 图像经过左右旋转后的数据

python捷豹_图像处理基本工具——Python 环境下的 Pillow( PIL )相关推荐

  1. python代码覆盖率_增量代码覆盖率工具

    背景 当存量代码较多时,项目单元测试整体覆盖率就会偏低,但这可能是正常现象,因此不能依据已有的全量单元测试覆盖率来判断项目质量. 基于这个背景,我们需要统计增量代码覆盖率作为项目质量的参考指标之一,并 ...

  2. 鲲鹏云服务器运行python项目_鲲鹏云实验-Python+Jupyter机器学习基础环境

    [摘要] 介绍Ubuntu 18.04环境下Python3常用科学计算和数据分析包(numpy, scipy, matplotlib, sklearn, pandas)的安装,以及Jupyter No ...

  3. 零基础学python 视频_全网最全Python视频教程真正零基础学习Python视频教程 490集...

    Python Web开发-进阶提升 490集超强Python视频教程 真正零基础学习Python视频教程 [课程简介] 这是一门Python Web开发进阶课程,手把手教你用Python开发完整的商业 ...

  4. 3 x 10的python表达式_这道数学题用PYTHON编程语言怎么写? 编程语言python是用

    我觉着,这个应该这样解决比较符合计算机解题思路. 下面的回答的,思考的东西太多. # -*- coding: utf-8 -*- __author__ = 'lpe234' __date__ = '2 ...

  5. anaconda3对应的python版本_利用SWIG实现Python调用C/C++!速度快就算了,代码量还特少!...

    SWIG简介 SWIG是Simplified Wrapper and Interface Generator的简称,它是一个能将C和C++的程序与其他各种高级语言诸如Perl,Python,Ruby和 ...

  6. pythoncookbook和流畅的python对比_为什么你学Python效率比别人慢?因为你没有这套完整的学习资料...

    以下资源免费获取方式! 关注!转发!私信"资料"即可免费领取! 入门书籍 1.<Python基础教程>(Beginning Python From Novice to ...

  7. python虚拟环境安装包在哪_ubuntu环境下python虚拟环境的安装

    在开发中安装模块的方法: pip install 模块名称 之前我们安装模块都是直接在物理环境下安装,这种安装方法,后面一次安装的会覆盖掉前面一次安装的.那如果一台机器上面开发多个项目使用到不同版本的 ...

  8. python 计时器_谁能取代Python?我使用Go来部署机器学习模型的原因

    全文共1881字,预计学习时长7分钟 图源:unsplash 毋庸置疑,Python是如今最受欢迎的机器学习语言.虽然机器学习框架使用CUDA C / C ++之类的语言进行实际运算,但它们都提供了P ...

  9. 杭州哪里学python好_杭州哪里学python好

    1. Python 易于学习 好吧,相较于其它许多你可以拿来用的编程语言而言,它"更容易一些". Python 的语言没有多少仪式化的东西,所以就算不是一个 Python 专家,你 ...

最新文章

  1. 识别TLS加密恶意流量
  2. 数位dp 的简单入门
  3. 在ubuntu14.04 64位虚拟机中安装mysql
  4. 阿里云助力完美日记半年内系统吞吐量提升50倍
  5. ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能
  6. 技术研究院006---B站自用的微服务框架——Kratos
  7. GID绘图和CDC类
  8. Galaxy+note3+android+5.0,三星NOTE3 SM-N9008S原厂刷机包5.0Rom固件ZCSCQD1线刷包
  9. Could not find a version that satisfies the requirement tensorflow
  10. html支付系统时间,中国人民银行支付系统介绍
  11. SPF算法中的ISPF和PRC介绍
  12. 可视化html css布局,高效可视化网页布局(ViewDiv)
  13. Firefox七种武器之firebug
  14. 英飞凌XC2000系列——汽车ECU Bootloader 设计详解
  15. php或js判断网站访问者来自手机或者pc机
  16. 如何从ST官网下载STM32标准库
  17. [转载]荷香如歌_xing2516_新浪博客
  18. 中国电信广东DNS服务器
  19. 在虚拟机中开启VT功能
  20. MONTHS_BETWEEN函数使用

热门文章

  1. python编程有什么用处-python中的生成器是什么?生成器有什么用处?
  2. 怎么自学python软件-Python入门学习难吗,新手如何学习
  3. python对笔记本电脑的要求-Python的用法笔记本
  4. python文件传输模块ftplib模块的使用
  5. LeetCode Wiggle Subsequence(动态规划)
  6. Luhn算法验证信用卡的合法性
  7. redis安装后提示权限问题ERR operation not permitted
  8. Qt中禁止调节窗口大小
  9. QPixmap: It is not safe to use pixmaps outside the GUI thread原因
  10. ES6 let const 关键字