知识图谱系列---机器学习---PIL图片处理

Python图像处理库PIL的基本概念介绍

Python图像处理库PIL中图像格式转换(一)

Python图像处理库PIL中图像格式转换(二)

Python图像处理库PIL的ImageColor模块介绍

Python图像处理库PIL的ImageFilter模块介绍

Python图像处理库PIL的ImageChops模块介绍

Python图像处理库PIL的ImageDraw模块介绍

Python图像处理库PIL的ImageEnhance模块介绍

Python图像处理库PIL的ImageFile模块介绍

Python图像处理库PIL的ImageFont模块介绍

Python图像处理库PIL的ImageGrab模块介绍

Python图像处理库PIL的ImageStat模块介绍

Python图像处理库PIL的ImageOps模块介绍

Python图像处理库PIL的Image模块介绍(一)

Python图像处理库PIL的Image模块介绍(三)

Python图像处理库PIL的ImagePath模块介绍

Python图像处理库PIL的ImageSequence模块介绍

Python图像处理库PIL的Image模块介绍(二)

Python图像处理库PIL的Image模块介绍(四)

Python图像处理库PIL的Image模块介绍(五)

Python图像处理库PIL的基本模块介绍

转载 傅立叶变换的物理意义

转载 图像处理常用边缘检测算子总结

Python图像处理库PIL中快速傅里叶变换FFT的实现(一)

python PIL 图像处理

python skimage图像处理(一)

python skimage图像处理(二)

python skimage图像处理(三)

 

Python图像处理库PIL的基本概念介绍

这一节我们介绍一下PIL中的基本概念。

PIL中所涉及的基本概念有如下几个:通道(bands)、模式(mode)、尺寸(size)、坐标系统(coordinate system)、调色板(palette)、信息(info)和滤波器(filters)。

1、  通道

每张图片都是由一个或者多个数据通道构成。PIL允许在单张图片中合成相同维数和深度的多个通道。

RGB图像为例,每张图片都是由三个数据通道构成,分别为RGB通道。而对于灰度图像,则只有一个通道。

对于一张图片的通道数量和名称,可以通过方法getbands()来获取。方法getbands()Image模块的方法,它会返回一个字符串元组(tuple)。该元组将包括每一个通道的名称。

Python的元组与列表类似,不同之处在于元组的元素不能修改,元组使用小括号,列表使用方括号,元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

方法getbands()的使用如下:

>>>from PIL import Image

>>> im= Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.getbands()

('R', 'G', 'B')

>>>im_bands = im.getbands()

>>>len(im_bands)

3

>>>print im_bands[0]

R

>>>print im_bands[1]

G

>>>print im_bands[2]

B

2、  模式

图像的模式定义了图像的类型和像素的位宽。当前支持如下模式:

11位像素,表示黑和白,但是存储的时候每个像素存储为8bit

L8位像素,表示黑和白。

P8位像素,使用调色板映射到其他模式。

RGB3x8位像素,为真彩色。

RGBA4x8位像素,有透明通道的真彩色。

CMYK4x8位像素,颜色分离。

YCbCr3x8位像素,彩色视频格式。

I32位整型像素。

F32位浮点型像素。

PIL也支持一些特殊的模式,包括RGBX(有padding的真彩色)和RGBa(有自左乘alpha的真彩色)。

可以通过mode属性读取图像的模式。其返回值是包括上述模式的字符串。

属性mode的使用如下:

>>> from PIL importImage

>>> im =Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>> im.mode

'RGB'

>>> md = im.mode

>>> print md

RGB

3、  尺寸

通过size属性可以获取图片的尺寸。这是一个二元组,包含水平和垂直方向上的像素数。

属性mode的使用如下:

>>> from PIL importImage

>>> im =Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.size

(800, 450)

>>>im_size = im.size

>>>print im_size[0]

800

>>>print im_size[1]

450

4、  坐标系统

PIL使用笛卡尔像素坐标系统,坐标(00)位于左上角。注意:坐标值表示像素的角;位于坐标(00)处的像素的中心实际上位于(0.50.5)。

坐标经常用于二元组(xy)。长方形则表示为四元组,前面是左上角坐标。例如,一个覆盖800x600的像素图像的长方形表示为(00800600)。

5、  调色板

调色板模式 ("P")使用一个颜色调色板为每个像素定义具体的颜色值

6、  信息

使用info属性可以为一张图片添加一些辅助信息。这个是字典对象。加载和保存图像文件时,多少信息需要处理取决于文件格式。

属性info的使用如下:

>>>from PIL import Image

>>> im =Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.info

{'jfif_version':(1, 1), 'jfif': 257, 'jfif_unit': 1, 'jfif_density': (96, 96), 'dpi': (96, 96)}

>>>im_info = im.info

>>>im_info

{'jfif_version':(1, 1), 'jfif': 257, 'jfif_unit': 1, 'jfif_density': (96, 96), 'dpi': (96, 96)}

>>>print im_info['jfif_version']

(1, 1)

>>>print im_info['jfif']

257

7、  滤波器

对于将多个输入像素映射为一个输出像素的几何操作,PIL提供了4个不同的采样滤波器:

NEAREST:最近滤波。从输入图像中选取最近的像素作为输出像素。它忽略了所有其他的像素。

BILINEAR双线性滤波。在输入图像的2x2矩阵上进行线性插值。注意:PIL的当前版本,做下采样时该滤波器使用了固定输入模板。

BICUBIC:双立方滤波。在输入图像的4x4矩阵上进行立方插值。注意:PIL的当前版本,做下采样时该滤波器使用了固定输入模板。

ANTIALIAS:平滑滤波。这是PIL 1.1.3版本中新的滤波器。对所有可以影响输出像素的输入像素进行高质量的重采样滤波,以计算输出像素值。在当前的PIL版本中,这个滤波器只用于改变尺寸和缩略图方法。

注意:在当前的PIL版本中,ANTIALIAS滤波器是下采样(例如,将一个大的图像转换为小图)时唯一正确的滤波器。BILIEARBICUBIC滤波器使用固定的输入模板,用于固定比例的几何变换和上采样是最好的。

Image模块中的方法resize()thumbnail()用到了滤波器。

方法resize()的使用如下:

方法resize()的定义为:resize(size, filter=None)=> image

>>>from PIL import Image

>>> im= Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.size

(800, 450)

>>>im_resize = im.resize((256,256))

>>> im_resize.size

(256, 256)

对参数filter不赋值的话,方法resize()默认使用NEAREST滤波器。如果要使用其他滤波器可以通过下面的方法来实现:

>>>im_resize0 = im.resize((256,256), Image.BILINEAR)

>>>im_resize0.size

(256, 256)

>>>im_resize1 = im.resize((256,256), Image.BICUBIC)

>>>im_resize1.size

(256, 256)

>>>im_resize2 = im.resize((256,256), Image.ANTIALIAS)

>>>im_resize2.size

(256, 256)

方法thumbnail ()的使用如下:

方法thumbnail ()的定义为:im.thumbnail(size, filter=None)

>>>from PIL import Image

>>> im= Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.size

(800, 450)

>>>im.thumbnail((200,200))

>>>im.size

(200,112)

这里需要说明的是,方法thumbnail()需要保持宽高比,对于size=(200,200)的输入参数,其最终的缩略图尺寸为(200, 112)

对参数filter不赋值的话,方法thumbnail()默认使用NEAREST滤波器。如果要使用其他滤波器可以通过下面的方法来实现:

>>> im= Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.size

(800, 450)

>>> im.thumbnail((200,200),Image.BILINEAR)

>>> im.size

(200, 112)

>>> im= Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.size

(800, 450)

>>> im.thumbnail((200,200), Image.BICUBIC)

>>> im.size

(200, 112)

>>> im= Image.open('D:\\Code\\Python\\test\\img\\1.jpg')

>>>im.size

(800, 450)

>>> im.thumbnail((200,200), Image.ANTIALIAS)

>>> im.size

(200, 112)

在数字图像处理中,针对不同的图像格式有其特定的处理算法。所以,在做图像处理之前,我们需要考虑清楚自己要基于哪种格式的图像进行算法设计及其实现。本文基于这个需求,使用python中的图像处理库PIL来实现不同图像格式的转换。

