为什么 PIL convert('RGB') 将一些透明的变成黑色而将一些变成白色?

Why PIL convert('RGB') makes some transparent into black but some into white?

我有两个类似的透明背景蒙版图像。 我想要获得图像差异,并希望它的价值尽可能低,因为图像相似。

lenna1.png lenna2.png

但是结果显示透明区域的巨大差异看起来是一样的。
(白色表示差异)

diff_res = ImageChops.difference(lenna1, lenna2).convert('RGB')

diff_res

我在一些网站上检查了 lenna1、lenna2 图像差异,它说图像除了边界上的小差异外都是一样的。

然后我怀疑alpha通道值,将lenna1,lenna2转换成'RGB'。 并且它显示一个人的背景为黑色,而另一个人的背景为白色。

lenna1 = Image.open('lenna1.png')
lenna2 = Image.open('lenna2.png')

converted_lenna1 = lenna1.convert('RGB')
converted_lenna2 = lenna2.convert('RGB')

converted_lenna1   converted_lenna2

现在我知道 convert() 默认将透明区域变成黑色。但是我还是不明白。

  1. 为什么透明区域图像有差异?
  2. 为什么有些透明图片变白了,如何制作自己的"will be white"透明图片?

*我还使用 .putalpha()

测试了相同的 alpha 级别

感谢您阅读这个问题。

两张图片都有透明度,只是一张白色像素透明,另一张黑色像素透明。换句话说,透明像素的底层颜色在一个图像中是黑色,在另一个图像中是白色。你看不出区别,因为它们是透明的!

这里是lenna1,左边移除了 alpha 层,然后是右边的 alpha 层本身:

这里是 lenna2,左侧移除了 alpha 层,然后是右侧的 alpha 层本身:

您可以通过找到所有透明像素并将它们变成白色来使它们相同:

# Load the image and make into Numpy array
rgba = np.array(Image.open('lena2.png'))

# Make image transparent white anywhere it is transparent
rgba[rgba[...,-1]==0] = [255,255,255,0]

# Make back into PIL Image and save
Image.fromarray(rgba).save('result.png')

如果您想让透明像素显示为蓝色以便您可以看到它们进行测试,请使用:

rgba[rgba[...,-1]==0] = [0,0,255,255]

如果您安装了 ImageMagick,您可以在终端中强制所有透明像素变成您选择的颜色,例如洋红色:

magick lenna1.png -background magenta -alpha background result.png

这通常意味着您可以通过将所有透明像素设为黑色来提高 PNG 压缩率并减小 PNG 文件的大小,因此,与透明像素的颜色完全不同的情况相比,图像的压缩效果可能会好得多:

magick image.png -background black -alpha background result.png

在 Imagemagick 7 中,您可以进行蒙版比较以忽略图像区域。 (Python Wand 0.5.3 支持 Imagemagick 7,虽然我还不知道它是否支持屏蔽比较)。这是命令行 Imagemagick 7 中的示例:

白色:

绿色:

掩码:

magick compare -metric rmse -read-mask hat_mask.png hat_white.png hat_green.png hat_diff.png

0 (0)


差异将在下面显示为红色。

如果我使用你的图片:

magick image1.png -alpha extract mask.png
magick compare -metric rmse -read-mask mask.png image1.png image2.png -alpha deactivate diff.png

or

magick compare -metric rmse  \( image1.png -alpha extract -write mpr:mask +delete \) -read-mask mpr:mask image1.png image2.png -alpha deactivate diff.png


7179.85 (0.109557) <--- ~11% different in opaque area


如果我们比较整个图像,包括透明区域下方的区域,则

magick compare -metric rmse image1.png image2.png -alpha off null:
59598.7 (0.909419) <--- ~91% different over the whole area

如果我们包含 alpha 通道,那么由于包含两个相同的 alpha 通道,这会降低比较指标,这是误导性的,我们得到:

magick compare -metric rmse image1.png image2.png null:

or

magick compare -metric rmse -channel rgba image1.png image2.png null:

2828.15 (0.0431548) <--- ~4.3% different.