潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)
Python圖像處理-Pillow
簡介
Python傳統(tǒng)的圖像處理庫PIL(Python Imaging Library ),可以說基本上是Python處理圖像的標(biāo)準(zhǔn)庫,功能強(qiáng)大,使用簡單。
但是由于PIL不支持Python3,而且更新緩慢。所以有志愿者在PIL的基礎(chǔ)上創(chuàng)建了一個分支版本,命名為Pillow,Pillow目前最新支持到python3.6,更新活躍,并且增添了許多新的特性。所以我們安裝Pillow即可。
安裝
Pillow的安裝比較的簡單,直接pip安裝即可:
pip install Pillow但是要注意的一點(diǎn)是,Pillow和PIL不能共存在同一個環(huán)境中,所以如果安裝的有PIL的話,那么安裝Pillow之前應(yīng)該刪除PIL。
由于是繼承自PIL的分支,所以Pillow的導(dǎo)入是這樣的:
import PIL # 或者 from PIl import Image使用手冊
Image
Image是Pillow中最為重要的類,實(shí)現(xiàn)了Pillow中大部分的功能。要創(chuàng)建這個類的實(shí)例主要有三個方式:
從文件加載圖像
處理其他圖像獲得
創(chuàng)建一個新的圖像
讀取圖像
一般來說,我們都是都過從文件加載圖像來實(shí)例化這個類,如下所示:
from PIL import Image picture = Image.open('happy.png')如果沒有指定圖片格式的話,那么Pillow會自動識別文件內(nèi)容為文件格式。
新建圖像
Pillow新建空白圖像使用new()方法, 第一個參數(shù)是mode即顏色空間模式,第二個參數(shù)指定了圖像的分辨率(寬x高),第三個參數(shù)是顏色。
-
可以直接填入常用顏色的名稱。如'red'。
-
也可以填入十六進(jìn)制表示的顏色,如#FF0000表示紅色。
-
還能傳入元組,比如(255, 0, 0, 255)或者(255, 0, 0)表示紅色。
保存圖像
保存圖片的話需要使用save()方法:
picture.save('happy.png')保存的時候,如果沒有指定圖片格式的話,那么Pillow會根據(jù)輸入的后綴名決定保存的文件格式。
圖像的坐標(biāo)表示
在Pillow中,用的是圖像的左上角為坐標(biāo)的原點(diǎn)(0,0),所以這意味著,x軸的數(shù)值是從左到右增長的,y軸的數(shù)值是從上到下增長的。
我們處理圖像時,常常需要去表示一個矩形的圖像區(qū)域。Pillow中很多方法都需要傳入一個表示矩形區(qū)域的元祖參數(shù)。
這個元組參數(shù)包含四個值,分別代表矩形四條邊的距離X軸或者Y軸的距離。順序是(左,頂,右,底)。其實(shí)就相當(dāng)于,矩形的左上頂點(diǎn)坐標(biāo)為(左,頂),矩形的右下頂點(diǎn)坐標(biāo)為(右,底),兩個頂點(diǎn)就可以確定一個矩形的位置。
右和底坐標(biāo)稍微特殊,跟python列表索引規(guī)則一樣,是左閉又開的。可以理解為[左, 右)和[頂, 底)這樣左閉右開的區(qū)間。比如(3, 2, 8, 9)就表示了橫坐標(biāo)范圍[3, 7];縱坐標(biāo)范圍[2, 8]的矩形區(qū)域。
常用屬性
-
PIL.Image.filename
圖像源文件的文件名或者路徑,只有使用open()方法創(chuàng)建的對象有這個屬性。
類型:字符串
-
PIL.Image.format
圖像源文件的文件格式。
-
PIL.Image.mode
圖像的模式,一般來說是“1”, “L”, “RGB”, 或者“CMYK” 。
-
PIL.Image.size
圖像的大小
-
PIL.Image.width
圖像的寬度
-
PIL.Image.height
圖像的高度
-
PIL.Image.info
圖像的一些信息,為字典格式
常用方法
裁剪圖片
Image使用crop()方法來裁剪圖像,此方法需要傳入一個矩形元祖參數(shù),返回一個新的Image對象,對原圖沒有影響。
croped_im = im.crop((100, 100, 200, 200))復(fù)制與粘貼圖像
復(fù)制圖像使用copy()方法:
copyed_im = im.copy()粘貼圖像使用paste()方法:
croped_im = im.crop((100, 100, 200, 200)) im.paste(croped_im, (0, 0))im對象調(diào)用了paste()方法,第一個參數(shù)是被裁剪下來用來粘貼的圖像,第二個參數(shù)是一個位置參數(shù)元祖,這個位置參數(shù)是粘貼的圖像的左頂點(diǎn)。
調(diào)整圖像的大小
調(diào)整圖像大小使用resize()方法:
resized_im = im.resize((width, height))resize()方法會返回一個重設(shè)了大小的Image對象。
旋轉(zhuǎn)圖像和翻轉(zhuǎn)圖像
旋轉(zhuǎn)圖像使用rotate()方法,此方法按逆時針旋轉(zhuǎn),并返回一個新的Image對象:
# 逆時針旋轉(zhuǎn)90度 im.rotate(90) im.rotate(180) im.rotate(20, expand=True)旋轉(zhuǎn)的時候,會將圖片超出邊界的邊角裁剪掉。如果加入expand=True參數(shù),就可以將圖片邊角保存住。
翻轉(zhuǎn)圖像使用transpose():
# 水平翻轉(zhuǎn) im.transpose(Image.FLIP_LEFT_RIGHT) # 垂直翻轉(zhuǎn) im.transpose(Image.FLIP_TOP_BOTTOM)獲取單個像素的值
使用getpixel(xy)方法可以獲取單個像素位置的值:
im.getpixel((100, 100))傳入的xy需要是一個元祖形式的坐標(biāo)。
如果圖片是多通道的,那么返回的是一個元祖。
通過通道分割圖片
split()
split()可以將多通道圖片按通道分割為單通道圖片:
R, G, B = im.split()split()方法返回的是一個元祖,元祖中的元素則是分割后的單個通道的值。
getchannel(channel)
getchannel()可以獲取單個通道的數(shù)據(jù):
R = im.getchannel("R")加載圖片全部數(shù)據(jù)
我們可以使用load()方法加載圖片所有的數(shù)據(jù),并比較方便的修改像素的值:
pixdata = im.load() pixdata[100,200] = 255此方法返回的是一個PIL.PyAccess,可以通過這個類的索引來對指定坐標(biāo)的像素點(diǎn)進(jìn)行修改。
關(guān)閉圖片并釋放內(nèi)存
此方法會刪除圖片對象并釋放內(nèi)存
im.close()把圖片轉(zhuǎn)為高對比度的圖片 # -*- coding:utf-8 -*- # 斌彬電腦 # @Time : 2018/9/11 0011 下午 2:50from 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: # 根據(jù)坐標(biāo)讀出像素的值data[i,j] = 255else: data[i,j] = 0# 得到一個高對比度的圖片 im.show()
?
驗(yàn)證碼簡單處理
# -*- coding: utf-8 -*- # 斌彬電腦 # @Time : 2018/9/12 0012 5:34from PIL import Imageim = 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: # 根據(jù)坐標(biāo)讀出像素的值data[i, j] = 255else:data[i, j] = 0# 降嗓 for x in range(1,h - 1):for y in range(1,w - 1):count = 0if data[x - 1, y - 1] == 255:count += 1if data[x + 1, y + 1] == 255:count += 1if data[x - 1, y - 1] == 255:count += 1if 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 += 1if count > 2:data[x, y] = 255im.save('123.png') # 得到一個高對比度的圖片 im.show()?
非黑即白的后處理
# -*- coding:utf-8 -*- # 斌彬電腦 # @Time : 2018/9/12 0012 上午 8:37from PIL import Image import json, reim = 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: # 根據(jù)坐標(biāo)讀出像素的值data[i, j] = 255else:data[i, j] = 0# 降嗓 for x in range(1,h - 1):for y in range(1,w - 1):count = 0if data[x - 1, y - 1] == 255:count += 1if data[x + 1, y + 1] == 255:count += 1if data[x - 1, y - 1] == 255:count += 1if data[x + 1, y + 1] == 255:count += 1if count > 2:data[x, y] = 255itm = {} file = open('itm.json', 'a', encoding='utf8') for x in range(1,h - 1):itm = {}y = 1file.write('\n')while (w-y)!=0:if data[x, y] == 0:itm[x] = yitem1 = json.dumps(itm, ensure_ascii=False )file.write(item1)y += 1bb='' 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()
?
?
?
驗(yàn)證碼黑白處理
# -*- coding:utf-8 -*- # 斌彬電腦 # @Time : 2018/9/12 0012 上午 8:37from PIL import Image import json, reim = 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: # 根據(jù)坐標(biāo)讀出像素的值data[i, j] = 255else:data[i, j] = 0# 降嗓 for x in range(1, h - 1):for y in range(1, w - 1):count = 0if data[x - 1, y - 1] == 255:count += 1if data[x + 1, y + 1] == 255:count += 1if data[x - 1, y - 1] == 255:count += 1if data[x + 1, y + 1] == 255:count += 1if count > 2:data[x, y] = 255itm = {} file1 = open('itm.json', 'a', encoding='utf8') for x in range(1, h - 1):itm = {}y = 1file1.write('\n')while (w - y) != 0:if data[x, y] == 0:itm[x] = yitem1 = 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: # 雜點(diǎn)大小# 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: # 雜點(diǎn)大小 # # 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()?
轉(zhuǎn)載于:https://www.cnblogs.com/gdwz922/p/9602382.html
總結(jié)
以上是生活随笔為你收集整理的潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习篇——微信小程序开发
- 下一篇: 千位分隔符的完整攻略