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
使用不同的參數,將當前的圖像轉換為新的模式,并產生新的圖像作為返回值。
通過博客“Python圖像處理庫PIL的基本概念介紹”。我們知道PIL中有九種不同模式。分別為1。L,P。RGB,RGBA,CMYK,YCbCr,I,F。
本文我採用的演示樣例圖像是圖像處理中經典的lena照片。
分辨率為512x512的lena圖片例如以下:
一、模式“RGB”轉換為其它不同模式
1、模式“1”
模式“1”為二值圖像。非黑即白。可是它每一個像素用8個bit表示,0表示黑,255表示白。以下我們將lena圖像轉換為“1”圖像。
樣例:
>>>from PIL import Image
>>> lena =Image.open("D:\Code\Python\test\img\lena.jpg")
>>> lena.mode
'RGB'
>>> lena.getpixel((0,0))
(197, 111, 78)
>>> lena_1 = lena.convert("1")
>>> lena_1.mode
'1'
>>> lena_1.size
(512, 512)
>>>lena_1.getpixel((0,0))
255
>>> lena_1.getpixel((10,10))
255
>>>lena_1.getpixel((10,120))
0
>>>lena_1.getpixel((130,120))
255
圖像lena_1的模式為“1”。分辨率為512x512,例如以下:
2、模式“L”
模式“L”為灰色圖像。它的每一個像素用8個bit表示。0表示黑,255表示白,其它數字表示不同的灰度。
在PIL中,從模式“RGB”轉換為“L”模式是依照以下的公式轉換的:
L = R * 299/1000 + G * 587/1000+ B * 114/1000
以下我們將lena圖像轉換為“L”圖像。
樣例:
>>> from PIL importImage
>>> lena = Image.open("D:\Code\Python\test\img\lena.jpg")
>>> lena.mode
'RGB'
>>> lena.getpixel((0,0))
(197, 111, 78)
>>> lena_L =lena.convert("L")
>>> lena_L.mode
'L'
>>> lena_L.size
(512, 512)
>>>lena.getpixel((0,0))
(197, 111, 78)
>>>lena_L.getpixel((0,0))
132
對于第一個像素點,原始圖像lena為(197,
111, 78),其轉換為灰色值為:
197 *299/1000 + 111 * 587/1000 + 78 * 114/1000
= 132.952。PIL中僅僅取了整數部分。即為132。
轉換后的圖像lena_L例如以下:
3、模式“P”
模式“P”為8位彩色圖像。它的每一個像素用8個bit表示,其相應的彩色值是依照調色板查詢出來的。
以下我們使用默認的調色板將lena圖像轉換為“P”圖像。
樣例:
>>> from PIL importImage
>>> lena = Image.open("D:\Code\Python\test\img\lena.jpg")
>>> lena.mode
'RGB'
>>> lena.getpixel((0,0))
(197, 111, 78)
>>> lena_P =lena.convert("P")
>>> lena_P.mode
'P'
>>>lena_P.getpixel((0,0))
62
轉換后的圖像lena_P例如以下:
4、模式“RGBA”
模式“RGBA”為32位彩色圖像。它的每一個像素用32個bit表示,當中24bit表示紅色、綠色和藍色三個通道。另外8bit表示alpha通道,即透明通道。
以下我們將模式為“RGB”的lena圖像轉換為“RGBA”圖像。
樣例:
>>> from PIL import Image
>>>lena = Image.open("D:\Code\Python\test\img\lena.jpg")
>>>lena.mode
'RGB'
>>>lena.getpixel((0,0))
(197,111, 78)
>>>lena_rgba = lena.convert("RGBA")
>>>lena_rgba.mode
'RGBA'
>>>lena_rgba.getpixel((0,0))
(197,111, 78, 255)
>>>lena_rgba.getpixel((0,1))
(196,110, 77, 255)
>>>lena.getpixel((0,0))
(197,111, 78)
>>>lena.getpixel((0,1))
(196,110, 77)
從實例中能夠看到,使用當前這個方式將“RGB”圖像轉為“RGBA”圖像時,alpha通道所有設置為255,即全然不透明。
轉換后的圖像lena_rgba例如以下:
<img src="http://img.blog.csdn.net/20160310081249935?
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
5、模式“CMYK”
模式“CMYK”為32位彩色圖像,它的每一個像素用32個bit表示。模式“CMYK”就是印刷四分色模式,它是彩色印刷時採用的一種套色模式。利用色料的三原色混色原理,加上黑色油墨,共計四種顏色混合疊加,形成所謂“全彩印刷”。
四種標準顏色是:C:Cyan =
青色,又稱為‘天藍色’或是‘湛藍’M:Magenta =
品紅色,又稱為‘洋紅色’。Y:Yellow =
黃色;K:Key Plate(blacK) =
定位套版色(黑色)。
以下我們將模式為“RGB”的lena圖像轉換為“CMYK”圖像。
樣例:
>>>from PIL import Image
>>> lena =Image.open("D:\Code\Python\test\img\lena.jpg")
>>> lena_cmyk =lena.convert("CMYK")
>>> lena_cmyk.mode
'CMYK'
>>>lena_cmyk.getpixel((0,0))
(58, 144, 177, 0)
>>> lena_cmyk.getpixel((0,1))
(59, 145, 178, 0)
>>>lena.getpixel((0,0))
(197, 111, 78)
>>>lena.getpixel((0,1))
(196, 110, 77)
從實例中能夠得知PIL中“RGB”轉換為“CMYK”的公式例如以下:
C = 255 - R
M = 255 - G
Y = 255 - B
K = 0
因為該轉換公式比較簡單,轉換后的圖像顏色有些失真。
轉換后的圖像lena_cmyk例如以下:
6、模式“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”圖像。
樣例:
>>>from PIL import Image
>>> lena =Image.open("D:\Code\Python\test\img\lena.jpg")
>>> lena_ycbcr =lena.convert("YCbCr")
>>>lena_ycbcr.mode
'YCbCr'
>>>lena_ycbcr.getpixel((0,0))
(132, 97, 173)
>>>lena.getpixel((0,0))
(197, 111, 78)
依照公式,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例如以下:
<img src="http://img.blog.csdn.net/20160310081415264?
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
7、模式“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”圖像。
樣例:
>>> from PIL import Image
>>>lena = Image.open("D:\Code\Python\test\img\lena.jpg")
>>>lena.getpixel((0,0))
(197,111, 78)
>>>lena.getpixel((0,1))
(196,110, 77)
>>> lena_I =lena.convert("I")
>>> lena_I.mode
'I'
>>>lena_I.getpixel((0,0))
132
>>>lena_I.getpixel((0,1))
131
>>> lena_L =lena.convert("L")
>>>lena_L.getpixel((0,0))
132
>>>lena_L.getpixel((0,1))
131
從實驗的結果看。模式“I”與模式“L”的結果是全然一樣。僅僅是模式“L”的像素是8bit,而模式“I”的像素是32bit。
8、模式“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”圖像。
樣例:
>>>from PIL import Image
>>> lena =Image.open("D:\Code\Python\test\img\lena.jpg")
>>>lena.getpixel((0,0))
(197, 111, 78)
>>>lena.getpixel((0,1))
(196, 110, 77)
>>> lena_F =lena.convert("F")
>>> lena_F.mode
'F'
>>>lena_F.getpixel((0,0))
132.95199584960938
>>>lena_F.getpixel((0,1))
131.95199584960938
模式“F”與模式“L”的轉換公式是一樣的,都是RGB轉換為灰色值的公式,但模式“F”會保留小數部分,如實驗中的數據。
(未完待續)
總結
以上是生活随笔為你收集整理的Python图像处理库PIL中图像格式转换(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PowerShell攻防进阶篇:nish
- 下一篇: 使用Eclipse连接SAP云平台上的H