前戏:

虽然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的更多相关文章

  1. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  2. python基础知识回顾之列表

    在python 中,主要的常用数据类型有列表,元组,字典,集合,字符串.对于这些基础知识,应该要能够足够熟练掌握. 如何创建列表: # 创建一个空列表:定义一个变量,然后在等号右边放一个中括号,就创建 ...

  3. python基础知识回顾之字符串

    字符串是python中使用频率很高的一种数据类型,内置方法也是超级多,对于常用的方法,还是要注意掌握的. #author: Administrator #date: 2018/10/20 # pyth ...

  4. python基础知识回顾之元组

    元组与列表的方法基本一样,只不过创建元组是用小括号()把元素括起来,两者的区别在于,元组的元素不可被修改. 元组被称为只读列表,即数据可以被查询,但不能被修改,列表的切片操作适用于元组. 元组写在小括 ...

  5. python基础知识回顾[1]

    1.声明变量 # 声明一个变量name用来存储一个字符串'apollo' name = 'apollo' # 声明一个变量age用来存储一个数字20 age = 20 # 在控制台打印变量name中存 ...

  6. Python 基础知识(一)

    1.Python简介 1.1.Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时 ...

  7. python 基础知识(一)

    python 基础知识(一) 一.python发展介绍 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本 ...

  8. python基础知识小结-运维笔记

    接触python已有一段时间了,下面针对python基础知识的使用做一完整梳理:1)避免‘\n’等特殊字符的两种方式: a)利用转义字符‘\’ b)利用原始字符‘r’ print r'c:\now' ...

  9. Python基础知识(五)

    # -*- coding: utf-8 -*-# @Time : 2018-12-25 19:31# @Author : 三斤春药# @Email : zhou_wanchun@qq.com# @Fi ...

  10. scrapy实战1,基础知识回顾和虚拟环境准备

        视频地址 https://coding.imooc.com/learn/list/92.html   一. 基础知识回顾     1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...

随机推荐

  1. 四则运算2及PSP0设计项目计划

    时间比较紧,我简单写写我的设计思路: 题目在四则运算1的基础上控制产生题目的数量,这个可以用变量控制:打印方式也可选用变量控制,程序的关键是括号的生成.我们可以将整个四则运算式看成()+()的模型,然 ...

  2. struts2 中怎样获取HttpServletReqest

    struts2 中怎样获取HttpServletRequest 和HttpServletResponse 提供两种方法 第一种通过调用ServletActionContext这个类源代码中提供这个对象 ...

  3. ARP 询问之 校级路由器的猫腻

    前情 我为什么选定 172.17.174.73 这个 ip 来进行测试.戳前情 Scapy之ARP询问 前言 在一般家用路由器局域网下,进行 arp 广播,说:我是192.168.1.100,你们谁的 ...

  4. 【Python】LeetCode-155

    一.题目 Design a stack that supports push, pop, top, and retrieving the minimum element in constant tim ...

  5. Alpha 冲刺报告3

    队名 massivehard 组员一(组长:晓辉) 今天完成了哪些任务 .整理昨天的两个功能,补些bug 写了一个初步的loyaut github 还剩哪些任务: 后台的用来处理自然语言的服务器还没架 ...

  6. Scala入门系列(六):面向对象之object

    object object相当于class的单个实例,类似于Java中的static,通常在里面放一些静态的field和method.   第一次调用object中的方法时,会执行object的con ...

  7. TCP系列52—拥塞控制—15、前向重传与RACK重传拥塞控制处理对比

    一.概述 这里主要简单分析一个丢包重传并恢复的场景,通过不同的设置让这个相同的场景分别触发RACK重传和前向重传,通过对比说明以下问题: Forward Retransmit可以产生只有重传标记的数据 ...

  8. Delphi 使用TAdoQuery执行存储过程的样例

    procedure TCustomerForm.FindCustomerInfo;var  strSql:string;begin //  BL_HV_FindCustomerInfo 存储过程的名称 ...

  9. Android bp语法介绍

    参考网址: http://note.qidong.name/demo/soong_build/ 谷歌官网文档: https://android.googlesource.com/platform/bu ...

  10. [微软官网] SQLSERVER 执行页面还原

    执行页面还原 https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008-r2/ms175168(v=sql.105) ...