Python 圖像處理 Pillow 庫(kù)詳情
前言:
圖像處理是常用的技術(shù),python 擁有豐富的第三方擴(kuò)展庫(kù),Pillow 是 Python3 最常用的圖像處理庫(kù),目前最高版本5.2.0。Python2 使用Pil庫(kù),兩者是使用方法差不多,區(qū)別在于類(lèi)的引用不同。
注意:Pil 庫(kù)與 Pillow 不能同時(shí)存在與一個(gè)環(huán)境中,如果你已經(jīng)安裝 Pil 庫(kù),那么請(qǐng)將他卸載。
使用 pip 安裝 Pillow:
> pip install Pillow
一、使用 Image.open() 創(chuàng)建圖像實(shí)例
Image 是 Pillow 最常用的類(lèi),他可以通過(guò)多種方式創(chuàng)建圖像實(shí)例。
“ from PIL import Image ”導(dǎo)入 Image 模塊。然后通過(guò) Image 類(lèi)中的 open 函數(shù)即可載入圖像文件, open 函數(shù)會(huì)自動(dòng)判斷圖片格式,只需指定文件位置即可。成功,open 函數(shù)返回一個(gè) Image 對(duì)象;載入文件失敗,則會(huì)引起 IOError 異常 。
1. 通過(guò)文件創(chuàng)建 Image 對(duì)象
通過(guò)文件創(chuàng)建 Image 圖像對(duì)象是最常用的方法
示例:通過(guò)文件創(chuàng)建 Image 圖像對(duì)象
from PIL import Image
image = Image.open('python-logo.png') # 創(chuàng)建圖像實(shí)例
# 查看圖像實(shí)例的屬性
print(image.format, image.size, image.mode)
image.show() # 顯示圖像
代碼解讀:
實(shí)例屬性說(shuō)明:
format 圖像格式
size 圖像的 (寬,高) 元組
mode 常見(jiàn)模式,默認(rèn) RGB 真彩圖像;L 為灰階圖像;CMYK 印刷色彩;RGBA 帶透明度的真彩圖像;YCbCr 彩色視頻格式;LAB L * a * b顏色空間;HSV 等。
show() 方法為使用系統(tǒng)默認(rèn)圖片查看器顯示圖像,一般用于調(diào)試;
2. 從打開(kāi)文件中讀取
可以從文件對(duì)象讀取而不是文件名,但文件對(duì)象必須實(shí)現(xiàn) read( ) ,seek( ) 和 tell( ) 方法,并且是以二進(jìn)制模式打開(kāi)。
示例:從文件對(duì)象中讀取圖像
from PIL import Image
with open("hopper.ppm", "rb") as fp:
im = Image.open(fp)
2. 從 string 二進(jìn)制流中讀取
要從字符串?dāng)?shù)據(jù)中讀取圖像,需使用 io 類(lèi):
import io from PIL import Image im = Image.open(io.StringIO(buffer))
注意:在讀取圖像 header 之前將文件倒回(使用 seek(0) )。
3. 從tar文件中讀取
from PIL import TarIO
fp = TarIO.TarIO("Imaging.tar", "Imaging/test/lena.ppm")
im = Image.open(fp)
二、讀寫(xiě)圖像
1. 格式轉(zhuǎn)換并保存圖像
Image 模塊中的 save 函數(shù)可以保存圖片,除非你指定文件格式,否則文件的擴(kuò)展名就是文件格式。
import os
from PIL import Image
image_path='python-logo.png' # 圖片位置
f, e = os.path.splitext(image_path) # 獲取文件名與后綴
outfile = f + ".jpg"
if image_path != outfile:
try:
Image.open(image_path).save(outfile) # 修改文件格式
except IOError:
print("cannot convert", image_path)
注意: 如果你的圖片mode是RGBA那么會(huì)出現(xiàn)異常,因?yàn)?RGBA 意思是紅色,綠色,藍(lán)色,Alpha 的色彩空間,Alpha 是指透明度。而 JPG 不支持透明度 ,所以要么丟棄Alpha , 要么保存為.png文件。解決方法將圖片格式轉(zhuǎn)換:
Image.open(image_path).convert("RGB").save(outfile) # convert 轉(zhuǎn)換為 RGB 格式,丟棄Alpha
save() 函數(shù)有兩個(gè)參數(shù),如果文件名沒(méi)有指定圖片格式,那么第二個(gè)參數(shù)是必須的,他指定圖片的格式。
2. 創(chuàng)建縮略圖
創(chuàng)建縮略圖 使用 Image.thumbnail( size ), size 為縮略圖寬長(zhǎng)元組。
示例: 創(chuàng)建縮略圖
import os
from PIL import Image
image_path = 'python-logo.png' # 圖片位置
size = (128, 128) # 文件大小
f, e = os.path.splitext(image_path) # 獲取文件名與后綴
outfile = f + ".thumbnail"
if image_path != outfile:
try:
im = Image.open(image_path)
im.thumbnail(size) # 設(shè)置縮略圖大小
im.save(outfile, "JPEG")
except IOError:
print("cannot convert", image_path)
注意: 出現(xiàn)異常,同上一個(gè)示例,convert("RGB")轉(zhuǎn)換圖片mode。
注意:除非必須,Pillow不會(huì)解碼或柵格數(shù)據(jù)。當(dāng)你打開(kāi)文件,Pillow通過(guò)文件頭確定文件格式,大小,mode等數(shù)據(jù),余下數(shù)據(jù)直到需要時(shí)才處理。這意味著打開(kāi)文件非??焖?,它與文件大小和壓縮格式無(wú)關(guān)。
三、剪貼,粘貼、合并圖像
Image類(lèi)包含允許您操作圖像中的區(qū)域的方法。
如:要從圖像中復(fù)制子矩形圖像使用 crop() 方法。
1. 從圖像復(fù)制子矩形
示例: 截取矩形圖像
box = (100, 100, 400, 400) region = im.crop(box)
定義box元組,表示圖像基于左上角為(0,0)的坐標(biāo),box 坐標(biāo)為 (左,上,右,下)。注意,坐標(biāo)是基于像素。示例中為 300 * 300 像素。
2. 處理子矩形并將其粘貼回來(lái)
示例: 在原圖上粘貼子矩形圖像
region = region.transpose(Image.ROTATE_180) # 顛倒180度 box = (400, 400, 700, 700) # 粘貼位置,像素必須吻合,300 * 300 im.paste(region, box)
注意:將子圖(region) 粘貼(paste)回原圖時(shí),粘貼位置 box 的像素與寬高必須吻合。而原圖和子圖的 mode 不需要匹配,Pillow會(huì)自動(dòng)處理。
示例:滾動(dòng)圖像
from PIL import Image
def roll(image, delta):
""" 向側(cè)面滾動(dòng)圖像 """
xsize, ysize = image.size
delta = delta % xsize
if delta == 0: return image
part1 = image.crop((0, 0, delta, ysize))
part2 = image.crop((delta, 0, xsize, ysize))
image.paste(part1, (xsize - delta, 0, xsize, ysize))
image.paste(part2, (0, 0, xsize - delta, ysize))
return image
if __name__ == '__main__':
image_path = 'test.jpg'
im = Image.open(image_path)
roll(im, 300).show() # 向側(cè)面滾動(dòng) 300 像素
3. 分離和合并通道
Pillow 允許處理圖像的各個(gè)通道,例如RGB圖像有R、G、B三個(gè)通道。 split 方法分離圖像通道,如果圖像為單通道則返回圖像本身。merge 合并函數(shù)采用圖像的 mode 和 通道元組為參數(shù),將它們合并成新圖像。
示例:交換RGB圖像的三個(gè)波段
r, g, b = im.split()
im = Image.merge("RGB", (b, g, r))
注意:如果要處理單色系,可以先將圖片轉(zhuǎn)換為'RGB‘
四. 幾何變換
PIL.Image.Image 包含調(diào)整圖像大小 resize() 和旋轉(zhuǎn) rotate() 的方法。前者采用元組給出新的大小,后者采用逆時(shí)針?lè)较虻慕嵌取?/p>
示例:調(diào)整大小并逆時(shí)針旋轉(zhuǎn) 45度
out = im.resize((128, 128)) out = out.rotate(45)
要以90度為單位旋轉(zhuǎn)圖像,可以使用 rotate() 或 transpose() 方法。后者也可用于圍繞其水平軸或垂直軸翻轉(zhuǎn)圖像。
示例:
out = im.transpose(Image.FLIP_LEFT_RIGHT) # 水平左右翻轉(zhuǎn) out = im.transpose(Image.FLIP_TOP_BOTTOM) # 垂直上下翻轉(zhuǎn) out = im.transpose(Image.ROTATE_90) # 逆時(shí)針90度 out = im.transpose(Image.ROTATE_180) # 逆時(shí)針180度 out = im.transpose(Image.ROTATE_270) # 逆時(shí)針270度
rotate() 和 transpose() 方法相同,他們之間沒(méi)有差別, transpose() 方法比較通用。
五. 顏色變換
示例:在 mode 之間轉(zhuǎn)換
from PIL import Image
im = Image.open("hopper.ppm").convert("L") # 轉(zhuǎn)換為灰階圖像
注意:它支持每種模式轉(zhuǎn)換為"L" 或 "RGB",要在其他模式之間進(jìn)行轉(zhuǎn)換,必須先轉(zhuǎn)換模式(通常為“RGB”圖像)。
六. 圖像增強(qiáng)
1. Filters 過(guò)濾器
ImageFilter 模塊有很多預(yù)定義的增強(qiáng)過(guò)濾器,通過(guò) filter() 方法運(yùn)用。
示例:使用 filter()
from PIL import ImageFilter out = im.filter(ImageFilter.DETAIL)
2. 像素點(diǎn)處理
point() 方法可用于轉(zhuǎn)換圖像的像素值(如對(duì)比度),在大多數(shù)情況下,可以將函數(shù)對(duì)象作為參數(shù)傳遞格此方法,它根據(jù)函數(shù)返回值對(duì)每個(gè)像素進(jìn)行處理。
示例:每個(gè)像素點(diǎn)擴(kuò)大1.2倍
out = im.point(lambda i: i * 1.2)
上述方法可以用簡(jiǎn)單的表達(dá)式進(jìn)行圖像處理,還可以通過(guò)組合 point() 和 paste() 對(duì)圖像的局部區(qū)域進(jìn)行處理 。
3. 處理單獨(dú)通道
# 將通道分離 source = im.split() R, G, B = 0, 1, 2 # 選擇紅色小于100的區(qū)域 mask = source[R].point(lambda i: i < 100 and 255) # 處理綠色 out = source[G].point(lambda i: i * 0.7) # 粘貼已處理的通道,紅色通道僅限于<100 source[G].paste(out, None, mask) # 合并圖像 im = Image.merge(im.mode, source)
注意創(chuàng)建 mask 的語(yǔ)句:
imout = im.point(lambda i: expression and 255)
對(duì)于 and 邏輯判斷來(lái)說(shuō),expression 為 False (0) 已經(jīng)能證明整個(gè)表達(dá)式為 False (0) , 否則還有對(duì)后面的結(jié)果進(jìn)行判斷。所以 expression 為 False (0) 返回 False (0) ,expression 為 True (本身的結(jié)果)是返回后面的 255;
同理對(duì)于 or 的邏輯判斷,當(dāng)前面的表達(dá)式為 True,返回前面的值;當(dāng)前面表達(dá)式為 False,返回后面表達(dá)式的值。
七、高級(jí)增強(qiáng)
其他圖像增強(qiáng)功能可以使用 ImageEnhance 模塊中的類(lèi)。從圖像創(chuàng)建后,可以使用 ImageEnhance 快速調(diào)整圖片的對(duì)比度、亮度、飽和度和清晰度。
from PIL import ImageEnhance
enh = ImageEnhance.Contrast(im) # 創(chuàng)建調(diào)整對(duì)比度對(duì)象
enh.enhance(1.3).show("增加30%對(duì)比度")
ImageEnhance 方法類(lèi)型:
ImageEnhance.Contrast(im) 對(duì)比度
ImageEnhance.Color(im) 色彩飽和度
ImageEnhance.Brightness(im) 亮度
ImageEnhance.Sharpness(im) 清晰度
八、 動(dòng)態(tài)圖像
Pillow 支持一些動(dòng)態(tài)圖像處理(如FLI/FLC,GIF等格式)。TIFF文件同樣可以包含數(shù)幀圖像。
打開(kāi)動(dòng)態(tài)圖像時(shí),PIL 會(huì)自動(dòng)加載序列中的第一幀。你可以使用 seek 和 tell 方法在不同的幀之間移動(dòng)。
示例: 讀取動(dòng)態(tài)圖像
from PIL import Image
im = Image.open("animation.gif")
im.seek(1) # 跳到第二幀
try:
while 1:
im.seek(im.tell()+1) # tell() 獲取當(dāng)前幀的索引號(hào)
except EOFError: # 當(dāng)讀取到最后一幀時(shí),Pillow拋出EOFError異常。
pass # 結(jié)束
注意:有些版本的庫(kù)中的驅(qū)動(dòng)程序僅允許您搜索下一幀。要回放文件,您可能需要重新打開(kāi)它。都遇到無(wú)法回放的庫(kù)時(shí),可以使用 for 語(yǔ)句循環(huán)實(shí)現(xiàn)。
示例:for 使用 ImageSequence Iterator 類(lèi)遍歷動(dòng)態(tài)圖像
from PIL import ImageSequence
for frame in ImageSequence.Iterator(im):
# ...處理過(guò)程...
示例:保存動(dòng)態(tài)圖像
im.save(out, save_all=True, append_images=[im1, im2, ...])
參數(shù)說(shuō)明:
out 需要保存到那個(gè)文件
save_all 為T(mén)rue,保存圖像的所有幀。否則,僅保存多幀圖像的第一幀。
append_images 需要附加為附加幀的圖像列表。列表中的每個(gè)圖像可以是單幀或多幀圖像( 目前只有GIF,PDF,TIFF和WebP支持此功能)。
九、Postscript 打印
Pillow 允許通過(guò) Postscript Printer 在圖片上添加圖像或文字。
from PIL import Image
from PIL import PSDraw
im = Image.open("test.jpg")
title = "hopper"
box = (1*72, 2*72, 7*72, 10*72) # in points
ps = PSDraw.PSDraw() # 默認(rèn) sys.stdout
ps.begin_document(title)
# 畫(huà)出圖像 (75 dpi)
ps.image(box, im, 75)
ps.rectangle(box)
# 畫(huà)出標(biāo)題
ps.setfont("HelveticaNarrow-Bold", 36)
ps.text((3*72, 4*72), title)
十、配置加載器 draft
某些解碼器允許在從文件中讀取圖像時(shí)對(duì)其進(jìn)行操作。這通常可用于創(chuàng)建縮略圖時(shí)(當(dāng)速度比質(zhì)量更重要)加速解碼并打印到單色激光打印機(jī)(僅需灰階圖像時(shí))。
draft() 方法操作已打開(kāi)但尚未加載的圖像,使其盡可能匹配給定的模式和大小。它通過(guò)重新配置圖像解碼器來(lái)完成。僅適用于JPEG和MPO文件。
示例:使用 draft() 快速解碼圖像
from PIL import Image
im = Image.open('test.jpg')
print("original =", im.mode, im.size)
im.draft("L", (100, 100))
print("draft =", im.mode, im.size)
輸出:
original = RGB (1920, 1200) draft = L (240, 150)
注意: 生成的圖像與請(qǐng)求的模式和大小可能不完全匹配。要確保圖像不大于給定大小,需改用縮略圖方法。
相關(guān)文章
pandas 數(shù)據(jù)結(jié)構(gòu)之Series的使用方法
這篇文章主要介紹了pandas 數(shù)據(jù)結(jié)構(gòu)之Series的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Python數(shù)據(jù)可視化之簡(jiǎn)單折線(xiàn)圖的繪制
這篇文章主要為大家詳細(xì)介紹了Python數(shù)據(jù)可視化之繪制簡(jiǎn)單折線(xiàn)圖的相關(guān)資料,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以了解一下2022-10-10
python實(shí)現(xiàn)簡(jiǎn)單的文字識(shí)別
這篇文章主要為大家詳細(xì)介紹了基于百度云文字識(shí)別API,python實(shí)現(xiàn)的簡(jiǎn)單文字識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
mac系統(tǒng)裝python后pip命令不能用的解決方案
這篇文章主要介紹了mac系統(tǒng)裝python后pip命令不能用的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
python中的turtle庫(kù)函數(shù)簡(jiǎn)單使用教程
這篇文章主要介紹了python中的turtle庫(kù)函數(shù)簡(jiǎn)單使用教程。本文通過(guò)圖片的形式給大家展示的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07
Pandas數(shù)據(jù)分析多文件批次聚合處理實(shí)例解析
這篇文章主要為大家介紹了Pandas數(shù)據(jù)分析多文件批次聚合處理實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
查看keras的默認(rèn)backend實(shí)現(xiàn)方式
這篇文章主要介紹了查看keras的默認(rèn)backend實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
Python調(diào)用Elasticsearch更新數(shù)據(jù)庫(kù)的操作方法
Elasticsearch是一個(gè)分布式、多租戶(hù)的全文搜索引擎,支持HTTP Web接口和無(wú)模式的JSON文檔,本文介紹Python調(diào)用Elasticsearch更新數(shù)據(jù)庫(kù)的相關(guān)操作,感興趣的朋友一起看看吧2024-12-12
python 實(shí)現(xiàn)tar文件壓縮解壓的實(shí)例詳解
這篇文章主要介紹了python 實(shí)現(xiàn)tar文件壓縮解壓的實(shí)例詳解的相關(guān)資料,這里提供實(shí)現(xiàn)方法,幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下2017-08-08
一文教會(huì)你用nginx+uwsgi部署自己的django項(xiàng)目
uWSGI是一個(gè)Web服務(wù)器,它實(shí)現(xiàn)了WSGI協(xié)議、uwsgi、http等協(xié)議,下面這篇文章主要給大家介紹了關(guān)于用nginx+uwsgi部署自己的django項(xiàng)目的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08