对于彩色图像,不管其图像格式是PNG,还是BMP,或者JPG,在PIL中,使用Image模块的open()函数打开后,返回的图像对象的模式都是“RGB”。而对于灰度图像,不管其图像格式是PNG,还是BMP,或者JPG,打开后,其模式为“L”。

通过之前的博客对Image模块的介绍,对于PNGBMPJPG彩色图像格式之间的互相转换都可以通过Image模块的open()save()函数来完成。具体说就是,在打开这些图像时,PIL会将它们解码为三通道的“RGB”图像。用户可以基于这个“RGB”图像,对其进行处理。处理完毕,使用函数save(),可以将处理结果保存成PNGBMPJPG中任何格式。这样也就完成了几种格式之间的转换。同理,其他格式的彩色图像也可以通过这种方式完成转换。当然,对于不同格式的灰度图像,也可通过类似途径完成,只是PIL解码后是模式为“L”的图像。

这里,我想详细介绍一下Image模块的convert()函数,用于不同模式图像之间的转换。

Convert()函数有三种形式的定义,它们定义形式如下:

im.convert(mode) image

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

im.convert(mode, matrix) image

使用不同的参数,将当前的图像转换为新的模式,并产生新的图像作为返回值。

通过博客“Python图像处理库PIL的基本概念介绍”,我们知道PIL中有九种不同模式。分别为1LPRGBRGBACMYKYCbCrIF

本文我采用的示例图像是图像处理中经典的lena照片。分辨率为512x512lena图片如下:

Python图像处理库PIL中图像格式转换

一、模式“RGB”转换为其他不同模式

1、 模式“1

模式“1”为二值图像,非黑即白。但是它每个像素用8bit表示,0表示黑,255表示白。下面我们将lena图像转换为“1”图像。

例子:

  1.  
     
  2.  
    >>>from PIL import Image
  3.  
     
  4.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>> lena.mode
  7.  
     
  8.  
    'RGB'
  9.  
     
  10.  
    >>> lena.getpixel((0,0))
  11.  
     
  12.  
    (197, 111, 78)
  13.  
     
  14.  
    >>> lena_1 = lena.convert("1")
  15.  
     
  16.  
    >>> lena_1.mode
  17.  
     
  18.  
    '1'
  19.  
     
  20.  
    >>> lena_1.size
  21.  
     
  22.  
    (512, 512)
  23.  
     
  24.  
    >>>lena_1.getpixel((0,0))
  25.  
     
  26.  
    255
  27.  
     
  28.  
    >>> lena_1.getpixel((10,10))
  29.  
     
  30.  
    255
  31.  
     
  32.  
    >>>lena_1.getpixel((10,120))
  33.  
     
  34.  
    0
  35.  
     
  36.  
    >>>lena_1.getpixel((130,120))
  37.  
     
  38.  
    255

 

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

2、 模式“L

模式“L”为灰色图像,它的每个像素用8bit表示,0表示黑,255表示白,其他数字表示不同的灰度。在PIL中,从模式“RGB”转换为“L”模式是按照下面的公式转换的:

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

下面我们将lena图像转换为“L”图像。

例子:

  1.  
    >>> from PIL importImage
  2.  
     
  3.  
    >>> lena = Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena.mode
  6.  
     
  7.  
    'RGB'
  8.  
     
  9.  
    >>> lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>> lena_L =lena.convert("L")
  14.  
     
  15.  
    >>> lena_L.mode
  16.  
     
  17.  
    'L'
  18.  
     
  19.  
    >>> lena_L.size
  20.  
     
  21.  
    (512, 512)
  22.  
     
  23.  
    >>>lena.getpixel((0,0))
  24.  
     
  25.  
    (197, 111, 78)
  26.  
     
  27.  
    >>>lena_L.getpixel((0,0))
  28.  
     
  29.  
    132

对于第一个像素点,原始图像lena(197, 111, 78),其转换为灰色值为:

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

转换后的图像lena_L如下:

3、 模式“P

模式“P”为8位彩色图像,它的每个像素用8bit表示,其对应的彩色值是按照调色板查询出来的。

下面我们使用默认的调色板将lena图像转换为“P”图像。

例子:

  1.  
     
  2.  
    >>> from PIL importImage
  3.  
     
  4.  
    >>> lena = Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>> lena.mode
  7.  
     
  8.  
    'RGB'
  9.  
     
  10.  
    >>> lena.getpixel((0,0))
  11.  
     
  12.  
    (197, 111, 78)
  13.  
     
  14.  
    >>> lena_P =lena.convert("P")
  15.  
     
  16.  
    >>> lena_P.mode
  17.  
     
  18.  
    'P'
  19.  
     
  20.  
    >>>lena_P.getpixel((0,0))
  21.  
     
  22.  
    62

 

转换后的图像lena_P如下:

4、 模式“RGBA

模式“RGBA”为32位彩色图像,它的每个像素用32bit表示,其中24bit表示红色、绿色和蓝色三个通道,另外8bit表示alpha通道,即透明通道。

下面我们将模式为“RGB”的lena图像转换为“RGBA”图像。

例子: 

  1.  
     
  2.  
     
  3.  
    >>> from PIL import Image
  4.  
     
  5.  
    >>>lena = Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  6.  
     
  7.  
    >>>lena.mode
  8.  
     
  9.  
    'RGB'
  10.  
     
  11.  
    >>>lena.getpixel((0,0))
  12.  
     
  13.  
    (197,111, 78)
  14.  
     
  15.  
    >>>lena_rgba = lena.convert("RGBA")
  16.  
     
  17.  
    >>>lena_rgba.mode
  18.  
     
  19.  
    'RGBA'
  20.  
     
  21.  
    >>>lena_rgba.getpixel((0,0))
  22.  
     
  23.  
    (197,111, 78, 255)
  24.  
     
  25.  
    >>>lena_rgba.getpixel((0,1))
  26.  
     
  27.  
    (196,110, 77, 255)
  28.  
     
  29.  
    >>>lena.getpixel((0,0))
  30.  
     
  31.  
    (197,111, 78)
  32.  
     
  33.  
    >>>lena.getpixel((0,1))
  34.  
     
  35.  
    (196,110, 77)

 

从实例中可以看到,使用当前这个方式将“RGB”图像转为“RGBA”图像时,alpha通道全部设置为255,即完全不透明。

转换后的图像lena_rgba如下:

5、 模式“CMYK

模式“CMYK”为32位彩色图像,它的每个像素用32bit表示。模式CMYK”就是印刷四分色模式,它是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。

四种标准颜色是:CCyan = 青色,又称为‘天蓝色’或是‘湛蓝’MMagenta = 品红色,又称为‘洋红色’;YYellow = 黄色;KKey Plate(blacK) = 定位套版色(黑色)。

下面我们将模式为“RGB”的lena图像转换为“CMYK”图像。

例子:

  1.  
     
  2.  
    >>>from PIL import Image
  3.  
     
  4.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>> lena_cmyk =lena.convert("CMYK")
  7.  
     
  8.  
    >>> lena_cmyk.mode
  9.  
     
  10.  
    'CMYK'
  11.  
     
  12.  
    >>>lena_cmyk.getpixel((0,0))
  13.  
     
  14.  
    (58, 144, 177, 0)
  15.  
     
  16.  
    >>> lena_cmyk.getpixel((0,1))
  17.  
     
  18.  
    (59, 145, 178, 0)
  19.  
     
  20.  
    >>>lena.getpixel((0,0))
  21.  
     
  22.  
    (197, 111, 78)
  23.  
     
  24.  
    >>>lena.getpixel((0,1))
  25.  
     
  26.  
    (196, 110, 77)

 

从实例中可以得知PIL中“RGB”转换为“CMYK”的公式如下:

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

由于该转换公式比较简单,转换后的图像颜色有些失真。

转换后的图像lena_cmyk如下:

6、 模式“YCbCr

