03.17 Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

Python學習交流群:666468218,群內每天分享乾貨,包括最新的python企業案例學習資料和零基礎入門教程,歡迎各位小夥伴入群學習交流

在數字圖像處理中,針對不同的圖像格式有其特定的處理算法。所以,在做圖像處理之前,我們需要考慮清楚自己要基於哪種格式的圖像進行算法設計及其實現。本文基於這個需求,使用python中的圖像處理庫PIL來實現不同圖像格式的轉換。

對於彩色圖像,不管其圖像格式是PNG,還是BMP,或者JPG,在PIL中,使用Image模塊的open()函數打開後,返回的圖像對象的模式都是“RGB”。而對於灰度圖像,不管其圖像格式是PNG,還是BMP,或者JPG,打開後,其模式為“L”。

通過之前對Image模塊的介紹,對於PNG、BMP和JPG彩色圖像格式之間的互相轉換都可以通過Image模塊的open()和save()函數來完成。具體說就是,在打開這些圖像時,PIL會將它們解碼為三通道的“RGB”圖像。用戶可以基於這個“RGB”圖像,對其進行處理。處理完畢,使用函數save(),可以將處理結果保存成PNG、BMP和JPG中任何格式。這樣也就完成了幾種格式之間的轉換。同理,其他格式的彩色圖像也可以通過這種方式完成轉換。當然,對於不同格式的灰度圖像,也可通過類似途徑完成,只是PIL解碼後是模式為“L”的圖像。

這裡,我想詳細介紹一下Image模塊的convert()函數,用於不同模式圖像之間的轉換。

Convert()函數有三種形式的定義,它們定義形式如下:

  • im.convert(mode) ⇒ image

  • im.convert(“P”, **options) ⇒ image

  • im.convert(mode, matrix) ⇒ image

使用不同的參數,將當前的圖像轉換為新的模式,併產生新的圖像作為返回值。

通過 我們知道PIL中有九種不同模式。分別為1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。

模式“RGB”轉換為其他不同模式

模式“1”

模式“1”為二值圖像,非黑即白。但是它每個像素用8個bit表示,0表示黑,255表示白。下面我們將lena圖像轉換為“1”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“L”

模式“L”為灰色圖像,它的每個像素用8個bit表示,0表示黑,255表示白,其他數字表示不同的灰度。在PIL中,從模式“RGB”轉換為“L”模式是按照下面的公式轉換的:

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

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

對於第一個像素點,原始圖像lena為(69, 106, 125 ),其轉換為灰色值為:

197 *299/1000 + 111 * 587/1000 + 125 * 114/1000 = 97.103,PIL中只取了整數部分,即為97。

模式“P”

模式“P”為8位彩色圖像,它的每個像素用8個bit表示,其對應的彩色值是按照調色板查詢出來的。

下面我們使用默認的調色板將圖像轉換為“P”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“RGBA”

模式“RGBA”為32位彩色圖像,它的每個像素用32個bit表示,其中24bit表示紅色、綠色和藍色三個通道,另外8bit表示alpha通道,即透明通道。

下面我們將模式為“RGB”的lena圖像轉換為“RGBA”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

從實例中可以看到,使用當前這個方式將“RGB”圖像轉為“RGBA”圖像時,alpha通道全部設置為255,即完全不透明。

模式“CMYK”

模式“CMYK”為32位彩色圖像,它的每個像素用32個bit表示。模式“CMYK”就是印刷四分色模式,它是彩色印刷時採用的一種套色模式,利用色料的三原色混色原理,加上黑色油墨,共計四種顏色混合疊加,形成所謂“全綵印刷”。

四種標準顏色是:C:Cyan =青色,又稱為‘天藍色’或是‘湛藍’M:Magenta =品紅色,又稱為‘洋紅色’;Y:Yellow =黃色;K:Key Plate(blacK) =定位套版色(黑色)。

下面我們將模式為“RGB”的lena圖像轉換為“CMYK”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

