圖像處理庫 pillow(一)

Python 提供了 PIL(python image library)圖像庫,來滿足開發(fā)者處理圖像的功能醒颖,該庫提供了廣泛的文件格式支持雇锡,包括常見的 JPEG、PNG贬蛙、GIF 等,它提供了圖像創(chuàng)建谚攒、圖像顯示阳准、圖像處理等功能。

基本概念

要學習 PIL 圖像庫的使用馏臭,我們必須先來了解一些關于圖像的基本概念野蝇,包括深度(depth)讼稚,通道(bands),模式(mode)绕沈,坐標系統(tǒng)(coordinate system)等锐想。

圖像的深度

圖像中像素點占得 bit 位數(shù),就是圖像的深度乍狐,比如:

二值圖像:圖像的像素點不是0就是1 (圖像不是黑色就是白色)赠摇,圖像像素點占的位數(shù)就是1位,圖像的深度就是1浅蚪,也稱作位圖藕帜。

灰度圖像:圖像的像素點位于0-255之間(0代表全黑,255代表全白惜傲,在0-255之間插入了255個等級的灰度)洽故。2^8=255,圖像像素點占的位數(shù)就是8位盗誊,圖像的深度是8时甚。

依次類推,我們把計算機中存儲單個像素點所用的 bit 位稱為圖像的深度哈踱。

圖像的通道

每張圖像都是有一個或者多個數(shù)據(jù)通道構成的荒适,如 RGB 是基本的三原色(紅色、綠色和藍色)嚣鄙,如果我們用8位代表一種顏色吻贿,那么每種顏色的最大值是255,這樣哑子,每個像素點的顏色值范圍就是(0-255, 0-255, 0-255)舅列。這樣的圖像的通道就是3。而灰度圖像的通道數(shù)是1卧蜓。

圖像的模式

圖像實際上是像素數(shù)據(jù)的矩形圖帐要,圖像的模式定義了圖像中像素的類型和深度,每種類型代表不同的深度弥奸,在 PIL 中我們稱之為圖像的模式榨惠。常見的模式有以下幾種:

1:1位像素,表示黑和白盛霎,占8 bit 赠橙,在圖像表示中稱為位圖。

L:表示黑白之間的灰度愤炸,占8 bit 像素期揪。

P:8位像素,使用調色版映射规个。

RGB:真彩色凤薛,占用 3x8 位像素姓建,其中 R 為紅色,G 為綠色缤苫,B為藍色速兔,三原色疊加形成的色彩變化,如三通道都為0則代表黑色活玲,都為255則代表白色涣狗。

RGBA:為帶透明蒙版的真彩色,其中的 A 為 alpha 透明度翼虫,占用 4x8 位像素

其他的還有 CMYK屑柔、 YCbCr、I珍剑、F等不常用的模式掸宛,這里就不多做介紹了。

圖像的坐標系

PIL 中圖像的坐標是從左上角開始招拙,向右下角延伸唧瘾,以二元組 (x,y)的形式傳遞别凤,x 軸從左到右饰序,y 軸從上到下,即左上角的坐標為 (0, 0)规哪。那么矩形用四元組表示就行求豫,例如一個450 x 450 像素的矩形圖像可以表示為 (0, 0, 450, 450)。

PIL 的安裝

和其他庫一樣诉稍,PIL 的安裝也很簡單:

pip3 install pillow

PIL 圖像模塊的功能

打開圖像

我們可以從本地目錄中打開文件蝠嘉,也可以從文件流中打開圖像。打開文件的方法為:

Image.open(file,mode)

讀取圖像文件杯巨,mode 只能是 ‘r’蚤告,所以我們也可以省略這個參數(shù)。

from PIL import Image
from io import BytesIO
import requests

# 打開圖像文件
im = Image.open('cat.jpg')

# 從文件流中打開圖像
r = requests.get('http://f.hiphotos.baidu.com/image/pic/item/b151f8198618367aa7f3cc7424738bd4b31ce525.jpg')
im2 = Image.open(BytesIO(r.content))

# 展示圖像
im.show()
im2.show()

# 翻轉90度展示
im.rotate(90).show()

我們首先打開本目錄下的 cat.jpg 圖像服爷,接著從百度圖片請求到一張圖片杜恰,使用文件流的方式打開。使用 show 方法可以展示圖像仍源。我們也可以使用 rotate 方法來是圖像翻轉角度心褐。運行程序,我們會看到彈出三張圖片笼踩,一張是 cat.jpg 對應的圖像檬寂,一張是百度圖片中的圖像,還有一種是將 cat.jpg 翻轉90度后展示的圖像戳表。

創(chuàng)建圖像

