上節我們講了 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 Imageim = Image.open('cat.png')im.show()# 將圖像轉換成黑白色并返回新圖像im1 = im.convert('L')im1.show()
我們將一個圖像轉換成 L模式(灰色),轉換結果如下圖所示:
Image.copy()
復制圖像方法,該方法完全復制一個一模一樣的圖像,很好理解,我們就不舉例說明了。
crop
Image.crop(box)
參數說明:
- box:相對圖像左上角坐標為(0,0)的矩形坐標元組, 順序為(左, 上, 右, 下)
該方法從圖像中獲取 box 矩形區域的圖像,相當于從圖像中摳一個矩形區域出來。我們來看例子:
from PIL import Imageim = 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 Imagefrom PIL import ImageFilterim = 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 Imageim = Image.open('cat.png')# 將彩色圖像轉換成灰度圖im2 = im.convert("L")# 打印灰度圖的顏色列表,返回的點數超過maxcolors就直接返回Noneprint(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 Imageim = 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 Imageim = 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/
文中示例代碼:https://github.com/JustDoPython/python-100-day/tree/master/day-097
系列文章
第96天:圖像庫 PIL(一)第95天:StringIO & BytesIO第94天:數據分析之 pandas 初步第93天:文件讀寫第92天:Python Matplotlib 進階操作第91天:Python matplotlib introduction從 0 學習 Python 0 - 90 大合集總結PS:公號內回復 :Python,即可進入Python 新手學習交流群,一起100天計劃!-END-Python 技術關于 Python 都在這里