從實例中可以得知PIL中“RGB”轉換為“CMYK”的公式如下:

C = 255 - R

M = 255 - G

Y = 255 - B

K = 0

由於該轉換公式比較簡單,轉換後的圖像顏色有些失真。

模式“YCbCr”

模式“YCbCr”為24位彩色圖像,它的每個像素用24個bit表示。YCbCr其中Y是指亮度分量,Cb指藍色色度分量,而Cr指紅色色度分量。人的肉眼對視頻的Y分量更敏感,因此在通過對色度分量進行子採樣來減少色度分量後,肉眼將察覺不到的圖像質量的變化。

模式“RGB”轉換為“YCbCr”的公式如下:

Y= 0.257*R+0.504*G+0.098*B+16

Cb = -0.148*R-0.291*G+0.439*B+128

Cr = 0.439*R-0.368*G-0.071*B+128

下面我們將模式為“RGB”的lena圖像轉換為“YCbCr”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

按照公式

Y =0.257*69+0.564*106+0.098*125+16= 105.767

Cb=-0.148*69-0.291*106+0.439*125+128=162.240

Cr = 0.439*69-0.368*106-0.071*125+128 = 110.408

由此可見,PIL中並非按照這個公式進行“RGB”到“YCbCr”的轉換。

模式“I”

模式“I”為32位整型灰色圖像,它的每個像素用32個bit表示,0表示黑,255表示白,(0,255)之間的數字表示不同的灰度。在PIL中,從模式“RGB”轉換為“I”模式是按照下面的公式轉換的:

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

下面我們將模式為“RGB”的圖像轉換為“I”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

從實驗的結果看,模式“I”與模式“L”的結果是完全一樣,只是模式“L”的像素是8bit,而模式“I”的像素是32bit。

模式“F”

模式“F”為32位浮點灰色圖像,它的每個像素用32個bit表示,0表示黑,255表示白,(0,255)之間的數字表示不同的灰度。在PIL中,從模式“RGB”轉換為“F”模式是按照下面的公式轉換的:

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

下面我們將模式為“RGB”的lena圖像轉換為“F”圖像。

代碼

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“F”與模式“L”的轉換公式是一樣的,都是RGB轉換為灰色值的公式,但模式“F”會保留小數部分,如實驗中的數據


其他不同模式轉換為“RGB”模式

Python學習交流群:666468218,群內每天分享乾貨,包括最新的python企業案例學習資料和零基礎入門教程,歡迎各位小夥伴入群學習交流

模式“RGB”為24位彩色圖像,它的每個像素用24個bit表示,分別表示紅色、綠色和藍色三個通道。

在PIL中,對於彩色圖像,open後都會轉換為“RGB”模式,然後該模式可以轉換為其他模式,比如“1”、“L”、“P”和“RGBA”,這幾種模式也可以轉換為“RGB”模式。

模式“1”轉換為模式“RGB”

模式“RGB”轉換為模式“1”以後,像素點變成黑白兩種點,要麼是0,要麼是255。而從模式“1”轉換成“RGB”時,“RGB”的三個通道都是模式“1”的像素值的拷貝。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“L”轉換為模式“RGB”

模式“RGB”轉換為模式“L”以後,像素值為[0,255]之間的某個數值。而從模式“L”轉換成“RGB”時,“RGB”的三個通道都是模式“L”的像素值的拷貝。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

嘿嘿 日常翻車~

模式“P”轉換為模式“RGB”

模式“RGB”轉換為模式“P”以後,像素值為[0,255]之間的某個數值,但它為調色板的索引值,其最終還是彩色圖像。從模式“P”轉換成“RGB”時,“RGB”的三個通道會變成模式“P”的像素值索引的彩色值。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“RGBA”轉換為模式“RGB”

模式“RGB”轉換為模式“RGBA”以後,圖像從三通道變成了四通道,其R、G、B三個通道的數值沒有變化,新增的alpha通道均為255,表示不透明。從模式“RGBA”轉換成“RGB”時,“RGB”的三個通道又變回原來的數值。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“CMYK”轉換為模式“RGB”