模式“YCbCr”为24位彩色图像,它的每个像素用24bit表示。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.  
    >>>from PIL import Image
  3.  
     
  4.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>> lena_ycbcr =lena.convert("YCbCr")
  7.  
     
  8.  
    >>>lena_ycbcr.mode
  9.  
     
  10.  
    'YCbCr'
  11.  
     
  12.  
    >>>lena_ycbcr.getpixel((0,0))
  13.  
     
  14.  
    (132, 97, 173)
  15.  
     
  16.  
    >>>lena.getpixel((0,0))
  17.  
     
  18.  
    (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如下:

7、 模式“I

模式“I”为32位整型灰色图像,它的每个像素用32bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“I”模式是按照下面的公式转换的:

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

下面我们将模式为“RGB”的lena图像转换为“I”图像。

例子:

  1.  
     
  2.  
    >>> from PIL import Image
  3.  
     
  4.  
    >>>lena = Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>>lena.getpixel((0,0))
  7.  
     
  8.  
    (197,111, 78)
  9.  
     
  10.  
    >>>lena.getpixel((0,1))
  11.  
     
  12.  
    (196,110, 77)
  13.  
     
  14.  
    >>> lena_I =lena.convert("I")
  15.  
     
  16.  
    >>> lena_I.mode
  17.  
     
  18.  
    'I'
  19.  
     
  20.  
    >>>lena_I.getpixel((0,0))
  21.  
     
  22.  
    132
  23.  
     
  24.  
    >>>lena_I.getpixel((0,1))
  25.  
     
  26.  
    131
  27.  
     
  28.  
    >>> lena_L =lena.convert("L")
  29.  
     
  30.  
    >>>lena_L.getpixel((0,0))
  31.  
     
  32.  
    132
  33.  
     
  34.  
    >>>lena_L.getpixel((0,1))
  35.  
     
  36.  
    131

 

从实验的结果看,模式“I”与模式“L”的结果是完全一样,只是模式“L”的像素是8bit,而模式“I”的像素是32bit

8、 模式“F

模式“F”为32位浮点灰色图像,它的每个像素用32bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“F”模式是按照下面的公式转换的:

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

下面我们将模式为“RGB”的lena图像转换为“F”图像。

例子:

  1.  
     
  2.  
    >>>from PIL import Image
  3.  
     
  4.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>>lena.getpixel((0,0))
  7.  
     
  8.  
    (197, 111, 78)
  9.  
     
  10.  
    >>>lena.getpixel((0,1))
  11.  
     
  12.  
    (196, 110, 77)
  13.  
     
  14.  
    >>> lena_F =lena.convert("F")
  15.  
     
  16.  
    >>> lena_F.mode
  17.  
     
  18.  
    'F'
  19.  
     
  20.  
    >>>lena_F.getpixel((0,0))
  21.  
     
  22.  
    132.95199584960938
  23.  
     
  24.  
    >>>lena_F.getpixel((0,1))
  25.  
     
  26.  
    131.95199584960938

 

模式“F”与模式“L”的转换公式是一样的,都是RGB转换为灰色值的公式,但模式“F”会保留小数部分,如实验中的数据。

 二、其他不同模式转换为“RGB”模式

模式“RGB”为24位彩色图像,它的每个像素用24bit表示,分别表示红色、绿色和蓝色三个通道。

PIL中,对于彩色图像,open后都会转换为“RGB”模式,然后该模式可以转换为其他模式,比如“1”、“L”、“P”和“RGBA”,这几种模式也可以转换为“RGB”模式。

1、 模式“1”转换为模式“RGB

模式“RGB”转换为模式“1”以后,像素点变成黑白两种点,要么是0,要么是255。而从模式“1”转换成“RGB”时,“RGB”的三个通道都是模式“1”的像素值的拷贝。

例子:

  1.  
    >>> from PILimport Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_1 =lena.convert("1")
  6.  
     
  7.  
    >>> lena_1_rgb =lena_1.convert("RGB")
  8.  
     
  9.  
    >>> lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>>lena_1.getpixel((0,0))
  14.  
     
  15.  
    255
  16.  
     
  17.  
    >>>lena_1_rgb.getpixel((0,0))
  18.  
     
  19.  
    (255, 255, 255)

2、 模式“L”转换为模式“RGB

模式“RGB”转换为模式“L”以后,像素值为[0,255]之间的某个数值。而从模式“L”转换成“RGB”时,“RGB”的三个通道都是模式“L”的像素值的拷贝。

例子:

  1.  
     
  2.  
    >>> from PIL import Image
  3.  
     
  4.  
    >>> lena = Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  5.  
     
  6.  
    >>> lena_L =lena.convert("L")
  7.  
     
  8.  
    >>> lena_L_rgb =lena_L.convert("RGB")
  9.  
     
  10.  
    >>>lena.getpixel((0,0))
  11.  
     
  12.  
    (197, 111, 78)
  13.  
     
  14.  
    >>>lena_L.getpixel((0,0))
  15.  
     
  16.  
    132
  17.  
     
  18.  
    >>>lena_rgb.getpixel((0,0))
  19.  
     
  20.  
    (132, 132, 132)

 

3、 模式“P”转换为模式“RGB

模式“RGB”转换为模式“P”以后,像素值为[0,255]之间的某个数值,但它为调色板的索引值,其最终还是彩色图像。从模式“P”转换成“RGB”时,“RGB”的三个通道会变成模式“P”的像素值索引的彩色值。

例子:

  1.  
    >>> from PIL import Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_P =lena.convert("P")
  6.  
     
  7.  
    >>> lena_P_rgb =lena_P.convert("RGB")
  8.  
     
  9.  
    >>>lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>>lena_P.getpixel((0,0))
  14.  
     
  15.  
    62
  16.  
     
  17.  
    >>>lena_P_rgb.getpixel((0,0))
  18.  
     
  19.  
    (204, 102, 51)

4、 模式“RGBA”转换为模式“RGB

模式“RGB”转换为模式“RGBA”以后,图像从三通道变成了四通道,其RGB三个通道的数值没有变化,新增的alpha通道均为255,表示不透明。从模式“RGBA”转换成“RGB”时,“RGB”的三个通道又变回原来的数值。

例子:

  1.  
    >>> from PILimport Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_RGBA =lena.convert("RGBA")
  6.  
     
  7.  
    >>> lena_RGBA_rgb= lena_RGBA.convert("RGB")
  8.  
     
  9.  
    >>>lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>>lena_RGBA.getpixel((0,0))
  14.  
     
  15.  
    (197, 111, 78, 255)
  16.  
     
  17.  
    >>>lena_RGBA_rgb.getpixel((0,0))
  18.  
     
  19.  
    (197, 111, 78)

5、 模式“CMYK”转换为模式“RGB

模式“RGB”转换为模式“CMYK”以后,图像从三通道变成了四通道,其CMY三个通道的数值是通过之前的公式计算得到,K通道被直接赋值为0

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

从模式“CMYK”转换成“RGB”时,“RGB”的三个通道又变回原来的数值,这是无损的转换。

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

例子:

  1.  
    >>> from PIL import Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_CMYK =lena.convert("CMYK")
  6.  
     
  7.  
    >>> lena_CMYK_rgb= lena_CMYK.convert("RGB")
  8.  
     
  9.  
    >>>lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>>lena_CMYK.getpixel((0,0))
  14.  
     
  15.  
    (58, 144, 177, 0)
  16.  
     
  17.  
    >>>lena_CMYK_rgb.getpixel((0,0))
  18.  
     
  19.  
    (197, 111, 78)

6、 模式“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)