Image.new(mode,size,color)

我們可以使用給定的模式桶至、大小和顏色來創(chuàng)建新圖像。大小以(寬度匾旭,高度)的二元組形式給出镣屹,單位為像素;顏色以單波段圖像的單個值和多波段圖像的元組(每個波段的一個值)給出价涝,可以使用顏色名如 ‘red’ 女蜈,也可以受用16進制 '#FF0000' 或者使用數(shù)字表示(255,0,0)。

from PIL import Image

im = Image.new('RGB', (450, 450), (255, 0, 0))
im1 = Image.new('RGB', (450, 450), 'red')
im2 = Image.new('RGB', (450, 450), '#FF0000')
im.show()
im1.show()
im2.show()

上面例子中我們分別通過三種形式創(chuàng)建了 RGB 模式的大小為 450x450 色瘩,顏色為紅色的圖像伪窖,最終的圖像效果是一樣的。

轉換格式

Image.save(file)

我們直接使用保存方法居兆,修改保存的文件名就可以轉換圖像的格式覆山。

from PIL import Image

# 加載 cat.jpg
im = Image.open('cat.jpg', 'r')

# 打印圖片類型
print(im.format)

# 保存為 png 類型圖片
im.save('cat.png')

# 加載新保存的 png 類型圖片
im2 = Image.open('cat.png', 'r')

# 打印新保存圖片類型
print(im2.format)


# 輸出結果
JPEG
PNG

例子中我們先打開 cat.jpg 圖像,然后新保存一張類型為 png 的圖像泥栖,通過打印我們可以看到兩者的格式簇宽。

創(chuàng)建縮略圖

Image.thumbnail(size, resample=3)

修改當前圖像制作成縮略圖,該縮略圖尺寸不大于給定的尺寸吧享。這個方法會計算一個合適的縮略圖尺寸魏割,使其符合當前圖像的寬高比,調用方法 draft() 配置文件讀取器钢颂,最后改變圖像的尺寸钞它。

size 參數(shù)表示給定的最終縮略圖大小。

resample 參數(shù)是過濾器殊鞭,只能是 NEAREST、BILINEAR钱豁、BICUBIC 或者 ANTIALIAS 之一。如果省略該變量牲尺,則默認為 NEAREST。

注意:在當前PIL的版本中谤碳,濾波器 BILINEAR 和 BICUBIC 不能很好地適應縮略圖產(chǎn)生溃卡。用戶應該使 用ANTIALIAS,圖像質量最好瘸羡。如果處理速度比圖像質量更重要,可以選用其他濾波器犹赖。這個方法在原圖上進行修改队他。

from PIL import Image

# 加載圖像
im = Image.open('cat.png')

# 展示圖像
im.show()

# 圖像尺寸
size = 128, 128
# 縮放圖像
im.thumbnail(size, Image.ANTIALIAS)

# 展示圖像
im.show()

我們將一個 450x450 大小的圖像縮放成了 128x128 大小的圖像,程序運行的結果如下圖:

thumbnail.png

融合圖像

Image.blend(image1, image2, alpha)

將圖像 image1 和 圖像 im2 根據(jù) alpha 值進行融合峻村,公式為:

out = image1 * (1.0 - alpha) + image2 * alpha

image1 和 image2 表示兩個大小和模式相同的圖像麸折, alpha 是介于 0 和 1 之間的值粘昨。如果 alpha 為0,返回 image1 圖像张肾,如果 alpha 為1,返回 image2 圖像馁启。

from PIL import Image

# 藍色圖像
image1 = Image.new('RGB', (128, 128), (0, 0, 255))
# 紅色圖像
image2=Image.new('RGB', (128, 128), (255, 0, 0))
# 取中間值
im = Image.blend(image1, image2, 0.5)
image1.show()
image2.show()
# 顯示紫色圖像
im.show()

我們將一張藍色圖像和一張紅色圖像進行融合尸饺,融合度為兩張圖像各0.5进统,最終得到一張紫色圖像(因為紅色疊加藍色會調和成紫色)浪听。顯示圖像如下圖:

blend.png

像素點處理

Image.eval(image, *args)

根據(jù)傳入的函數(shù)對圖像每個像素點進行處理。第一個參數(shù) image 為需要處理的圖像對象掉分,第二個參數(shù)是函數(shù)對象克伊,有一個整數(shù)作為參數(shù)。

如果變量image所代表圖像有多個通道愿吹,那么函數(shù)作用于每一個通道。注意:函數(shù)對每個像素點只處理一次犁跪,所以不能使用隨機組件和其他生成器。

from PIL import Image

im = Image.open('cat.jpg')
im.show()

