python:PIL图像处理PIL (Python Imaging Library)
Python图像处理库,该库支持多种文件格式,提供强大的图像处理功能 。
PIL中最重要的类是Image类,该类在Image模块中定义 。
从文件加载图像:
如果成功,这个函数返回一个Image对象 。现在你可以使用该对象的属性来探索文件的内容 。
format 属性指定了图像文件的格式,如果图像不是从文件中加载的则为 None。
size 属性是一个2个元素的元组,包含图像宽度和高度(像素) 。
mode 属性定义了像素格式,常用的像素格式为:“L” (luminance) - 灰度图, “RGB” , “CMYK” 。
如果文件打开失败, 将抛出IOError异常 。
一旦你拥有一个Image类的实例,你就可以用该类定义的方法操作图像 。比如:显示
( show() 的标准实现不是很有效率,因为它将图像保存到一个临时文件,然后调用外部工具(比如系统的默认图片查看软件)显示图像 。该函数将是一个非常方便的调试和测试工具 。)
接下来的部分展示了该库提供的不同功能 。
PIL支持多种图像格式 。从磁盘中读取文件,只需使用 Image 模块中的 open 函数 。不需要提供文件的图像格式 。PIL库将根据文件内容自动检测 。
如果要保存到文件,使用 Image 模块中的 save 函数 。当保存文件时,文件名很重要,除非指定格式,否则PIL库将根据文件的扩展名来决定使用哪种格式保存 。
** 转换文件到JPEG **
save 函数的第二个参数可以指定使用的文件格式 。如果文件名中使用了一个非标准的扩展名,则必须通过第二个参数来指定文件格式 。
** 创建JPEG缩略图 **
需要注意的是,PIL只有在需要的时候才加载像素数据 。当你打开一个文件时,PIL只是读取文件头获得文件格式、图像模式、图像大小等属性,而像素数据只有在需要的时候才会加载 。
这意味着打开一个图像文件是一个非常快的操作,不会受文件大小和压缩算法类型的影响 。
** 获得图像信息 **
Image 类提供了某些方法,可以操作图像的子区域 。提取图像的某个子区域,使用 crop() 函数 。
** 复制图像的子区域 **
定义区域使用一个包含4个元素的元组,(left, upper, right, lower) 。坐标原点位于左上角 。上面的例子提取的子区域包含300x300个像素 。
该区域可以做接下来的处理然后再粘贴回去 。
** 处理子区域然后粘贴回去 **
当往回粘贴时,区域的大小必须和参数匹配 。另外区域不能超出图像的边界 。然而原图像和区域的颜色模式无需匹配 。区域会自动转换 。
** 滚动图像 **
paste() 函数有个可选参数,接受一个掩码图像 。掩码中255表示指定位置为不透明,0表示粘贴的图像完全透明,中间的值表示不同级别的透明度 。
PIL允许分别操作多通道图像的每个通道,比如RGB图像 。split() 函数创建一个图像集合,每个图像包含一个通道 。merge() 函数接受一个颜色模式和一个图像元组,然后将它们合并为一个新的图像 。接下来的例子交换了一个RGB图像的三个通道 。
** 分离和合并图像通道 **
对于单通道图像,split() 函数返回图像本身 。如果想处理各个颜色通道 , 你可能需要先将图像转为RGB模式 。
resize() 函数接受一个元组,指定图像的新大小 。
rotate() 函数接受一个角度值,逆时针旋转 。
** 基本几何变换 **
图像旋转90度也可以使用 transpose() 函数 。transpose() 函数也可以水平或垂直翻转图像 。
** transpose **
transpose() 和 rotate() 函数在性能和结果上没有区别 。
更通用的图像变换函数为 transform()。
PIL可以转换图像的像素模式 。
** 转换颜色模式 **
PIL库支持从其他模式转为“L”或“RGB”模式,其他模式之间转换,则需要使用一个中间图像,通常是“RGB”图像 。
ImageFilter 模块包含多个预定义的图像增强过滤器用于 filter() 函数 。
** 应用过滤器 **
point() 函数用于操作图像的像素值 。该函数通常需要传入一个函数对象 , 用于操作图像的每个像素:
** 应用点操作 **
使用以上技术可以快速地对图像像素应用任何简单的表达式 。可以结合 point() 函数和 paste 函数修改图像 。
** 处理图像的各个通道 **
注意用于创建掩码图像的语法:
Python计算逻辑表达式采用短路方式,即:如果and运算符左侧为false,就不再计算and右侧的表达式,而且返回结果是表达式的结果 。比如 a and b 如果a为false则返回a,如果a为true则返回b,详见Python语法 。
对于更多高级的图像增强功能,可以使用 ImageEnhance 模块中的类 。
可以调整图像对比度、亮度、色彩平衡、锐度等 。
** 增强图像 **
PIL库包含对图像序列(动画格式)的基本支持 。支持的序列格式包括 FLI/FLC 、 GIF 和一些实验性的格式 。TIFF 文件也可以包含多个帧 。
当打开一个序列文件时,PIL库自动加载第一帧 。你可以使用 seek() 函数 tell() 函数在不同帧之间移动 。
** 读取序列 **
如例子中展示的,当序列到达结尾时,将抛出EOFError异常 。
注意当前版本的库中多数底层驱动只允许seek到下一帧 。如果想回到前面的帧 , 只能重新打开图像 。
以下迭代器类允许在for语句中循环遍历序列:
** 一个序列迭代器类 **
PIL库包含一些函数用于将图像、文本打印到Postscript打印机 。以下是一个简单的例子 。
** 打印到Postscript **
如前所述,可以使用 open() 函数打开图像文件,通常传入一个文件名作为参数:
如果打开成功,返回一个Image对象,否则抛出IOError异常 。
也可以使用一个file-like object代替文件名(暂可以理解为文件句柄) 。该对象必须实现read,seek,tell函数,必须以二进制模式打开 。
** 从文件句柄打开图像 **
如果从字符串数据中读取图像,使用StringIO类:
** 从字符串中读取 **
如果图像文件内嵌在一个大文件里,比如 tar 文件中 。可以使用ContainerIO或TarIO模块来访问 。
** 从tar文档中读取 **
** 该小节不太理解,请参考原文 **
有些解码器允许当读取文件时操作图像 。通常用于在创建缩略图时加速解码(当速度比质量重要时)和输出一个灰度图到激光打印机时 。
draft() 函数 。
** Reading in draft mode **
输出类似以下内容:
注意结果图像可能不会和请求的模式和大小匹配 。如果要确保图像不大于指定的大小 , 请使用 thumbnail 函数 。
Python2.7 教程 PIL
Python 之 使用 PIL 库做图像处理
来自
Python如何图像识别?1. 简介 。
图像处理是一门应用非常广的技术,而拥有非常丰富第三方扩展库的 Python 当然不会错过这一门盛宴 。PIL (Python Imaging Library)是 Python 中最常用的图像处理库 , 目前版本为 1.1.7,我们可以 在这里 下载学习和查找资料 。
Image 类是 PIL 库中一个非常重要的类,通过这个类来创建实例可以有直接载入图像文件,读取处理过的图像和通过抓取的方法得到的图像这三种方法 。
2. 使用 。
导入 Image 模块 。然后通过 Image 类中的 open 方法即可载入一个图像文件 。如果载入文件失败,则会引起一个 IOError ;若无返回错误,则 open 函数返回一个 Image 对象 。现在,我们可以通过一些对象属性来检查文件内容,即:
1import Image
2im = Image.open("j.jpg")
3print im.format, im.size, im.mode
4 JPEG (440, 330) RGB
这里有三个属性,我们逐一了解 。
format : 识别图像的源格式,如果该文件不是从文件中读取的,则被置为 None 值 。
size : 返回的一个元组,有两个元素,其值为象素意义上的宽和高 。
mode : RGB(true color image) , 此外还有 , L(luminance),CMTK(pre-press image) 。
现在,我们可以使用一些在 Image 类中定义的方法来操作已读取的图像实例 。比如 , 显示最新载入的图像:
1 im.show()
2
输出原图:
3. 函数概貌 。
3.1Reading and Writing Images : open( infilename ) , save( outfilename )
3.2Cutting and Pasting and Merging Images :
crop() : 从图像中提取出某个矩形大小的图像 。它接收一个四元素的元组作为参数 , 各元素为(left, upper, right, lower),坐标系统的原点(0, 0)是左上角 。
paste() :
merge() :
1box = (100, 100, 200, 200)
2region = im.crop(box)
3region.show()
4region = region.transpose(Image.ROTATE_180)
5region.show()
6im.paste(region, box)
7im.show()
其效果图为:
旋转一幅图片:
1 def roll(image, delta):
2"Roll an image sideways"
3
4xsize, ysize = image.size
5
6delta = delta % xsize
7if delta == 0: return image
8
9part1 = image.crop((0, 0, delta, ysize))
10part2 = image.crop((delta, 0, xsize, ysize))
11image.paste(part2, (0, 0, xsize-delta, ysize))
12image.paste(part1, (xsize-delta, 0, xsize, ysize))
13
14return image
3.3几何变换 。
3.3.1简单的几何变换 。
1 out = im.resize((128, 128))#
2out = im.rotate(45)#逆时针旋转 45 度角 。
3out = im.transpose(Image.FLIP_LEFT_RIGHT)#左右对换 。
4out = im.transpose(Image.FLIP_TOP_BOTTOM)#上下对换 。
5out = im.transpose(Image.ROTATE_90)#旋转 90 度角 。
6out = im.transpose(Image.ROTATE_180)#旋转 180 度角 。
7 out = im.transpose(Image.ROTATE_270)#旋转 270 度角 。
各个调整之后的图像为:
图片1:
图片2:
图片3:
图片4:
3.3.2色彩空间变换 。
convert() : 该函数可以用来将图像转换为不同色彩模式 。
3.3.3图像增强 。
Filters : 在 ImageFilter 模块中可以使用 filter 函数来使用模块中一系列预定义的增强滤镜 。
1import ImageFilter
2imfilter = im.filter(ImageFilter.DETAIL)
3imfilter.show()
3.4序列图像 。
即我们常见到的动态图 , 最常见的后缀为 .gif,另外还有 FLI / FLC。PIL 库对这种动画格式图也提供了一些基本的支持 。当我们打开这类图像文件时,PIL 自动载入图像的第一帧 。我们可以使用 seek 和 tell 方法在各帧之间移动 。
1 import Image
2 im.seek(1)# skip to the second frame
3
4 try:
5while 1:
6im.seek( im.tell()1)
7# do something to im
8 except EOFError:
9pass
3.5更多关于图像文件的读取 。
最基本的方式:im = Image.open("filename")
类文件读?。篺p = open("filename", "rb"); im = Image.open(fp)
字符串数据读?。篿mport StringIO; im = Image.open(StringIO.StringIO(buffer))
从归档文件读?。篿mport TarIO; fp = TarIo.TarIO("Image.tar", "Image/test/lena.ppm"); im = Image.open(fp)
基本的 PIL 目前就练习到这里 。其他函数的功能可点击 这里 进一步阅读 。
python 常用的系统函数有哪些1.常用内置函数:(不用import就可以直接使用)
help(obj) 在线帮助, obj可是任何类型
callable(obj) 查看一个obj是不是可以像函数一样调用
repr(obj) 得到obj的表示字符串 , 可以利用这个字符串eval重建该对象的一个拷贝
eval_r(str) 表示合法的python表达式,返回这个表达式
dir(obj) 查看obj的name space中可见的name
hasattr(obj,name) 查看一个obj的name space中是否有name
getattr(obj,name) 得到一个obj的name space中的一个name
setattr(obj,name,value) 为一个obj的name space中的一个name指向vale这个object
delattr(obj,name) 从obj的name space中删除一个name
vars(obj) 返回一个object的name space 。用dictionary表示
locals() 返回一个局部name space,用dictionary表示
globals() 返回一个全局name space,用dictionary表示
type(obj) 查看一个obj的类型
isinstance(obj,cls) 查看obj是不是cls的instance
issubclass(subcls,supcls) 查看subcls是不是supcls的子类
类型转换函数
chr(i) 把一个ASCII数值,变成字符
ord(i) 把一个字符或者unicode字符,变成ASCII数值
oct(x) 把整数x变成八进制表示的字符串
hex(x) 把整数x变成十六进制表示的字符串
str(obj) 得到obj的字符串描述
list(seq) 把一个sequence转换成一个list
tuple(seq) 把一个sequence转换成一个tuple
dict(),dict(list) 转换成一个dictionary
int(x) 转换成一个integer
long(x) 转换成一个long interger
float(x) 转换成一个浮点数
complex(x) 转换成复数
max(...) 求最大值
min(...) 求最小值
用于执行程序的内置函数
complie 如果一段代码经常要使用,那么先编译,再运行会更快 。
2.和操作系统相关的调用
系统相关的信息模块 import sys
sys.argv是一个list,包含所有的命令行参数.
sys.stdout sys.stdin sys.stderr 分别表示标准输入输出,错误输出的文件对象.
sys.stdin.readline() 从标准输入读一行 sys.stdout.write("a") 屏幕输出a
sys.exit(exit_code) 退出程序
sys.modules 是一个dictionary , 表示系统中所有可用的module
sys.platform 得到运行的操作系统环境
sys.path 是一个list,指明所有查找module,package的路径.
操作系统相关的调用和操作 import os
os.environ 一个dictionary 包含环境变量的映射关系 os.environ["HOME"] 可以得到环境变量HOME的值
os.chdir(dir) 改变当前目录 os.chdir('d:\\outlook') 注意windows下用到转义
os.getcwd() 得到当前目录
os.getegid() 得到有效组idos.getgid() 得到组id
os.getuid() 得到用户idos.geteuid() 得到有效用户id
os.setegid os.setegid() os.seteuid() os.setuid()
os.getgruops() 得到用户组名称列表
os.getlogin() 得到用户登录名称
os.getenv 得到环境变量
os.putenv 设置环境变量
os.umask 设置umask
os.system(cmd) 利用系统调用 , 运行cmd命令
操作举例:
os.mkdir('/tmp/xx') os.system("echo 'hello'/tmp/xx/a.txt") os.listdir('/tmp/xx')
os.rename('/tmp/xx/a.txt','/tmp/xx/b.txt') os.remove('/tmp/xx/b.txt') os.rmdir('/tmp/xx')
用python编写一个简单的shell
#!/usr/bin/python
import os, sys
cmd = sys.stdin.readline()
while cmd:
os.system(cmd)
cmd = sys.stdin.readline()
用os.path编写平台无关的程序
os.path.abspath("1.txt") == os.path.join(os.getcwd(), "1.txt")
os.path.split(os.getcwd()) 用于分开一个目录名称中的目录部分和文件名称部分 。
os.path.join(os.getcwd(), os.pardir, 'a', 'a.doc') 全成路径名称.
os.pardir 表示当前平台下上一级目录的字符 ..
os.path.getctime("/root/1.txt")返回1.txt的ctime(创建时间)时间戳
os.path.exists(os.getcwd()) 判断文件是否存在
os.path.expanduser('~/dir') 把~扩展成用户根目录
os.path.expandvars('$PATH') 扩展环境变量PATH
os.path.isfile(os.getcwd()) 判断是否是文件名,1是0否
os.path.isdir('c:\Python26\temp') 判断是否是目录,1是0否
os.path.islink('/home/huaying/111.sql') 是否是符号连接 windows下不可用
os.path.ismout(os.getcwd()) 是否是文件系统安装点 windows下不可用
os.path.samefile(os.getcwd(), '/home/huaying') 看看两个文件名是不是指的是同一个文件
os.path.walk('/home/huaying', test_fun, "a.c")
遍历/home/huaying下所有子目录包括本目录,对于每个目录都会调用函数test_fun.
例:在某个目录中 , 和他所有的子目录中查找名称是a.c的文件或目录 。
def test_fun(filename, dirname, names): //filename即是walk中的a.c dirname是访问的目录名称
if filename in names: //names是一个list,包含dirname目录下的所有内容
print os.path.join(dirname, filename)
os.path.walk('/home/huaying', test_fun, "a.c")
文件操作
打开文件
f = open("filename", "r") r只读 w写 rw读写 rb读二进制 wb写二进制 w 写追加
读写文件
f.write("a") f.write(str) 写一字符串 f.writeline() f.readlines() 与下read类同
f.read() 全读出来 f.read(size) 表示从文件中读取size个字符
f.readline() 读一行,到文件结尾,返回空串. f.readlines() 读取全部 , 返回一个list. list每个元素表示一行,包含"\n"\
f.tell() 返回当前文件读取位置
f.seek(off, where) 定位文件读写位置. off表示偏移量,正数向文件尾移动 , 负数表示向开头移动 。
where为0表示从开始算起,1表示从当前位置算,2表示从结尾算.
f.flush() 刷新缓存
关闭文件
f.close()
【tell函数python tell函数用法】regular expression 正则表达式 import re
简单的regexp
p = re.compile("abc") if p.match("abc") : print "match"
上例中首先生成一个pattern(模式),如果和某个字符串匹配 , 就返回一个match object
除某些特殊字符metacharacter元字符,大多数字符都和自身匹配 。
这些特殊字符是。^ $ *? { [ ] \ | ( )
字符集合(用[]表示)
列出字符,如[abc]表示匹配a或b或c,大多数metacharacter在[]中只表示和本身匹配 。例:
a = ".^$* ?{\\|()"大多数metachar在[]中都和本身匹配,但"^[]\"不同
p = re.compile("[" a "]")
for i in a:
if p.match(i):
print "[%s] is match" %i
else:
print "[%s] is not match" %i
在[]中包含[]本身,表示"["或者"]"匹配.用
和
表示.
^出现在[]的开头,表示取反.[^abc]表示除了a,b,c之外的所有字符 。^没有出现在开头,即于身身匹配 。
-可表示范围.[a-zA-Z]匹配任何一个英文字母 。[0-9]匹配任何数字 。
\在[]中的妙用 。
\d [0-9]
\D [^0-9]
\s [ \t\n\r\f\v]
\S [^ \t\n\r\f\v]
\w [a-zA-Z0-9_]
\W [^a-zA-Z0-9_]
\t 表示和tab匹配, 其他的都和字符串的表示法一致
\x20 表示和十六进制ascii 0x20匹配
有了\,可以在[]中表示任何字符 。注:单独的一个"."如果没有出现[]中,表示出了换行\n以外的匹配任何字符,类似[^\n].
regexp的重复
{m,n}表示出现m个以上(含m个),n个以下(含n个).如ab{1,3}c和abc,abbc,abbbc匹配,不会与ac,abbbc匹配 。
m是下界,n是上界 。m省略表下界是0,n省略,表上界无限大 。
*表示{,}表示{1,} ?表示{0,1}
最大匹配和最小匹配 python都是最大匹配,如果要最小匹配,在*, ,?,{m,n}后面加一个?.
match object的end可以得到匹配的最后一个字符的位置 。
re.compile("a*").match('aaaa').end()4最大匹配
re.compile("a*?").match('aaaa').end()0最小匹配
使用原始字符串
字符串表示方法中用\\表示字符\.大量使用影响可读性 。
解决方法:在字符串前面加一个r表示raw格式 。
a = r"\a" print a 结果是\a
a = r"\"a" print a 结果是\"a
使用re模块
先用re.compile得到一个RegexObject 表示一个regexp
后用pattern的match,search的方法,得到MatchObject
再用match object得到匹配的位置,匹配的字符串等信息
RegxObject常用函数:
re.compile("a").match("abab") 如果abab的开头和re.compile("a")匹配 , 得到MatchObject
_sre.SRE_Match object at 0x81d43c8
print re.compile("a").match("bbab")
None 注:从str的开头开始匹配
re.compile("a").search("abab") 在abab中搜索第一个和re_obj匹配的部分
_sre.SRE_Match object at 0x81d43c8
print re.compile("a").search("bbab")
_sre.SRE_Match object at 0x8184e18 和match()不同,不必从开头匹配
re_obj.findall(str) 返回str中搜索所有和re_obj匹配的部分.
返回一个tuple,其中元素是匹配的字符串.
MatchObject的常用函数
m.start() 返回起始位置,m.end()返回结束位置(不包含该位置的字符).
m.span() 返回一个tuple表示(m.start(), m.end())
m.pos(), m.endpos(), m.re(), m.string()
m.re().search(m.string(), m.pos(), m.endpos()) 会得到m本身
m.finditer()可以返回一个iterator,用来遍历所有找到的MatchObject.
for m in re.compile("[ab]").finditer("tatbxaxb"):
print m.span()
高级regexp
| 表示联合多个regexp. A B两个regexp,A|B表示和A匹配或者跟B匹配.
^ 表示只匹配一行的开始行首,^只有在开头才有此特殊意义 。
$ 表示只匹配一行的结尾
\A 表示只匹配第一行字符串的开头 ^匹配每一行的行首
\Z 表示只匹配行一行字符串的结尾 $匹配第一行的行尾
\b 只匹配词的边界 例:\binfo\b 只会匹配"info" 不会匹配information
\B 表示匹配非单词边界
示例如下:
print re.compile(r"\binfo\b").match("info ") #使用raw格式 \b表示单词边界
_sre.SRE_Match object at 0x817aa98
print re.compile("\binfo\b").match("info ") #没有使用raw \b表示退格符号
None
print re.compile("\binfo\b").match("\binfo\b ")
_sre.SRE_Match object at 0x8174948
分组(Group) 示例:re.compile("(a(b)c)d").match("abcd").groups()('abc', 'b')
#!/usr/local/bin/python
import re
x = """
name: Charles
Address: BUPT
name: Ann
Address: BUPT
"""
#p = re.compile(r"^name:(.*)\n^Address:(.*)\n", re.M)
p = re.compile(r"^name:(?P.*)\n^Address:(?P.*)\n", re.M)
for m in p.finditer(x):
print m.span()
print "here is your friends list"
print "%s, %s"%m.groups()
Compile Flag
用re.compile得到RegxObject时,可以有一些flag用来调整RegxObject的详细特征.
DOTALL, S 让.匹配任意字符,包括换行符\n
IGNORECASE, I 忽略大小写
LOCALES, L 让\w \W \b \B和当前的locale一致
MULTILINE, M 多行模式,只影响^和$(参见上例)
VERBOSE, X verbose模式
关于python中file.tell()的问题因为这个方法返回文件读写指针当前所处tell函数python的位置,它是从文件开头开始算起tell函数python的字节数 。一定要注意了tell函数python,是字节数,不是字符数 。
详细参考tell函数python:刘江的教程
tell函数python的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于tell函数用法、tell函数python的信息别忘了在本站进行查找喔 。
推荐阅读
- 路由器问题怎么办理,路由器出了问题怎么弄
- ios屏幕显示怎么调整大小,iphone屏幕变大怎么设置
- 十大网络射击游戏,十大网络射击游戏排行榜
- python导入本地函数 python导入函数的几种写法
- 银杏视频为什么这么耗电,银杏视频是病毒软件吗
- oracle存储过程无法编辑,oracle存储过程无效是什么意思
- java写轰炸代码怎么用,js轰炸代码
- python的帮助函数 python的帮助文件
- 电视盒怎么换路由器设置,教你一招电视盒子零成本变身路由器