模式“RGB”轉換為模式“CMYK”以後,圖像從三通道變成了四通道,其C、M、Y三個通道的數值是通過之前的公式計算得到,K通道被直接賦值為0。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

從模式“CMYK”轉換成“RGB”時,“RGB”的三個通道又變回原來的數值,這是無損的轉換。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“YCbCr”轉換為模式“RGB”

模式“RGB”轉換為模式“YCbCr”,通常都是使用下面的公式計算,但PIL中並沒有嚴格按照這個公式進行轉換。

Y= 0.257*R+0.564*G+0.098*B+16

Cb =-0.148*R-0.291*G+0.439*B+128

Cr = 0.439*R-0.368*G-0.071*B+128

從模式“YCbCr”轉換成“RGB”時,通常是按照下面的公式計算,但PIL中並沒有嚴格按照這個公式進行轉換。

R= 1.164*(Y-16)+1.596*(Cr-128)

G = 1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128)

B = 1.164*(Y-16)+2.017*(Cb-128)

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“I”轉換為模式“RGB”

模式“RGB”轉換為模式“I”,將三通道變成了單通道,使用下面的公式計算獲得像素值:

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

從模式“I”轉換成“RGB”時,“RGB”的三個通道都是模式“I”的像素值的拷貝。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

模式“F”轉換為模式“RGB”

模式“RGB”轉換為模式“F”,將彩色圖像變成了32位浮點灰色圖像。在PIL中,從模式“RGB”轉換為“F”模式是按照下面的公式轉換的:

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

從模式“F”轉換成“RGB”時,“RGB”的三個通道都是模式“F”的像素值整數部分的拷貝。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~


調色板圖像的轉換

在PIL中,將“RGB”圖像轉換為“P”模式圖像時,有對應的convert()函數定義,如下:

im.convert(“P”,**options) ⇒ image

這個定義將模式固定為“P”,後面可以帶幾個可選參數。它們分別為:dither,palette和colors

  • 參數dither:用於控制顏色抖動。默認是FLOYDSTEINBERG,不使能該功能,則賦值為NONE。

  • 參數palette:用於控制調色板的產生。默認是WEB,這是標準的216色的“web palette”。要使用優化的調色板,則賦值為ADAPTIVE。

  • 參數colors:用於控制調色板顏色數目。當參數palette為ADAPTIVE時,colors數值表示調色板的顏色數目。默認是最大值,即256種顏色。

使用默認值,將“RGB”轉換為“P”模式圖像後如下:

  • 參數dither默認為FLOYDSTEINBERG;如果不開啟顏色抖動功能,則賦值為NONE。

  • 參數palette默認是WEB。要使用優化的調色板,則賦值為ADAPTIVE。

  • 當參數palette為ADAPTIVE時,colors數值表示調色板的顏色數目。默認值為256。

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~


帶矩陣的模式轉換

模式轉換函數convert()的第三種定義如下:

im.convert(mode,matrix) ⇒ image

這種定義只適合將一個“RGB”圖像轉換為“L”或者“RGB”圖像,不能轉換為其他模式的圖像。變量matrix為4或者16元組。

例子:下面的例子將一個RGB圖像(根據ITU-R709線性校準,使用D65亮度)轉換到CIE XYZ顏色空間:

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~

PIL中對圖像格式及模式的轉換,相對都是非常簡潔。用戶可以根據自己的需求,將圖像轉換為目標模式,進而進行各種處理。對於不同的圖像處理目的,需要選擇在哪種模式上設計圖像算法,設計什麼樣的算法,這個是一個極為關鍵的問題。希望之後的學習中,能夠有比較深刻的認識。

感謝各位大大看完,如果說想要代碼以及筆記的請私信或者在下方評論“源碼”即可獲取

Python 的圖像處理PIL庫這麼強大?也許這是最詳細的文章了~


分享到:


相關文章: