天天看點

python的Image圖像處理對P I i 模式的了解

在數字圖像進行中,針對不同的圖像格式有其特定的處理算法。是以,在做圖像處理之前,我們需要考慮清楚自己要基于哪種格式的圖像進行算法設計及其實作。本文基于這個需求,使用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圖檔如下:

python的Image圖像處理對P I i 模式的了解

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

1、模式“1”

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

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

>>>from PIL

import

Image

>>> lena =Image.open(

"D:\\Code\\Python\\test\\img\\lena.jpg"

)

>>> lena.mode

'RGB'

>>> lena.getpixel((

,

))

(

197

,

111

,

78

)

>>> lena_1 = lena.convert(

"1"

)

>>> lena_1.mode

'1'

>>> lena_1.size

(

512

,

512

)

>>>lena_1.getpixel((

,

))

255

>>> lena_1.getpixel((

10

,

10

))

255

>>>lena_1.getpixel((

10

,

120

))

>>>lena_1.getpixel((

130

,

120

))

255

圖像lena_1的模式為“1”,分辨率為512x512,如下:

python的Image圖像處理對P I i 模式的了解

2、模式“L”

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

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

下面我們将lena圖像轉換為“L”圖像。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

>>> from PIL importImage

>>> lena = Image.open(

"D:\\Code\\Python\\test\\img\\lena.jpg"

)

>>> lena.mode

'RGB'

>>> lena.getpixel((

,

))

(

197

,

111

,

78

)

>>> lena_L =lena.convert(

"L"

)

>>> lena_L.mode

'L'

>>> lena_L.size

(

512

,

512

)

>>>lena.getpixel((

,

))

(

197

,

111

,

78

)

>>>lena_L.getpixel((

,

))

132

對于第一個像素點,原始圖像lena為(197, 111, 78),其轉換為灰色值為:

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

轉換後的圖像lena_L如下:

python的Image圖像處理對P I i 模式的了解

3、模式“P”

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

下面我們使用預設的調色闆将lena圖像轉換為“P”圖像。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

>>> from PIL importImage

>>> lena = Image.open(

"D:\\Code\\Python\\test\\img\\lena.jpg"

)

>>> lena.mode

'RGB'

>>> lena.getpixel((

,

))

(

197

,

111

,

78

)

>>> lena_P =lena.convert(

"P"

)

>>> lena_P.mode

'P'

>>>lena_P.getpixel((

,

))

62

轉換後的圖像lena_P如下:

python的Image圖像處理對P I i 模式的了解

4、模式“RGBA”

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

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

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

>>> from PIL

import

Image

>>>lena = Image.open(

"D:\\Code\\Python\\test\\img\\lena.jpg"

)

>>>lena.mode

'RGB'

>>>lena.getpixel((

,

))

(

197

,

111

,

78

)

>>>lena_rgba = lena.convert(

"RGBA"

)

>>>lena_rgba.mode

'RGBA'

>>>lena_rgba.getpixel((

,

))

(

197

,

111

,

78

,

255

)

>>>lena_rgba.getpixel((

,

1

))

(

196

,

110

,

77

,

255

)

>>>lena.getpixel((

,

))

(

197

,

111

,

78

)

>>>lena.getpixel((

,

1

))

(

196

,

110

,

77

)

從執行個體中可以看到,使用目前這個方式将“RGB”圖像轉為“RGBA”圖像時,alpha通道全部設定為255,即完全不透明。

轉換後的圖像lena_rgba如下:

python的Image圖像處理對P I i 模式的了解

5、模式“CMYK”

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

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

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

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

>>>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((

,

))

(

58

,

144

,

177

,

)

>>> lena_cmyk.getpixel((

,

1

))

(

59

,

145

,

178

,

)

>>>lena.getpixel((

,

))

(

197

,

111

,

78

)

>>>lena.getpixel((

,

1

))

(

196

,

110

,

77

)

從執行個體中可以得知PIL中“RGB”轉換為“CMYK”的公式如下:

C = 255 - R

M = 255 - G

Y = 255 - B

K = 0

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

轉換後的圖像lena_cmyk如下:

python的Image圖像處理對P I i 模式的了解

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”圖像。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

>>>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((

,

))

(

132

,

97

,

173

)

>>>lena.getpixel((

,

))

(

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如下:

python的Image圖像處理對P I i 模式的了解

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”圖像。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

>>> from PIL

import

Image

>>>lena = Image.open(

"D:\\Code\\Python\\test\\img\\lena.jpg"

)

>>>lena.getpixel((

,

))

(

197

,

111

,

78

)

>>>lena.getpixel((

,

1

))

(

196

,

110

,

77

)

>>> lena_I =lena.convert(

"I"

)

>>> lena_I.mode

'I'

>>>lena_I.getpixel((

,

))

132

>>>lena_I.getpixel((

,

1

))

131

>>> lena_L =lena.convert(

"L"

)

>>>lena_L.getpixel((

,

))

132

>>>lena_L.getpixel((

,

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”圖像。

例子:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

>>>from PIL

import

Image

>>> lena =Image.open(

"D:\\Code\\Python\\test\\img\\lena.jpg"

)

>>>lena.getpixel((

,

))

(

197

,

111

,

78

)

>>>lena.getpixel((

,

1

))

(

196

,

110

,

77

)

>>> lena_F =lena.convert(

"F"

)

>>> lena_F.mode

'F'

>>>lena_F.getpixel((

,

))

132.95199584960938

>>>lena_F.getpixel((

,

1

))

131.95199584960938

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

轉載自:https://www.2cto.com/kf/201603/492898.html