1. 程式人生 > 程式設計 >Python影象處理庫PIL中影象格式轉換的實現

Python影象處理庫PIL中影象格式轉換的實現

  在數字影象處理中,針對不同的影象格式有其特定的處理演算法。所以,在做影象處理之前,我們需要考慮清楚自己要基於哪種格式的影象進行演算法設計及其實現。本文基於這個需求,使用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

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

本文我們取樣的圖片是lena的照片:

模式“1”:

>>> from PIL import Image
>>> lena = Image.open("lena.bmp")
>>> lena.mode
'RGB'
>>> lena.getpixel((0,0))
(226,137,125)
>>> lena_1 = lena.convert("1")
>>> lena_1.mode
'1'
>>> lena_1.size
(512,512)
>>> lena_1.getpixel((0,0))
>>> lena_1.getpixel((10,10))
>>> lena_1.getpixel((10,120))
>>> lena_1.getpixel((130,120))
>>> lena_1.show()

結果:

Python影象處理庫PIL中影象格式轉換的實現

模式“L”:

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

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

下面我們將lena影象轉換為“L”影象。

>>> lena_L = lena.convert("L")
>>> lena_L.mode
'L'
>>> lena_L.size
(512,512)
>>> lena_L.getpixel((0,0))
>>> lena.getpixel((0,125)
>>> lena_L.show()
>>> lena_L.save("lena_l.bmp")
>>>

對於第一個畫素點,原始影象lena為(197,111,78),其轉換為灰色值為:

197 *299/1000 + 111 * 587/1000 + 78 * 114/1000= 132.952,PIL中只取了整數部分,即為132。

轉換後的影象lena_L如下:

Python影象處理庫PIL中影象格式轉換的實現

模式P:

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

下面我們使用預設的調色盤將lena影象轉換為“P”影象。

example:

>>> lena_P = lena.convert("P")
>>> lena_P.mode
'P'
>>> lena_P.getpixel((0,0))

結果:

Python影象處理庫PIL中影象格式轉換的實現

模式“RGBA”:

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

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

>>> lena_rgba = lena.convert("RGBA")
>>> 
>>> 
>>> 
>>> lena_rgba.mode
'RGBA'
>>> lena_rgba.getpixel((0,125,255)
>>> lena_rgba.getpixel((0,1))
(226,255)
>>> lena_rgba.show()

Python影象處理庫PIL中影象格式轉換的實現

模式“CMYK”:

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

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

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

>>> lena_cmyk = lena.convert("CMYK")
>>> lena_cmyk.mode
'CMYK'
>>> lena_cmyk.getpixel((0,0))
(29,118,130,0)
>>> lena_cmyk.getpixel((0,1))
(29,0)
>>> lena_cmyk.show()

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

C = 255 - R
M = 255 - G
Y = 255 - B
K = 0

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

轉換後的影象lena_cmyk如下:

Python影象處理庫PIL中影象格式轉換的實現

模式“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”影象。

>>> lena_ycbcr = lena.convert("YCbCr")
>>> lena_ycbcr.mode
'YCbCr'
>>> lena_ycbcr.getpixel((0,0))
(162,107,173)
>>> lena.getpixel((0,125)
>>>

按照公式,Y =0.257*197+0.564*111+0.098*78+16= 136.877

Cb=-0.148*197-0.291*111+0.439*78+128= 100.785
Cr = 0.439*197-0.368*111-0.071*78+128 = 168.097

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

轉換後的影象lena_ycbcr如下:

Python影象處理庫PIL中影象格式轉換的實現

模式“I”

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

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

下面我們將模式為“RGB”的lena影象轉換為“I”影象。

>>> lena_I = lena.convert("I")
>>> lena_I.mode
'I'
>>> lena_I.getpixel((0,0))
>>> lena_I.getpixel((0,1))
>>> lena_L = lena.convert("L")
>>> lena_L.getpixel((0,0))
>>> lena_L.getpixel((0,1))

從實驗的結果看,模式“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”影象。

>>> lena_F = lena.convert("F")
>>> lena_F.mode
'F'
>>> lena_F.getpixel((0,0))
162.2429962158203
>>> lena_F.getpixel((0,1))
162.2429962158203
>>>

Python影象處理庫PIL中影象格式轉換的實現

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

以上就是Python影象處理庫PIL中影象格式轉換的實現的詳細內容,更多關於PIL 影象格式轉換的資料請關注我們其它相關文章!