潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)
Python图像处理-Pillow
简介
Python传统的图像处理库PIL
(Python Imaging Library ),可以说基本上是Python处理图像的标准库,功能强大,使用简单。
但是由于PIL
不支持Python3,而且更新缓慢。所以有志愿者在PIL
的基础上创建了一个分支版本,命名为Pillow
,Pillow
目前最新支持到python3.6,更新活跃,并且增添了许多新的特性。所以我们安装Pillow即可。
安装
Pillow
的安装比较的简单,直接pip安装即可:
pip install Pillow
但是要注意的一点是,Pillow
和PIL
不能共存在同一个环境中,所以如果安装的有PIL
的话,那么安装Pillow
之前应该删除PIL
。
由于是继承自PIL
的分支,所以Pillow
的导入是这样的:
import PIL
# 或者
from PIl import Image
使用手册
Image
Image
是Pillow中最为重要的类,实现了Pillow中大部分的功能。要创建这个类的实例主要有三个方式:
从文件加载图像
处理其他图像获得
创建一个新的图像
读取图像
一般来说,我们都是都过从文件加载图像来实例化这个类,如下所示:
from PIL import Image
picture = Image.open('happy.png')
如果没有指定图片格式的话,那么Pillow
会自动识别文件内容为文件格式。
新建图像
Pillow
新建空白图像使用new()
方法, 第一个参数是mode即颜色空间模式,第二个参数指定了图像的分辨率(宽x高),第三个参数是颜色。
可以直接填入常用颜色的名称。如'red'。
也可以填入十六进制表示的颜色,如
#FF0000
表示红色。还能传入元组,比如(255, 0, 0, 255)或者(255, 0, 0)表示红色。
picture = Image.new('RGB', (200, 100), 'red')
保存图像
保存图片的话需要使用save()
方法:
picture.save('happy.png')
保存的时候,如果没有指定图片格式的话,那么Pillow
会根据输入的后缀名决定保存的文件格式。
图像的坐标表示
在Pillow中,用的是图像的左上角为坐标的原点(0,0),所以这意味着,x轴的数值是从左到右增长的,y轴的数值是从上到下增长的。
我们处理图像时,常常需要去表示一个矩形的图像区域。Pillow
中很多方法都需要传入一个表示矩形区域的元祖参数。
这个元组参数包含四个值,分别代表矩形四条边的距离X轴或者Y轴的距离。顺序是(左,顶,右,底)
。其实就相当于,矩形的左上顶点坐标为(左,顶)
,矩形的右下顶点坐标为(右,底)
,两个顶点就可以确定一个矩形的位置。
右和底坐标稍微特殊,跟python列表索引规则一样,是左闭又开的。可以理解为[左, 右)
和[顶, 底)
这样左闭右开的区间。比如(3, 2, 8, 9)就表示了横坐标范围[3, 7];纵坐标范围[2, 8]的矩形区域。
常用属性
PIL.Image.filename
图像源文件的文件名或者路径,只有使用
open()
方法创建的对象有这个属性。类型:字符串
PIL.Image.format
图像源文件的文件格式。
PIL.Image.mode
图像的模式,一般来说是“1”, “L”, “RGB”, 或者“CMYK” 。
PIL.Image.size
图像的大小
PIL.Image.width
图像的宽度
PIL.Image.height
图像的高度
PIL.Image.info
图像的一些信息,为字典格式
常用方法
裁剪图片
Image
使用crop()
方法来裁剪图像,此方法需要传入一个矩形元祖参数,返回一个新的Image
对象,对原图没有影响。
croped_im = im.crop((100, 100, 200, 200))
复制与粘贴图像
复制图像使用copy()
方法:
copyed_im = im.copy()
粘贴图像使用paste()
方法:
croped_im = im.crop((100, 100, 200, 200))
im.paste(croped_im, (0, 0))
im对象调用了paste()
方法,第一个参数是被裁剪下来用来粘贴的图像,第二个参数是一个位置参数元祖,这个位置参数是粘贴的图像的左顶点。
调整图像的大小
调整图像大小使用resize()
方法:
resized_im = im.resize((width, height))
resize()
方法会返回一个重设了大小的Image
对象。
旋转图像和翻转图像
旋转图像使用rotate()
方法,此方法按逆时针旋转,并返回一个新的Image
对象:
# 逆时针旋转90度
im.rotate(90)
im.rotate(180)
im.rotate(20, expand=True)
旋转的时候,会将图片超出边界的边角裁剪掉。如果加入expand=True
参数,就可以将图片边角保存住。
翻转图像使用transpose()
:
# 水平翻转
im.transpose(Image.FLIP_LEFT_RIGHT)
# 垂直翻转
im.transpose(Image.FLIP_TOP_BOTTOM)
获取单个像素的值
使用getpixel
(xy)方法可以获取单个像素位置的值:
im.getpixel((100, 100))
传入的xy需要是一个元祖形式的坐标。
如果图片是多通道的,那么返回的是一个元祖。
通过通道分割图片
split()
split()
可以将多通道图片按通道分割为单通道图片:
R, G, B = im.split()
split()
方法返回的是一个元祖,元祖中的元素则是分割后的单个通道的值。
getchannel(channel)
getchannel()
可以获取单个通道的数据:
R = im.getchannel("R")
加载图片全部数据
我们可以使用load()
方法加载图片所有的数据,并比较方便的修改像素的值:
pixdata = im.load()
pixdata[100,200] = 255
此方法返回的是一个PIL.PyAccess
,可以通过这个类的索引来对指定坐标的像素点进行修改。
关闭图片并释放内存
此方法会删除图片对象并释放内存
im.close()
把图片转为高对比度的图片
# -*- coding:utf-8 -*-
# 斌彬电脑
# @Time : 2018/9/11 0011 下午 2:50 from PIL import Image
im = Image.open('ss.png')
im = im.convert('L') # 灰度图片
data = im.load()
h,w = im.size # 读出图片大小,
# 不是黑的就是白的,
for i in range(h):
for j in range(w):
if data[i,j] > 128: # 根据坐标读出像素的值
data[i,j] = 255
else: data[i,j] = 0 # 得到一个高对比度的图片
im.show()
验证码简单处理
# -*- coding: utf-8 -*-
# 斌彬电脑
# @Time : 2018/9/12 0012 5:34 from PIL import Image im = Image.open('aaaaaaa.png')
im = im.convert('L') # 灰度图片
data = im.load()
h, w = im.size # 读出图片大小,
# 不是黑的就是白的,
for i in range(h):
for j in range(w):
if data[i, j] > 20: # 根据坐标读出像素的值
data[i, j] = 255
else:
data[i, j] = 0 # 降嗓
for x in range(1,h - 1):
for y in range(1,w - 1):
count = 0
if data[x - 1, y - 1] == 255:
count += 1
if data[x + 1, y + 1] == 255:
count += 1
if data[x - 1, y - 1] == 255:
count += 1
if data[x + 1, y + 1] == 255:
count += 1 # if data[x, y - 1] == 255:
# count += 1
# if data[x, y + 1] == 255:
# count += 1
# if data[x - 1, y] == 255:
# count += 1
# if data[x + 1, y] == 255:
# count += 1 if count > 2:
data[x, y] = 255 im.save('123.png')
# 得到一个高对比度的图片
im.show()
非黑即白的后处理
# -*- coding:utf-8 -*-
# 斌彬电脑
# @Time : 2018/9/12 0012 上午 8:37 from PIL import Image
import json, re im = Image.open('aaaaaaa.png')
im = im.convert('L') # 灰度图片
data = im.load()
h, w = im.size # 读出图片大小,
# 不是黑的就是白的,
for i in range(h):
for j in range(w):
if data[i, j] > 20: # 根据坐标读出像素的值
data[i, j] = 255
else:
data[i, j] = 0 # 降嗓
for x in range(1,h - 1):
for y in range(1,w - 1):
count = 0
if data[x - 1, y - 1] == 255:
count += 1
if data[x + 1, y + 1] == 255:
count += 1
if data[x - 1, y - 1] == 255:
count += 1
if data[x + 1, y + 1] == 255:
count += 1 if count > 2:
data[x, y] = 255 itm = {}
file = open('itm.json', 'a', encoding='utf8')
for x in range(1,h - 1):
itm = {}
y = 1
file.write('\n')
while (w-y)!=0:
if data[x, y] == 0:
itm[x] = y
item1 = json.dumps(itm, ensure_ascii=False )
file.write(item1)
y += 1 bb=''
with open("itm.json", "r") as f:
for i in f:
if len(i.strip()) < 50:
# print(i.strip())
bb = bb+i.strip()
# print(bb) a,b = re.findall(r"{'(.*?)':(.*?)}", bb)
print(a,b) # im.save('123.png')
# 得到一个高对比度的图
# im.show()
验证码黑白处理
# -*- coding:utf-8 -*-
# 斌彬电脑
# @Time : 2018/9/12 0012 上午 8:37 from PIL import Image
import json, re im = Image.open('9.png')
im = im.convert('L') # 灰度图片
data = im.load()
h, w = im.size # 读出图片大小,
# 不是黑的就是白的,
for i in range(h):
for j in range(w):
if data[i, j] > 50: # 根据坐标读出像素的值
data[i, j] = 255
else:
data[i, j] = 0 # 降嗓
for x in range(1, h - 1):
for y in range(1, w - 1):
count = 0
if data[x - 1, y - 1] == 255:
count += 1
if data[x + 1, y + 1] == 255:
count += 1
if data[x - 1, y - 1] == 255:
count += 1
if data[x + 1, y + 1] == 255:
count += 1 if count > 2:
data[x, y] = 255 itm = {}
file1 = open('itm.json', 'a', encoding='utf8')
for x in range(1, h - 1):
itm = {}
y = 1
file1.write('\n')
while (w - y) != 0:
if data[x, y] == 0:
itm[x] = y
item1 = json.dumps(itm, ensure_ascii=False)
file1.write(item1)
y += 1
file1.close() bb = ''
with open("itm.json", "r") as f:
for i in f:
if len(i.strip()) < 30: # 杂点大小
# print(i.strip())
bb = bb + i.strip()
# print(bb)
# {"4": 40}
a = re.findall(r'{"(.*?)":.*?}', bb)
b = re.findall(r'{".*?":(.*?)}', bb)
# print(a)
# print(b)
print(len(a),len(b))
for i in range(len(a)):
data[int(a[i]), int(b[i])] = 255 # im2 = im
# data2 = im.load()
# h2, w2 = im2.size # 读出图片大小,
# # print(h2,w2,'00000')
#
# atm = {}
# file2 = open('atm.json', 'a', encoding='utf8')
# for n in range(1, w2 - 1):
# atm = {}
# m = 1
# file2.write('\n')
# while (h2 - m) != 0:
# if data2[n, m] == 0:
# atm[n] = m
# stem1 = json.dumps(atm, ensure_ascii=False)
# file2.write(stem1)
# n += 1
# file2.close()
#
# cc = ''
# with open("atm.json", "r") as f:
# for i in f:
# if len(i.strip()) < 30: # 杂点大小
# # print(i.strip())
# cc = cc + i.strip()
# # print(bb)
# # {"4": 40}
# c = re.findall(r'{"(.*?)":.*?}', cc)
# d = re.findall(r'{".*?":(.*?)}', cc)
# # print(c)
# # print(d)
# print(len(c), len(d))
# for i in range(len(c)):
# data2[int(c[i]), int(d[i])] = 255 # im.save('123.png')
# 得到一个高对比度的图
# im2 = im2.rotate(270)
im.show()
潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)的更多相关文章
- 潭州课堂25班:Ph201805201 爬虫高级 第九课 scrapyd 部署 (课堂笔记)
c rapyd是 scrapy 的部署, 是官方提供的一个爬虫管理工具, 通过他可以非常方便的上传控制爬虫的运行, 安装 : pip install scapyd 他提供了一个json ,web, s ...
- 潭州课堂25班:Ph201805201 爬虫基础 第一课 (课堂笔记)
爬虫的概念: 其实呢,爬虫更官方点的名字叫数据采集,英文一般称作spider,就是通过编程来全自动的从互联网上采集数据.比如说搜索引擎就是一种爬虫.爬虫需要做的就是模拟正常的网络请求,比如你在网站上点 ...
- 潭州课堂25班:Ph201805201 爬虫基础 第二课 fidder (课堂笔记)
通过浏览器访问百度的详细过程? 一.通过dns获取百度IP地址.二.通过百度IP访问百度服务器, 三,返回数据. 四,通过渲染显示内容, fidder设置 tf 信任证书
- 潭州课堂25班:Ph201805201 爬虫高级 第二课 sclapy 框架 (课堂笔记)
win 下安装 sclapy 先安装 pip install wheel py 库下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 在这 ...
- 潭州课堂25班:Ph201805201 爬虫高级 第一课 pyspider框架 (课堂笔记)
利用wheel安装 S1: pip install wheelS2: 进入www.lfd.uci.edu/~gohlke/pythonlibs/,Ctrl + F查找pycurl 这个包名是pycur ...
- 潭州课堂25班:Ph201805201 WEB 之 页面编写 第四课 登录注册 (课堂笔记)
index.html 首页 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- 潭州课堂25班:Ph201805201 WEB 之 页面编写 第三课 (课堂笔记)
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 潭州课堂25班:Ph201805201 WEB 之 页面编写 第二课 (课堂笔记)
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 潭州课堂25班:Ph201805201 WEB 之 页面编写 第一课 (课堂笔记)
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
随机推荐
- dubbo系列二、dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台)
一.zookeeper配置中心安装 1.下载安装包,zookeeper-3.4.6.tar.gz 2.解压安装包,修改配置文件 参考zookeeper-3.4.6/conf/zoo_sample.cf ...
- sklearn,交叉验证中的分层抽样
StratifiedKFold用法类似Kfold,但是他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同. 例子: import numpy as np from sklearn.m ...
- PYTHON-函数的定义与调用,返回值,和参数-练习
# day10函数的定义调用和参数作业# 1.写函数,用户传入修改的文件名.与要修改的内容,执行函数,完成批量修改操作# def modify_file(filename,old,new):# imp ...
- idea开发swing(二)
闲话少说,书接idea开发swing(一). 程序编译完成后,需要打包发布,如果有fat_jar的同学可以通过该插件打包,这里是使用ant来打包,步骤如下: 一.编写build.xml <?xm ...
- python之__dict__与dir(转载)
Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案. __dict__与dir()的区别: dir()是一个函数,返回的是list: __di ...
- Linux在bash history当中添加timestamp
执行以下两条命令即可 echo 'export HISTTIMEFORMAT="%y-%m-%d %T "' >> /etc/profile source /etc/p ...
- LeetCode(37): 每k个一组翻转链表
Hard! 题目描述: 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一 ...
- STL整理之set
转载请注明出处,部分内容引自李煜东<算法竞赛进阶指南> 前置知识: C++.C语言入门 Set是什么 Set是C++STL中提供的容器,set是数学上的集合——具有唯一性,即每个元素 ...
- MySQL重复数据处理
最近工作很忙,很久没写博客,嘻嘻!今天写一遍关于MySQL重复数据处理的博客!前不久有个开发问我,能不能把重复的数据去除,留下唯一的数据.然后我问他为什么有这么重复的数据呢,他说写了程序去爬数据,爬到 ...
- python 全栈开发,Day27(复习, defaultdict,Counter,时间模块,random模块,sys模块)
一.复习 看下面一段代码,假如运行结果有问题,那么就需要在每一步计算时,打印一下结果 b = 1 c = 2 d = 3 a = b+c print(a) e = a + d print(e) 执行输 ...