<ul>
<li><p>通常,图像是RGB,这意味着它们有3个通道,一个用于红色,一个用于绿色,一个用于蓝色。这通常意味着每个像素占用3个字节的存储空间,一个用于红色,一个用于绿色,一个用于蓝色。</p></li>
<li><p>如果您有一个p模式的图像,这意味着它是苍白的。这意味着有一个调色板,其中有多达256种不同的颜色,而不是为每个像素存储3个字节的R、G和B,而是存储1个字节,这是调色板的索引。这既有优点也有缺点。这样做的好处是,您的映像需要1/3的内存和磁盘空间。缺点是它只能代表256种独特的颜色,所以你可能会得到带状或工艺品。</p></li>
<li><p>如果你有一个L模式的图像,这意味着它是一个单通道图像-通常解释为灰度。L的意思是只存储亮度。它非常紧凑,但只存储灰度,而不是颜色。</p></li>
</ul>
<p>使用<code>convert(mode)</code>函数在它们之间进行转换,例如要转到RGB模式,请使用:</p>
<pre><code>image.convert('RGB')
</code></pre>
<hr/>
<p>我经常用“正常”这个词!为什么?因为你可以做不正常的事情!</p>
<ul>
<li><p>您可以以RGB格式存储灰色图像。你所要做的,就是使红色部分等于绿色部分等于蓝色部分(R=G=B),它将显示为灰色,但以一种低效的RGB格式存储,占用3倍的空间,否则可能需要。</p></li>
<li><p>您可以以p格式存储灰色图像,只需确保所有调色板条目都具有R=G=B即可。</p></li>
</ul>
<hr/>
<p>这是踢球的人。。。如果您想要并希望看到RGB图像,则应在打开时将其转换为RGB:</p>
<pre><code>im = Image.open("image.jpg").convert('RGB')
</code></pre>
<p>这样,您就不会有问题的GIF文件(它总是调色板)或PNG文件可以调色板,可以是灰度或RGB。通常JPEG图像不会出现问题,因为它们几乎总是RGB。</p>
<hr/>
<p>下面是一个例子。从这个红蓝渐变图像开始:</p>
<p><a href="https://i.stack.imgur.com/3NVV0.png" rel="noreferrer"><img src="https://i.stack.imgur.com/3NVV0.png" alt="enter image description here"/></a></p>
<p>让我们使用<code>IPython</code>在RGB空间中查看。首先,看看红色频道:</p>
<pre><code>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)
</code></pre>
<p>请注意,顶部有255,因为它是红色的,底部有0,因为那里没有红色。</p>
<p>现在让我们看一下绿色通道,它到处都是0,因为没有绿色。</p>
<pre><code>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)
</code></pre>
<p>最后,让我们看看蓝色频道。在图像为纯红色的顶部为0,在图像为纯蓝色的底部为255。</p>
<pre><code>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)
</code></pre>
<p>现在让我们在调色板模式下查看相同的图像。</p>
<pre><code># 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
</code></pre>
<p>现在将索引放入调色板:</p>
<pre><code>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)
</code></pre>
<p>现在您可以看到图像的顶行有palette index 15,如果您在前面的palette中查找它,您将看到它是红色的。</p>
<p>现在让我们在L模式下看同一个图像-记住L的意思是“亮度”<em>“亮度”</em>,这只是在黑白比例(即灰度)上说“亮度”</em>的一种奇特方式:</p>
<pre><code># 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)
</code></pre>
<p>所以,现在图像的第一行是76,第二行是29。这些是什么?把RGB转换成L的公式是:</p>
<blockquote>
<p>L = R * 299/1000 + G * 587/1000 + B * 114/1000</p>
</blockquote>
<p>所以,在顶行,R=255,G=0,B=0,所以亮度变成:</p>
<pre><code>L = 255 * 299/1000 + 0 + 0
L = 76
</code></pre>
<p>在最下面一行,R=0,G=0,B=255,所以亮度变成:</p>
<pre><code>L = 0 + 0 + 255 * 114/1000
L = 29
</code></pre>