Python圖像處理庫——PIL


  PIL全稱Python Image Library,是python官方的圖像處理庫,包含各種圖像處理模塊。Pillow是PIL的一個派生分支,包含與PIL相同的功能,並且更靈活。python3.0之后,PIL不再更新,pillow代替了它原有的地位。Pillow的官方文檔:

  https://pillow.readthedocs.io/en/stable/reference/index.html

  在調用pillow時,代碼依然是寫成PIL,模塊導入方式如下:

from PIL import Image,ImageFilter 

  下面介紹基本用法。

Image

  Image是pillow最基本的模塊,包含用於保存圖像對象的類。

圖像導入、旋轉、顯示、保存

from PIL import Image
img = Image.open('1.jpg')
img = img.rotate(45)
img.show()
img.save('r.jpg')

  圖像導入后保存為Image對象,該對象自帶各種函數,包括圖像處理操作、顯示、保存等功能,大部分操作返回的依然是Image對象。需要注意的是,open函數執行的時候並沒有立即把圖像像素數據導入,僅僅是對圖像文件添加占用標記,直到圖像真正需要用於計算時,才會把像素數據導入。以上代碼結果如下:

Numpy.array與Image之間的轉換

Image到array

import numpy as np
from PIL import Image

img = Image.open('1.jpg') 
a = np.array(img)
print(a.shape, a.dtype) 

  對於讀取的圖像,在Image對象中,圖像默認以RGB模式保存,且各個像素值默認用 8bit 的無符號整型來存,不論圖像以什么類型保存。因此轉換為array后dtype是uint8,不像matplotlib,png是float32,而jpg是uint8。其它圖像模式看官方文檔:

  https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes

array到Image

import numpy as np
from PIL import Image

a = np.random.random([256,256,3])*255
a = np.array(a,dtype = np.uint8)
img = Image.fromarray(a)
img.show()

  array必須先將數據類型轉換到uint8才能轉換成Image,否則會出錯,盡管文檔中寫着能有限地支持浮點類型。

圖像模式轉換

from PIL import Image

img = Image.open('1.jpg').convert('1')
img.show()

  以上代碼將Image模式從RGB轉換為1,也就是黑白兩色。效果如下:

  圖像轉換后,Image對象所對應的像素值以及對應的數據類型也就變了。顯示的時候,Pillow會以對應的模式來顯示。可以做如下實驗,先將圖像轉變為YCbCr模式,然后分別直接顯示和轉變成array后在matplotlib中顯示,代碼如下:

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

img = Image.open('1.jpg').convert('YCbCr')
img.show() # 直接顯示
img = np.array(img)  
plt.imshow(img)# matplotlib中顯示
plt.axis('off')
plt.show()

  兩個效果分別如下:

  可以看出,pillow 對轉換成 YCbCr 模式的圖像能以對應的模式顯示,而因為 matplotlib 是以RGB模式來顯示的,因此 YCbCr 模式的圖像會呈現右圖效果。

圖像縮放

等比例縮放

from PIL import Image 

size = 80,80
img = Image.open('1.jpg') 
img.thumbnail(size) 
img.show()

  按等比例縮小圖像,長寬都小於等於size。需要注意的是,這個操作是直接作用與原對象上,返回為None。而通常的操作則是返回處理得到的新對象,原對象不改變,比如上面的rotate。所以這個函數的實現有點問題,和其它的特性不同,容易導致出錯,最好少用。

直接縮放

img = img.resize([128,128],Image.BICUBIC,box = (10,50,1200,1000))

  三個參數分別表示:目標大小 (寬,高),采樣方式,用於縮放的圖像區域。

圖像混合

無透明通道

from PIL import Image 
 
img1 = Image.open('1.jpg') 
img2 = Image.open('2.jpg') 
img = Image.blend(img1,img2,0.5)
img.show()

  將兩張圖像按$\alpha : (1-\alpha)$的透明度混合,$\alpha$可以不在$(0,1)$內,結果像素值會裁剪到合理范圍內。顯示結果如下:

有透明通道

img = Image.alpha_composite(img1,img2)

  其中兩張圖像必須都有$\alpha$通道。

自定義混合

import numpy as np
from PIL import Image 
 
img1 = Image.open('1.jpg') 
img2 = Image.open('2.jpg')  
mask = np.ones([img1.size[1],img1.size[0]],dtype=np.uint8)
mask[:,img1.size[0]//2:] *= 175
mask[:,:img1.size[0]//2] *= 80
mask = Image.fromarray(mask)  
img = Image.composite(img1,img2,mask)
img.show() 

  composite函數使用mask對兩張圖像進行混合,從而不同的位置可以定義不同的透明度,以上代碼效果如下:

單像素處理

from PIL import Image
import numpy as np
img = Image.open('1.jpg') 
img = Image.eval(img, lambda x : x*np.random.rand()*2)
img.show()

  eval第二個參數傳入對單一像素的操作,這個操作會作用在整張圖像的每個像素值上。效果如下:

旋轉、鏡像

from PIL import Image

img = Image.open('1.jpg') 
img = img.transpose(1)
img.show()

  transpose 有0~6共7個輸入,代表圖像7個旋轉、鏡像方向,加上原圖,一共8個方向。

ImageFilter

  這個模塊用於圖像的濾波處理。用法也是基於Image模塊。基本用法如下:

from PIL import Image,ImageFilter

img = Image.open('1.jpg')
img = img.filter(ImageFilter.GaussianBlur(5))  
img.show()

  將ImageFilter的函數作為參數輸入filter中。還有很多種濾波方式,不一一列舉。

其它模塊

  ImageEnhance:用於圖像增強,如銳化、增亮。

  ImageGrab:用於截屏或讀取剪貼板獲取圖像。

  ImageDraw:用於繪制簡單的線條和標記。

  還有很多模塊,但感覺用起來還不如numpy+matplotlib方便,不在此記錄,有需要請看官方文檔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM