第97天:圖像庫 PIL(二)

by 閒歡

上節我們講了 Python 的圖像處理庫 PIL 的基本圖像處理功能,打開了 PIL 的神祕面紗。這節我們接着講 PIL 的 Image 模塊的常用方法。

Image 模塊的方法

convert

Image.convert(mode=None, matrix=None, dither=None, palette=0, colors=256)

參數說明:

  • mode:轉換的模式
  • matrix:可選轉變矩陣。如果給出,必須爲包含浮點值長爲 4 或 12 的元組。
  • dither:抖動方法。RGB 轉換爲 P;RGB 或 L 轉換爲 1 時使用。有 matrix 參數可以無 dither。參數值 NONE 或 FLOYDSTEINBERG(默認)。
  • palette:調色板,在 RGB 轉換爲 P 時使用, 值爲 WEB 或 ADAPTIVE 。
  • colors:調色板的顏色值,默認 256.

轉換圖片模式,它支持每種模式轉換爲"L" 、 "RGB"和 "CMYK"。
有 matrix 參數只能轉換爲"L" 或 "RGB"。
當模式之間不能轉換時,可以先轉換 RGB 模式,然後在轉換。
色彩模式轉換爲 L 模式計算公式
如下:

L = R * 299/1000 + G * 587/1000 + B * 114/1000

我們一般使用時,只用傳需要轉換的 mode 即可,其他的可選參數需要先理解圖片深層次的原理後纔可以理解,大家如果感興趣可以去深入瞭解一下。下面我們來看一個簡單實例:

from PIL import Image

im = Image.open('cat.png')
im.show()
# 將圖像轉換成黑白色並返回新圖像
im1 = im.convert('L')
im1.show()

我們將一個圖像轉換成 L模式(灰色),轉換結果如下圖所示:

copy

Image.copy()

複製圖像方法,該方法完全複製一個一模一樣的圖像,很好理解,我們就不舉例說明了。

crop

Image.crop(box)

參數說明:

  • box:相對圖像左上角座標爲(0,0)的矩形座標元組, 順序爲(左, 上, 右, 下)

該方法從圖像中獲取 box 矩形區域的圖像,相當於從圖像中摳一個矩形區域出來。我們來看例子:

from PIL import Image

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

# 定義了圖像的座標位置,從左、上、右、下
box = (100, 100, 250, 250)

# 它會從左上角開始,同時向下和向右移動100像素的位置開始截取250-100的像素寬高,也就是150x150的圖像
# 這裏注意後兩個數值要大於前兩個數值,不然截取後的圖像寬高爲負數,會報錯
region = im.crop(box)
print(region.size)
region.show()

# 輸出結果
(451, 300)
(150, 150)

我們從 cat.jpg 這張圖片中截取了 150x150 的圖像,從打印結果可以看到截取前和截取後的圖像大小。兩張圖像的對比如下圖:

filter

Image.filter(filter)

參數說明:

  • filter:過濾內核

使用給定的篩選器篩選此圖像。有關可用篩選器的列表:

篩選器名稱 說明
BLUR 模糊濾波,處理之後的圖像會整體變得模糊。
CONTOUR 輪廓濾波,將圖像中的輪廓信息全部提取出來。
DETAIL 細節增強濾波,會使得圖像中細節更加明顯。
EDGE_ENHANCE 邊緣增強濾波,突出、加強和改善圖像中不同灰度區域之間的邊界和輪廓的圖像增強方法。
EDGE_ENHANCE_MORE 深度邊緣增強濾波,會使得圖像中邊緣部分更加明顯。
EMBOSS 浮雕濾波,會使圖像呈現出浮雕效果。
FIND_EDGES 尋找邊緣信息的濾波,會找出圖像中的邊緣信息。
SHARPEN 銳化濾波,補償圖像的輪廓,增強圖像的邊緣及灰度跳變的部分,使圖像變得清晰。
SMOOTH 平滑濾波,突出圖像的寬大區域、低頻成分、主幹部分或抑制圖像噪聲和干擾高頻成分,使圖像亮度平緩漸變,減小突變梯度,改善圖像質量。
SMOOTH_MORE 深度平滑濾波,會使得圖像變得更加平滑。

看到這些,大家是不是聯想到我們手機上一些 APP 的圖像處理功能了,其實那些功能的實現方式跟我們這裏講的方法是一樣的。我們來看個例子:

from PIL import Image
from PIL import ImageFilter

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

# 模糊
im2 = im.filter(ImageFilter.BLUR)
im2.show()

# 輪廓濾波
im3 = im.filter(ImageFilter.CONTOUR)
im3.show()

# 細節增強
im4 = im.filter(ImageFilter.DETAIL)
im4.show()

我們分別對原圖了使用了模糊濾波、輪廓濾波、細節增強濾波的處理,大家運行程序就可以看到處理後的效果了,如下圖所示:

getbands

Image.getbands()

返回一個包含此圖像中每個通道名稱的元組。直接看實例:

from PIL import Image

# 打開圖像
im = Image.open('cat.jpg')
# 創建新圖像
im1 = Image.new('L', (450, 450), 50)

# 獲取圖像的通道名稱元組
print(im.getbands())
print(im1.getbands())

# 輸出結果
('R', 'G', 'B')
('L',)

上例中,我們分別打開一個 RGB 圖像和創建一個 L 模式的新圖像,然後打印輸出他們的通道名稱。

getbbox

Image.getbbox()

計算圖像中非零區域的邊界框。將邊界框作爲定義左、上、右和下像素座標的四元組返回。我們來看例子:

from PIL import Image

# 打開圖像(451x300)
im = Image.open('cat.jpg')
# 創建新圖像(450x450)
im1 = Image.new('L', (450, 450), 50)