例子:

  1.  
    >>> from PILimport Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_YCbCr =lena.convert("YCbCr")
  6.  
     
  7.  
    >>> lena_YCbCr_rgb= lena_YCbCr.convert("RGB")
  8.  
     
  9.  
    >>>lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>>lena_YCbCr.getpixel((0,0))
  14.  
     
  15.  
    (132, 97, 173)
  16.  
     
  17.  
    >>>lena_YCbCr_rgb.getpixel((0,0))
  18.  
     
  19.  
    (195, 110, 77)

7、 模式“I”转换为模式“RGB

模式“RGB”转换为模式“I”,将三通道变成了单通道,使用下面的公式计算获得像素值:

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

从模式“I”转换成“RGB”时,“RGB”的三个通道都是模式“I”的像素值的拷贝。

例子:

  1.  
    >>> from PILimport Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_I =lena.convert("I")
  6.  
     
  7.  
    >>> lena_I_rgb =lena_I.convert("RGB")
  8.  
     
  9.  
    >>>lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>>lena_I.getpixel((0,0))
  14.  
     
  15.  
    132
  16.  
     
  17.  
    >>>lena_I_rgb.getpixel((0,0))
  18.  
     
  19.  
    (132, 132, 132)

8、 模式“F”转换为模式“RGB

模式“RGB”转换为模式“F”,将彩色图像变成了32位浮点灰色图像。在PIL中,从模式“RGB”转换为“F”模式是按照下面的公式转换的:

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

