gpt4 book ai didi

python - PIL中 'P'和 'L'模式的图片有什么区别?

转载 作者:太空狗 更新时间:2023-10-29 20:34:37 25 4
gpt4 key购买 nike

根据 https://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes ,

  1. 它们有什么区别?
  2. 我们可以从一个转换为另一个吗?
  3. 两种模式的图像示例是什么?

最佳答案

  • 通常,图像是 RGB,这意味着它们有 3 个 channel ,一个用于红色,一个用于绿色,一个用于蓝色。这通常意味着每个像素占用 3 个字节的存储空间,一个用于红色,一个用于绿色,一个用于蓝色。

  • 如果您有一个 P 模式图像,这意味着它是调色板。这意味着调色板中有多达 256 种不同的颜色,而不是为每个像素存储 3 个字节的 R、G 和 B,而是存储 1 个字节,它是调色板的索引。这既有优点也有缺点。优点是您的图像需要内存和磁盘空间的 1/3。缺点是它只能表示 256 种独特的颜色 - 所以你可能会得到 banding或人工制品。

  • 如果您有一个 L 模式图像,这意味着它是一个单 channel 图像 - 通常被解释为灰度。 L 表示只存储亮度。它非常紧凑,但只存储灰度,不存储颜色。


你可以分辨出哪个mode您的图像通过查看:

image.mode

如果您的图像是调色板,它将是 P,或者 PA 如果也使用 alpha channel 进行调色板。如果您的图像是灰度图像,它将是 L,如果是带有 alpha channel 的灰度图像,它将是 LA

您可以使用 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。


这里有一个例子来演示。从这张红蓝渐变图像开始:

enter image description here

让我们使用 IPython 在 RGB 空间中查看。首先看红色 channel :

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,因为那里没有红色。

现在让我们看一下绿色 channel ,因为没有绿色,所以到处都是 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)

最后,让我们看看蓝色 channel 。在图像为纯红色的顶部为 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/1000 + 0 + 0 
L = 76

在最下面一行,R=0, G=0, B=255,所以亮度变成了:

L = 0 + 0 + 255 * 114/1000
L = 29

关键词:Python、PIL、Pillow、调色板、图像处理、prime。

关于python - PIL中 'P'和 'L'模式的图片有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52307290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com