python---基础知识回顾(十一)图像处理模块PIL
前戏:
虽然PIL没有入OpenCV那样强大的功能,但是所提供的功能,在一般的图像处理中足够使用。
图像类别:
计算机绘图中有两类图像:一类是矢量图,另一类是点阵图(位图)
矢量图:
基于计算机数字对象的绘图,其图形的构成包括点,线,多边形等这样的几何图像。在实际显示的时候一般都是通过数学公式计算得到的。
所以其产生的文件比较小,而且对其进行缩放,旋转等操作后,图像不会失真。这种图像与分辨率无关,在输出结果的时候不会影响到图像的清晰度。
Flash使用的就是矢量图。其缺点就是无法表现颜色的细节变化。所以在PIL中没有包含对这类图像处理的模块。不支持矢量图像
位图:
基本组成单元为像素。
通过这些像素的不同颜色排列,就构成了颜色丰富的图像。当放大图像,可以看到像素单元,也可能会失真。
这种图像需要保存每个像素的内容,所以文件比较大。而且,其大小是随着像素的增加而增加的。
但是由于采用了像素这样微小的图形单元来下显示色彩,使得位图可以表现丰富的颜色,更加逼真。在处理图像的时候需要考虑到分辨率邮箱,这对最后的输出很重要
常见位图格式:
(1)BMP格式:
windows下的标准图像文件格式。是很多图像处理软件的中间格式。其未进行压缩,文件占用空间较大
(2)JPEG格式:
对图像的视觉不敏感部分进行了有损压缩,保持了其中主要的图像特征。文件爱你相对较小。
JPEG2000可以实现渐进传输,先传递轮廓,再传递细节数据
(3)GIF格式:
针对网络传输带宽限制开发的一种图片格式。。图像中可以包含透明区域,同时可以存储多幅静态图片而形成的连续的动画。
压缩比高,文件较小。但是只能储存不超过256色的图像
(4)PNG格式:
考虑了文件大小和图像质量的关系。采用了无损压缩方式进行压缩。
使得图像在保持质量的同时,减小了文件大小。还支持透明区域,使得其在网络设计中也具有一定的优势。
其他概念:
1.坐标:
PIL中采用的是笛卡尔坐标系,以左上点为(,),水平向右为x正,垂直向下为y正
2.像素
由于位图中是采用像素来保存颜色,所以像素的大小就是指其水平方向和垂直方向上的像素个数,1600x1200表示长为1600像素,宽为1200像素的图像大小。
3.颜色模式
颜色模式决定了图像如何描述和重现图像中的色彩。在显示和打印输出的时候会用到这个概念。
常见颜色模式有RGB,CMYK,灰度模式等,不同表达方式用在不同的领域。
一般在计算机上进行图像处理都是使用RGB,加色法(颜色通道叠加产生颜色)。
印刷上多用CMKY,采用青,品红,黄,黑四种油墨。减色法,通过色素合成后吸收光线来产生不同的颜色。
灰度颜色模式值包含灰度信息,不包含彩色信息。可以看做是只由一种颜色通道组成的,一般用8比特来表示颜色信息。
4.PIL支持的4中插值算法
()nearest
最近邻插值方法,将会选择输入图像中最近的图像来处理
()bilinear
双线性插值方法。将会对输入的图像选择2x2的区域进行线性插值
()bicubic
双立方插值方法。选择输入的图像4x4区域进行立方插值
()antialias
通过高质量的采样器作用在所有输入图像的像素上,从而得到输出图像的方法
图像缩小可以选择antialias方法,bilinear和bicubic更适用于等比例变换或者是图像放大等操作。
图像的基本处理
1.图像的读写保存
from PIL import Image img1 = Image.open("1.jpg") #使用Image模块中的open方法,从指定的图像文件中获取一个Image对象,出错触发错误
img2 = Image.Image() #构造函数定义一个空的图像对象 print(img1,type(img1)) #根据文件判别Image对象
print(img2,type(img2)) #初始Image对象 img1.show() #显示图像
img1.save("hhh.png") #注意这里可以用来保存图片,而且支持不同类型文件的转换
#保存方法
# img1.save("6.png") #根据后缀名转换格式,并且生成的文件含有文件名
# img1.save("","png") #一个没有后缀名的图片,格式在save的第二个参数中指定
注意这里的show方法被调用的时候,PIL将会生成一个临时文件,然后使用windows中的图像处理工具显示。效率极低。而且若是程序先退出,临时文件会被回收,工具显示会出错
2.获取图像的信息
当生成了Image对象后,可以通过此Image对象来获取关于此图像文件的信息。包括分辨率,文件格式,大小,颜色模式,文件名,读写属性等。对于构造函数生成的空文件对象,大部分操作不允许,因为其文件格式为NoneType
from PIL import Image img1 = Image.open("1.jpg") #使用Image模块中的open方法,从指定的图像文件中获取一个Image对象,出错触发错误
img2 = Image.open("1.gif") #获取文件尺寸大小
print(img1.size)
print(img2.size) #获取文件的颜色模式
print(img1.mode) #RGB
print(img2.mode) #P 这是啥....也是一种颜色模式 #获取文件颜色模式的通道
print(img1.getbands()) #('R',"G","B")
print(img2.getbands()) #("P",)
#{'dpi': (, ), 'jfif': , 'jfif_version': (, ), 'jfif_density': (, ), 'exif': b'Exif\x00\x00', 'jfif_unit': }
#{'duration': , 'extension': (b'NETSCAPE2.0', ), 'background': , 'version': b'GIF89a', 'loop': } #获取文件的格式
print(img1.format)
print(img2.format) #获取文件的附加信息:字典对象
print(img1.info)
print(img2.info) #值为1时,代表只读,若是想对齐操作,需要先对齐拷贝
print(img1.readonly)
print(img2.readonly)
# official modes
"": ("L", "L", ("",)),
"L": ("L", "L", ("L",)),
"I": ("L", "I", ("I",)),
"F": ("L", "F", ("F",)),
"P": ("RGB", "L", ("P",)),
"RGB": ("RGB", "L", ("R", "G", "B")),
"RGBX": ("RGB", "L", ("R", "G", "B", "X")),
"RGBA": ("RGB", "L", ("R", "G", "B", "A")),
"CMYK": ("RGB", "L", ("C", "M", "Y", "K")),
"YCbCr": ("RGB", "L", ("Y", "Cb", "Cr")),
"LAB": ("RGB", "L", ("L", "A", "B")),
"HSV": ("RGB", "L", ("H", "S", "V")),
颜色模式
3.颜色模式的转换:
from PIL import Image img1 = Image.open("1.png") #使用Image模块中的open方法,从指定的图像文件中获取一个Image对象,出错触发错误 #L:这是一种8位的灰度图像,保留了原图除颜色外的大部分图像细节
img2 = img1.convert("L")
img2.show() #灰色 #:除了颜色外,对图像本身像素也进行了修改
img3 = img1.convert("")
img3.show()
4.图像裁剪和合成
使用Image类中的crop方法可以从图像中获取一个矩形空间。
注意:其裁剪是延时的,即只有当实际操作的时候,才会从图像中获取对应区域的数据。
裁剪
from PIL import Image img1 = Image.open("1.gif") #使用Image模块中的open方法,从指定的图像文件中获取一个Image对象,出错触发错误 w,h = img1.size rec = (w/,h/,w*/,h*/) #图片九等分中间的那部分 region = img1.crop(rec) region.show()
为避免对源图像的操作,可以对其先进行拷贝。
合成:
from PIL import Image img1 = Image.open("1.png") #使用Image模块中的open方法,从指定的图像文件中获取一个Image对象,出错触发错误 w,h = img1.size rec = (w/,h/,w*/,h*/) #图片九等分中间的那部分
rec = tuple(map(int,rec)) region = img1.crop(rec)
region = region.convert('L') #------------上面是获取裁剪区域------------------------
#------------下面是开始合成图像------------------------ img2 = Image.open("1.png")
img2 = img2.copy() #拷贝源图像 # rec = tuple(map(lambda x:x+,rec)) img2.paste(region,(10,10)) #box是第二个参数,我们可以只定义左上顶点 img2.show()
设置合成时的透明度(遮罩层):
mask = region.point(lambda i:i< and ) #当值为255代表不透明,为0代表完全透明
mask = mask.convert("") img2.paste(im = region,box = (,),mask = mask)
"""
If a mask is given, this method updates only the regions
indicated by the mask. You can use either "", "L" or "RGBA"
images (in the latter case, the alpha band is used as mask).
Where the mask is , the given image is copied as is. Where
the mask is , the current value is preserved. Intermediate
values will mix the two images together, including their alpha
channels if they have them.
"""
mask
也可以将图像分解为多个颜色通道,来进行单独处理
r,g,b = region.split() #分解为多个颜色通道 img2.paste(im = region,box = (,),mask = b)
#img2.paste(im = region,box = (,),mask = r)
#img2.paste(im = region,box = (,),mask = g)
使用merge方法合成
merge_im4 = Image.merge("RGB",(g,r,b)) #不同,将颜色转变R->g G->r B->b
merge_im5 = Image.merge("RGB",(r,g,b)) #原图 merge_im4.save("mm4.png")
merge_im5.save("mm5.png")
5.图像的变换
缩放
img1 = Image.open("1.png")
img2 = img1.resize((,)) #默认nearest
img2.show()
上面resize不止可以缩小,还可以放大
但是thumbnail方法总是会得到一个不超过图像自身尺寸大小的缩略图,注意他是对源图像进行设置。所以需要copy先拷贝源图像
img1 = Image.open("1.png") #(400,380) img1.thumbnail((,)) #按最大的比例进行缩放(200,190) img1.save("2.png")
旋转
img1 = Image.open("1.png")
img2 = img1.rotate(-) #负数代表顺时针
img2.save("3.png") #大小不变,空区域为黑色
设置rotate参数expand,可以调整图片大小,为真会调整大小去容纳所有,默认为假
翻转
img1 = Image.open("1.png") #使用Image模块中的open方法,从指定的图像文件中获取一个Image对象,出错触发错误 # img2 = img1.transpose(Image.FLIP_LEFT_RIGHT) #左右翻转
# img2 = img1.transpose(Image.FLIP_TOP_BOTTOM) #上下翻转
# img2 = img1.transpose(Image.ROTATE_90) #逆时针90
# img2 = img1.transpose(Image.ROTATE_180) #逆时针180
img2 = img1.transpose(Image.ROTATE_270) #逆时针270 img2.save("3.png")
图像处理的高级应用
1.图像的通道操作ImageChopsticks模块
填充内容
from PIL import Image
import PIL.ImageChops as IC img1 = Image.Image()
img1.mode = "RGB"
img1.size = (,) img2 = IC.constant(img1,) #像素值为100,铺满 img2.save("3.png")
图像反色处理
from PIL import Image
import PIL.ImageChops as IC img1 = Image.open("1.png") img3 = IC.invert(img1) #反色处理 img3.save("3.png")
其他常见的混合模式
lighter:亮化,返回两个图像对象中更亮的像素点
darker:暗化,返回更暗的点
difference:差值模式,返回两个图像的差值对象。
multiply:正片叠底模式,若与黑混合,则输出黑,与白色不变
screen:屏幕模式。与上面的正片叠底模式相反
add:相加模式,对应像素相加
subtract:相减模式
from PIL import Image
import PIL.ImageChops as IC img1 = Image.open("7.png")
img2 = Image.open("5.png")
#亮化
IC.lighter(img1,img2).save("8.png") #是以img1为源,所以以img1的尺寸为准
注意:对于我们操作的图像,其颜色模式必须一致
print(img2.mode,img1.mode)
#暗化
IC.darker(img1,img2).save("8.png")
#差值
IC.difference(img1,img2).save("8.png")
#正片叠底
IC.multiply(img1,img2).save("8.png")
#屏幕模式
IC.screen(img1,img2).save("8.png")
#相加模式
IC.add(img1,img2).save("8.png")
#相减模式
IC.subtract(img1,img2).save("8.png")
有遮罩效果
2.图像的增强处理ImageEnhance模块
含有色彩平衡,明亮度,对比度,锐度
在其模块中都有一个公有接口enhance方法,其中一个参数factor,当其为1.0,不是保持源图像的数据;较小,不是更少的色彩,较大,更多的色彩
调整色彩平衡Color
from PIL import Image
import PIL.ImageEnhance as IE img1 = Image.open("7.png") en = IE.Color(img1) # en.enhance(0.0).save("9.png") #.0黑白
# en.enhance(0.4).save("9.png") #.4暗
# en.enhance(0.8).save("9.png") #.8较亮
# en.enhance(1.0).save("9.png") #.0正常
en.enhance(1.6).save("9.png") #.6颜色更加深
调整明亮度Brightness
from PIL import Image
import PIL.ImageEnhance as IE img1 = Image.open("7.png") en = IE.Brightness(img1) # en.enhance(0.0).save("9.png") #.0全黑
# en.enhance(0.4).save("9.png") #.4灰暗
# en.enhance(0.8).save("9.png") #.8较亮
# en.enhance(1.0).save("9.png") #.0正常
en.enhance(1.6).save("9.png") #.6非常亮
调整对比度Contrast
from PIL import Image
import PIL.ImageEnhance as IE img1 = Image.open("7.png") en = IE.Contrast(img1) # en.enhance(0.0).save("9.png") #.0全灰
# en.enhance(0.4).save("9.png") #.4灰暗
# en.enhance(0.8).save("9.png") #.8较亮
# en.enhance(1.0).save("9.png") #.0正常
en.enhance(1.6).save("9.png") #.6非常亮
调整锐度Sharpness
from PIL import Image
import PIL.ImageEnhance as IE img1 = Image.open("7.png") en = IE.Sharpness(img1) # en.enhance(0.0).save("9.png") #.0模糊
# en.enhance(0.4).save("9.png") #.4灰暗
# en.enhance(0.8).save("9.png") #.8较亮
# en.enhance(1.0).save("9.png") #.0正常
en.enhance(2.0).save("9.png") #.0锐化
3.内置滤镜ImageFilter
In the current version, kernels can only be applied to
"L" and "RGB" images.
from PIL import Image
import PIL.ImageFilter as IF img1 = Image.open("7.png")
# img2 = img1.filter(IF.BLUR) #变模糊
# img2.save("9.png") # img2 = img1.filter(IF.CONTOUR) #黑白边框素描
# img2.save("9.png") # img2 = img1.filter(IF.DETAIL) #变清晰
# img2.save("9.png") # img2 = img1.filter(IF.EDGE_ENHANCE) #边缘明显
# img2.save("9.png") # img2 = img1.filter(IF.EMBOSS) #灰色浮雕
# img2.save("9.png") img2 = img1.filter(IF.SHARPEN) #锐化
img2.save("9.png")
大多不易看出
python---基础知识回顾(十一)图像处理模块PIL的更多相关文章
- python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。
本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...
- python基础知识回顾之列表
在python 中,主要的常用数据类型有列表,元组,字典,集合,字符串.对于这些基础知识,应该要能够足够熟练掌握. 如何创建列表: # 创建一个空列表:定义一个变量,然后在等号右边放一个中括号,就创建 ...
- python基础知识回顾之字符串
字符串是python中使用频率很高的一种数据类型,内置方法也是超级多,对于常用的方法,还是要注意掌握的. #author: Administrator #date: 2018/10/20 # pyth ...
- python基础知识回顾之元组
元组与列表的方法基本一样,只不过创建元组是用小括号()把元素括起来,两者的区别在于,元组的元素不可被修改. 元组被称为只读列表,即数据可以被查询,但不能被修改,列表的切片操作适用于元组. 元组写在小括 ...
- python基础知识回顾[1]
1.声明变量 # 声明一个变量name用来存储一个字符串'apollo' name = 'apollo' # 声明一个变量age用来存储一个数字20 age = 20 # 在控制台打印变量name中存 ...
- Python 基础知识(一)
1.Python简介 1.1.Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时 ...
- python 基础知识(一)
python 基础知识(一) 一.python发展介绍 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本 ...
- python基础知识小结-运维笔记
接触python已有一段时间了,下面针对python基础知识的使用做一完整梳理:1)避免‘\n’等特殊字符的两种方式: a)利用转义字符‘\’ b)利用原始字符‘r’ print r'c:\now' ...
- Python基础知识(五)
# -*- coding: utf-8 -*-# @Time : 2018-12-25 19:31# @Author : 三斤春药# @Email : zhou_wanchun@qq.com# @Fi ...
- scrapy实战1,基础知识回顾和虚拟环境准备
视频地址 https://coding.imooc.com/learn/list/92.html 一. 基础知识回顾 1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...
随机推荐
- Spring笔记③--spring的命名空间
p:命名空间: xmlns:p="http://www.springframework.org/schema/p" 作用:简化在xml配置bean的属性 在<bean> ...
- 剑指offer:用两个栈实现队列
题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路: 可以用stack1来存所有入队的数.在出队操作中,首先将stack1中的元素清空,转移到sta ...
- 经验分享(Android开发)
以前对于Android开发一点了解都没有,当然,以前觉得是一件很高大上的事情,而且是我没有能力去做的工作,但是在这个小组合作开发Android后,我觉得我有了很大的进步,当然我的进步也是Android ...
- pktgen-dpdk 运行 run.py 报错 Config file 'default' not found 解决方法
pktgen 操作手册:http://pktgen-dpdk.readthedocs.io/en/latest/getting_started.html 执行到这一步时: $ cd <Pktge ...
- Weka平台学习
链接:http://www.cs.waikato.ac.nz/ml/weka/index.html 一简介: WEKA的全名是怀卡托智能分析环境(Waikato Environment for Kno ...
- 预则立&&他山之石--团队计划、访谈优秀前辈
团队计划&访谈内容 一.团队计划 序号 任务内容 计划完成时间 主要负责人 备注 1 对接教师报课系统 决定是否重构代码 2016.10.16 陈少铭.黄家俊 阅读CourseManageme ...
- Littleproxy的使用
介绍 LittleProxy是一个用Java编写的高性能HTTP代理,它基于Netty事件的网络库之上.它非常稳定,性能良好,并且易于集成到的项目中. 项目页面:https://github.com/ ...
- sql中详解round(),floor(),ceiling()函数的用法和区别?
round() 遵循四舍五入把原值转化为指定小数位数,如:round(1.45,0) = 1;round(1.55,0)=2floor()向下舍入为指定小数位数 如:floor(1.45,0)= 1; ...
- PHP中define和defined的区别
PHP中define和defined的区别 对于初学者会混淆这两个函数 1.define用来定义一个常量,常量也是全局范围的.不用管作用域就可以在脚本的任何地方访问 常量.一个常量一旦被定义,就不能再 ...
- PHP qq第三方登录,install时,报Not Found
最近在学习qq的第三方登录,先在慕课网中观看了相关视频,懂了原理. 然后进行操作时,在下载好SDK后,在../install/install.html中,配置了相关的openid,oppkey,cal ...