从模式“F”转换成“RGB”时,“RGB”的三个通道都是模式“F”的像素值整数部分的拷贝。

例子:

  1.  
    >>> from PILimport Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_F =lena.convert("F")
  6.  
     
  7.  
    >>> lena_F_rgb =lena_F.convert("RGB")
  8.  
     
  9.  
    >>>lena.getpixel((0,0))
  10.  
     
  11.  
    (197, 111, 78)
  12.  
     
  13.  
    >>> lena_F.getpixel((0,0))
  14.  
     
  15.  
    132.95199584960938
  16.  
     
  17.  
    >>>lena_F_rgb.getpixel((0,0))
  18.  
     
  19.  
    (132, 132, 132)

三、调色板图像的转换

PIL中,将“RGB”图像转换为“P”模式图像时,有对应的convert()函数定义,如下:

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

这个定义将模式固定为“P”,后面可以带几个可选参数。它们分别为:ditherpalettecolors

参数dither用于控制颜色抖动。默认是FLOYDSTEINBERG,不使能该功能,则赋值为NONE

参数palette用于控制调色板的产生。默认是WEB,这是标准的216色的“web palette”。要使用优化的调色板,则赋值为ADAPTIVE

参数colors用于控制调色板颜色数目。当参数paletteADAPTIVE时,colors数值表示调色板的颜色数目。默认是最大值,即256种颜色。

使用默认值,将“RGB”转换为“P”模式图像后如下:

 

参数dither默认为FLOYDSTEINBERG;如果不开启颜色抖动功能,则赋值为NONE。其转换结果如下:

 

参数palette默认是WEB。要使用优化的调色板,则赋值为ADAPTIVE。其转换结果为:

 

当参数paletteADAPTIVE时,colors数值表示调色板的颜色数目。默认值为256。当colors设置为10时,其转换结果为:

 

         上述转换代码如下:

  1.  
    >>> from PILimport Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena_P_dither= lena.convert("P", dither = Image.NONE)
  6.  
     
  7.  
    >>> lena_P_palette= lena.convert("P", palette = Image.ADAPTIVE)
  8.  
     
  9.  
    >>>lena_P_palette_colors = lena.convert("P", palette = Image.ADAPTIVE,colors = 10)

四、带矩阵的模式转换

模式转换函数convert()的第三种定义如下:

im.convert(mode,matrix) image

这种定义只适合将一个“RGB”图像转换为“L”或者“RGB”图像,不能转换为其他模式的图像。变量matrix4或者16元组。

例子:下面的例子将一个RGB图像(根据ITU-R709线性校准,使用D65亮度)转换到CIE XYZ颜色空间:

  1.  
    >>>from PIL import Image
  2.  
     
  3.  
    >>> lena =Image.open("D:\\Code\\Python\\test\\img\\lena.jpg")
  4.  
     
  5.  
    >>> lena.mode
  6.  
     
  7.  
    'RGB'
  8.  
     
  9.  
    >>> rgb2xyz= (
  10.  
     
  11.  
    0.412453,0.357580, 0.180423, 0,
  12.  
     
  13.  
    0.212671,0.715160, 0.072169, 0,
  14.  
     
  15.  
    0.019334,0.119193, 0.950227, 0 )
  16.  
     
  17.  
     
  18.  
     
  19.  
    >>>lena_L = lena.convert("L", rgb2xyz)
  20.  
     
  21.  
    >>>lena_rgb = lena.convert("RGB", rgb2xyz)

 

图像lena_L如下:

图像lena_rgb如下:

 

五、小结

PIL中对图像格式及模式的转换,相对都是非常简洁。用户可以根据自己的需求,将图像转换为目标模式,进而进行各种处理。对于不同的图像处理目的,需要选择在哪种模式上设计图像算法,设计什么样的算法,这个是一个极为关键的问题。希望之后的学习中,能够有比较深刻的认识。

(完)

posted @ 2020-09-13 22:33  Satansz  阅读(690)  评论(0编辑  收藏  举报