# 將每個像素值翻倍(相當于亮度翻倍)
evl1 = Image.eval(im, lambda x: x*2)
evl1.show()

# 將每個像素值減半(相當于亮度減半)
evl2 = Image.eval(im, lambda x: x/2)
evl2.show()

我們分別對圖像進行像素值翻倍和減半處理寝优,顯示效果如下圖:

eval.png

合成圖像

Image.composite(image1, image2, mask)

使用給定的兩張圖像及 mask 圖像作為透明度枫耳,創(chuàng)建出一張新的圖像。變量 mask 圖像的模式可以為“1”,“L” 或者 “RGBA”钻心。所有圖像必須有相同的尺寸。

from PIL import Image

# 打開 cat.png
image1 = Image.open('cat.png')

# 打開 flower.jpg
image2 = Image.open('flower.jpg')

# 分離image1的通道
r, g, b = image1.split()

# 合成圖像帆喇,獲得 cat + flower
im = Image.composite(image1, image2, mask=b)

image1.show()
image2.show()
im.show()

上面例子中我們將一張圖像貓(cat.png)和一張圖像花(flower.jpg)亿胸,以圖像貓的一個通道構成的蒙版進行合成预皇,就像 PS 一樣侈玄,我們最終得到貓+花的圖像吟温,結果如下圖所示:

composite.png

通過單通道創(chuàng)建圖像

Image.merge(mode,bands)

將一組單通道圖像合并成多通道圖像。參數(shù) mode 為輸出圖像的模式鲁豪,bands 為輸出圖像中每個通道的序列。

from PIL import Image

im = Image.open('cat.png')
# 將三個通道分開
im_split = im.split()

# 分別顯示三個單通道圖像
im_split[0].show()
im_split[1].show()
im_split[2].show()

# 將三個通道再次合并
im2 = Image.merge('RGB', im_split)
im2.show()

# 打開第二張圖像
im3 = Image.open('flower.jpg')
# 將第二張圖像的三個通道分開
im_split2 = im3.split()

# 將第二張圖像的第1個通道和第一張圖像的第2治唤、3通道合成一張圖像
rgbs = [im_split2[0], im_split[1], im_split[2]]
im4 = Image.merge('RGB', rgbs)
im4.show()

上面例子中糙申,我們先將 cat.jpg 圖像的三個通道分離成三張圖像宾添,效果如下圖:

merge-split.png

然后我們又將 flower.jpg 圖像的三個通道分離柜裸,最后分別取 flower.jpg 的 R 通道圖像和 cat.jpg 的 G 和 B 通道圖像合成一張新圖像,最終的效果如下圖:

merge-merge.png

總結

本節(jié)為大家介紹了 Python pillow 庫中圖像有關的幾個基本概念疙挺,以及 PIL 模塊中處理圖像的幾個常見功能。掌握了這些功能后蔬崩,我們可以打開锦爵、創(chuàng)建圖像,也可以對圖像做一些常見的如拆分险掀、合成、融合等操作,這些都是圖像處理的基礎侠鳄,需要大家好好理解和掌握。

參考資料

https://www.osgeo.cn/pillow/reference/

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末死宣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子博秫,更是在濱河造成了極大的恐慌,老刑警劉巖挡育,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朴爬,死亡現(xiàn)場離奇詭異,居然都是意外死亡召噩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門凹嘲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抵蚊,“玉大人,你說我怎么就攤上這事贞绳。” “怎么了俱尼?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵萎攒,是天一觀的道長。 經(jīng)常有香客問我耍休,道長,這世上最難降的妖魔是什么斯够? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮读规,結果婚禮上,老公的妹妹穿的比我還像新娘铃在。我一直安慰自己碍遍,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布怕敬。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矮烹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天卤唉,我揣著相機與錄音仁期,去河邊找鬼。 笑死跛蛋,一個胖子當著我的面吹牛,可吹牛的內容都是我干的押框。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼橡伞,長吁一口氣:“原來是場噩夢啊……” “哼晋被!你這毒婦竟也來了?” 一聲冷哼從身側響起挂脑,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎最域,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牺蹄,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡薄翅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鼎天。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡斋射,死狀恐怖但荤,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情腹躁,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布哑了,位于F島的核電站掂墓,受9級特大地震影響棘钞,放射性物質發(fā)生泄漏科贬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一榜掌、第九天 我趴在偏房一處隱蔽的房頂上張望乘综。 院中可真熱鬧,春花似錦卡辰、人聲如沸邪意。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽策菜。三九已至,卻和暖如春又憨,著一層夾襖步出監(jiān)牢的瞬間锭吨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工零如, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耸携。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓辕翰,卻偏偏與公主長得像狈谊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子河劝,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容