圖像處理庫 pillow(一)

Python 提供了 PIL(python image library)圖像庫,來知足開發者處理圖像的功能,該庫提供了普遍的文件格式支持,包括常見的 JPEG、PNG、GIF 等,它提供了圖像建立、圖像顯示、圖像處理等功能。python

基本概念

要學習 PIL 圖像庫的使用,咱們必須先來了解一些關於圖像的基本概念,包括深度(depth),通道(bands),模式(mode),座標系統(coordinate system)等。bash

圖像的深度

圖像中像素點佔得 bit 位數,就是圖像的深度,好比:函數

二值圖像:圖像的像素點不是0就是1 (圖像不是黑色就是白色),圖像像素點佔的位數就是1位,圖像的深度就是1,也稱做位圖。學習

灰度圖像:圖像的像素點位於0-255之間(0表明全黑,255表明全白,在0-255之間插入了255個等級的灰度)。2^8=255,圖像像素點佔的位數就是8位,圖像的深度是8。ui

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

圖像的通道

每張圖像都是有一個或者多個數據通道構成的,如 RGB 是基本的三原色(紅色、綠色和藍色),若是咱們用8位表明一種顏色,那麼每種顏色的最大值是255,這樣,每一個像素點的顏色值範圍就是(0-255, 0-255, 0-255)。這樣的圖像的通道就是3。而灰度圖像的通道數是1。code

圖像的模式

圖像其實是像素數據的矩形圖,圖像的模式定義了圖像中像素的類型和深度,每種類型表明不一樣的深度,在 PIL 中咱們稱之爲圖像的模式。常見的模式有如下幾種:orm

1:1位像素,表示黑和白,佔8 bit ,在圖像表示中稱爲位圖。cdn

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’,因此咱們也能夠省略這個參數。

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度後展現的圖像。

建立圖像

Image.new(mode,size,color)

咱們可使用給定的模式、大小和顏色來建立新圖像。大小以(寬度,高度)的二元組形式給出,單位爲像素;顏色以單波段圖像的單個值和多波段圖像的元組(每一個波段的一個值)給出,可使用顏色名如 ‘red’ ,也能夠受用16進制 '#FF0000' 或者使用數字表示(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()
複製代碼

上面例子中咱們分別經過三種形式建立了 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 的圖像,經過打印咱們能夠看到二者的格式。

建立縮略圖

Image.thumbnail(size, resample=3)

修改當前圖像製做成縮略圖,該縮略圖尺寸不大於給定的尺寸。這個方法會計算一個合適的縮略圖尺寸,使其符合當前圖像的寬高比,調用方法 draft() 配置文件讀取器,最後改變圖像的尺寸。

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

resample 參數是過濾器,只能是 NEAREST、BILINEAR、BICUBIC 或者 ANTIALIAS 之一。若是省略該變量,則默認爲 NEAREST。

注意:在當前PIL的版本中,濾波器 BILINEAR 和 BICUBIC 不能很好地適應縮略圖產生。用戶應該使 用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 根據 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)

根據傳入的函數對圖像每一個像素點進行處理。第一個參數 image 爲須要處理的圖像對象,第二個參數是函數對象,有一個整數做爲參數。

若是變量image所表明圖像有多個通道,那麼函數做用於每個通道。注意:函數對每一個像素點只處理一次,因此不能使用隨機組件和其餘生成器。

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 圖像做爲透明度,建立出一張新的圖像。變量 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

經過單通道建立圖像

Image.merge(mode,bands)

將一組單通道圖像合併成多通道圖像。參數 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個通道和第一張圖像的第二、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

總結

本節爲你們介紹了 Python pillow 庫中圖像有關的幾個基本概念,以及 PIL 模塊中處理圖像的幾個常見功能。掌握了這些功能後,咱們能夠打開、建立圖像,也能夠對圖像作一些常見的如拆分、合成、融合等操做,這些都是圖像處理的基礎,須要你們好好理解和掌握。

參考資料

www.osgeo.cn/pillow/refe…

相關文章
相關標籤/搜索