根据https://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes,
答案 0 :(得分:11)
通常,图像是RGB,这意味着它们具有3个通道,一个用于红色,一个用于绿色,一个用于蓝色。通常,这意味着每个像素占用3个字节的存储空间,一个存储红色,一个存储绿色,一个存储蓝色。
如果您有P模式图像,则表示它已调色板化。这意味着其中有一个调色板,其中最多包含256种不同的颜色,而不是为每个像素分别为R,G和B存储3个字节,而是存储1个字节(这是调色板的索引)。这同时具有优点和缺点。好处是您的映像需要内存和磁盘上1/3的空间。缺点是它只能代表256种独特的颜色-因此您可能会出现条纹或伪像。
如果具有L模式图像,则表示它是单通道图像-通常解释为灰度。 L表示仅存储亮度。它非常紧凑,但是只存储灰度而不是颜色。
您可以使用convert(mode)
函数在它们之间进行转换,例如要进入RGB模式,请使用:
image.convert('RGB')
我经常使用“正常” 这个词!为什么?因为你可以做异常的事情!
您可以以RGB格式存储灰色图像。您要做的就是使红色分量等于绿色分量,等于蓝色分量(R = G = B),并且它将显示为灰色,但以低效的RGB格式存储,该格式占用原本需要的空间的3倍。
您可以以P格式存储灰色图像,只需确保所有调色板条目都具有R = G = B。
这里是踢球者...如果您希望并期望获得RGB图像,则只需在打开时转换为RGB:
im = Image.open("image.jpg").convert('RGB')
那样,您将永远不会遇到GIF文件(始终为灰色)和PNG文件(可呈灰色,可以是灰度或RGB)的问题。 JPEG图像通常不会出现问题,因为它们几乎总是RGB。
这是一个示例进行演示。从此红蓝色渐变图像开始:
让我们使用IPython
在RGB空间中查看。首先,查看红色频道:
In [21]: im = Image.open('a.png').convert('RGB')
In [22]: np.array(im.getchannel(0))
Out[22]:
array([[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[254, 254, 254, ..., 254, 254, 254],
...,
[ 1, 1, 1, ..., 1, 1, 1],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]], dtype=uint8)
请注意,由于红色,它的顶部有255,因为没有红色,所以在底部有0。
现在让我们看一下绿色通道,因为没有绿色,所以到处都是0。
In [23]: np.array(im.getchannel(1))
Out[23]:
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=uint8)
最后,让我们看一下Blue频道。在图像为纯红色的顶部为0,在图像为纯蓝色的底部为255。
In [24]: np.array(im.getchannel(2))
Out[24]:
array([[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 1, 1, 1, ..., 1, 1, 1],
...,
[254, 254, 254, ..., 254, 254, 254],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
现在让我们以调色板模式查看同一张图片。
# Convert to palette mode
im = Image.open('a.png').convert('P')
# Extract the palette and reshape as 256 entries of 3 RGB bytes each
In [27]: np.array(im.getpalette()).reshape(256,3)
Out[27]:
array([[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
[ 51, 0, 0],
[102, 0, 0],
[153, 0, 0],
[204, 0, 0],
[255, 0, 0], <--- entry 15 = rgb(255,0,0) = Red
[ 0, 51, 0],
[ 51, 51, 0],
[102, 51, 0],
[153, 51, 0],
[204, 51, 0],
[255, 51, 0],
[ 0, 102, 0],
[ 51, 102, 0],
[102, 102, 0],
[153, 102, 0],
[204, 102, 0],
[255, 102, 0],
[ 0, 153, 0],
[ 51, 153, 0],
[102, 153, 0],
[153, 153, 0],
[204, 153, 0],
[255, 153, 0],
[ 0, 204, 0],
[ 51, 204, 0],
[102, 204, 0],
[153, 204, 0],
[204, 204, 0],
[255, 204, 0],
[ 0, 255, 0],
[ 51, 255, 0],
[102, 255, 0],
[153, 255, 0],
[204, 255, 0],
[255, 255, 0],
...
... up to 256 entries
现在将索引添加到面板中:
In [28]: np.array(im.getchannel(0))
Out[28]:
array([[ 15, 15, 15, ..., 15, 15, 15],
[ 15, 15, 15, ..., 15, 15, 15],
[ 15, 15, 15, ..., 15, 15, 15],
...,
[190, 190, 190, ..., 190, 190, 190],
[190, 190, 190, ..., 190, 190, 190],
[190, 190, 190, ..., 190, 190, 190]], dtype=uint8)
现在您可以看到图像的第一行具有调色板索引15,如果您在前面的调色板中查找该索引,它将显示为红色。
现在让我们以L模式查看同一张图片-记住L表示“亮度” ,这只是一种以黑色标度表示“亮度” 的奇特方式变为白色,即灰度:
# Open into greyscale, or L mode
In [1]: im = Image.open('a.png').convert('L')
# Dump the pixels
In [2]: np.array(im.getchannel(0))
Out[2]:
array([[76, 76, 76, ..., 76, 76, 76],
[76, 76, 76, ..., 76, 76, 76],
[76, 76, 76, ..., 76, 76, 76],
...,
[29, 29, 29, ..., 29, 29, 29],
[29, 29, 29, ..., 29, 29, 29],
[29, 29, 29, ..., 29, 29, 29]], dtype=uint8)
因此,现在图像的第一行是76,最低行是29。那是什么?好了,将RGB转换为L的公式是:
L = R * 299/1000 + G * 587/1000 + B * 114/1000
因此,在第一行中,R = 255,G = 0,B = 0,所以亮度变为:
L = 255 * 299/100 + 0 + 0
L = 76
在最底行,R = 0,G = 0,B = 255,因此亮度变为:
L = 0 + 0 + 255 * 114/100
L = 29
答案 1 :(得分:4)
“ L”模式映射到黑白像素(及其间)。 “ P”模式映射有调色板。您可以将图像转换为这些模式之一。
from PIL import Image
im = Image.open("im.jpg")
im_l = im.convert('L')
im_p = im.convert('P')
im.show()
im_l.show()
im_p.show()
答案 2 :(得分:2)
“ L”模式在这里代表灰度。...因此它可以容纳256个灰度阴影中的任何一个(包括黑白作为灰度阴影)。
“ P”模式可以容纳256种不同的颜色,例如红色,蓝色,绿色等。
彼此转换,如果您的意思是将图像从灰度转换为彩色,反之亦然。...是的,这是可能的。...
示例:8位黑白图像(技术上为灰度图像)为“ L”,任何8位彩色图像为“ P”模式。