# 打印圖像中非零區域的邊界框
print(im.getbbox())
print(im1.getbbox())

# 輸出結果
(0, 0, 451, 300)
(0, 0, 450, 450)

這個方法很簡單,很容易理解,那麼這個方法有什麼用處呢?最直接的一個用處就是迅速地獲取圖像的邊界座標。

getcolors

Image.getcolors(maxcolors=256)

參數說明:

  • maxcolors:最大顏色數。默認限制爲256色。

獲取圖像中顏色的使用列表,超過 maxcolors 設置值返回 None 。
返回值爲 (count, pixel) 的列表,表示(出現的次數,像素的值)

from PIL import Image

im = Image.open('cat.png')

# 將彩色圖像轉換成灰度圖
im2 = im.convert("L")

# 打印灰度圖的顏色列表,返回的點數超過maxcolors就直接返回None
print(im2.getcolors(maxcolors=200))
print(im2.getcolors(maxcolors=255))

# 輸出結果
None
[(1, 0), (69, 1), (275, 2), (518, 3), (165, 4), ... (6, 250), (1, 251)]

我們這個圖像有252個像素值,所以第一次 maxcolors 設置爲200時,由於 252>200,所以返回了 None。第二次設置255時,正常返回。

getdata

Image.getdata(band=None)

參數:

  • band:獲取對應通道值。如:RGB 圖像像素值爲 (r,g,b) 的元組,要返回單個波段,請傳遞索引值(例如0,從 RGB 圖像中獲取 R 波段)。

獲取圖像中每個像素的通道對象元組,像素獲取從左至右,從上至下。

getextrema

Image.getextrema()

獲取圖像中每個通道的最小值與最大值。對於單波段圖像,包含最小和最大像素值的2元組。對於多波段圖像,每個波段包含一個2元組的元組。

getpixel

Image.getpixel(xy)

參數:

  • xy:座標,以(x,y)表示。

通過傳入座標返回像素值。如果圖像是多層圖像,則此方法返回元組。

point

Image.point(lut, mode=None)

參數說明:

  • lut:一個查找表,包含圖像中每個波段的256個(或65536個,如果 self.mode“I” 和 mode“L”)值。可以改用函數,它應採用單個參數。對每個可能的像素值調用一次函數,結果表將應用於圖像的所有帶區。

  • mode:輸出模式(默認與輸入相同)。只有當源圖像具有模式 “L” 或 “P” ,並且輸出具有模式 “1” 或源圖像模式爲 “I” ,並且輸出模式爲 “L” 時,才能使用此選項。

對圖像的的每個像素點進行操作,返回圖像的副本。

from PIL import Image

im = Image.open('cat.png')

# 調整灰色圖像的對比度
im_point=im.convert('L').point(lambda i: i < 80 and 255)
im_point.show()

source = im.split()
# 三通道分別處理對比度
band_r = source[0].point(lambda i: i < 80 and 255)
band_g = source[1].point(lambda i: i < 80 and 255)
band_b = source[2].point(lambda i: i < 80 and 255)
band_r.show()
band_g.show()
band_b.show()

在例子中,我們先將圖像轉換成 L 模式,然後調整對比度,以及將圖像的三個通道分別調整對比度。所謂調整對比度,我們這個例子的規則就是當像素值小於80時,將其調整爲255,相當於將接近黑色的像素點加黑,使其與淺色對比更明顯。運行效果如下圖:

resize

Image.resize(size, resample=0, box=None)

參數說明:

  • size:以像素爲單位的請求大小,作爲2元組:(寬度、高度)。
  • resample:可選的重新採樣濾波器。可以是 PIL.Image.NEAREST(最近濾波) , PIL.Image.ANTIALIAS (平滑濾波), PIL.Image.BILINEAR (雙線性濾波), PIL.Image.HAMMING , PIL.Image.BICUBIC (雙立方濾波)。如果省略,或者圖像具有模式 “1” 或 “P” ,則設置爲 PIL.Image.NEAREST 。
    -box:一個可選的4元組的浮點數,給出了應該縮放的源圖像區域。值應在(0,0,寬度,高度)矩形內。如果省略或沒有,則使用整個源。

這個方法是獲取調整大小後的圖片。通俗地講就是在原圖中摳一個矩形區域(如果傳入了 box 參數),然後對摳出來的區域進行濾波處理(如果傳入了 resample 參數),最後以指定的 size 大小進行返回。

from PIL import Image

im = Image.open('flower.jpg')

img1 = im.resize((250, 250), Image.BILINEAR)
img2 = im.resize((250, 250), Image.BICUBIC)
img3 = im.resize((250, 250), Image.NEAREST)

im.show()
img1.show()
img2.show()
img3.show()

這幾個濾波器的具體的原理比較理論,大家對照着程序運行返回自行去深入瞭解。

關於 PIL 的 Image 模塊的方法我們只講這麼多,還有好多其他方法,大家可參照 https://www.osgeo.cn/pillow/reference/ 這個網站去嘗試。

我們講的 PIL 的 Image 模塊只是 PIL 的一個基礎模塊而已,它還有好多其他的模塊,諸如 ImageChops (通道操作模塊)、ImageColor (顏色轉換模塊)、ImageDraw (二維圖形模塊)等,大家在需要的時候可以去查找 API 使用。

總結

pillow 庫是一個非常強大的基礎圖像處理庫,若不深入圖像處理,運用這個庫裏面的方法組合,對圖像進行各種常見的操作已經夠用,這是計算機圖片識別的基礎。當然,如果需要更專業的操作,那麼就直接上 opencv 吧。

參考

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

文中示例代碼:python-100-days

關注公衆號:python技術,回覆"python"一起學習交流

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章