将PIL图像从RGB转换为YCbCr会生成4个通道而不是3个,并且表现得像RGB。

9
好的,标题已经很明显了。我有一张图片文件,想要将其分别分离为Y、Cb和Cr。在打开文件后,将其从RGB(这是打开图像文件时的默认模式)转换为YCbCr,然后使用numpy.array()将其转换为数组时,它产生了一个具有4个通道的2D数组,这不是我所期望的,因为根据文档的说明,应该只有3个通道。

这是我在解释器中做的事情:

ImageFile = Image.open('filePath', 'r')
ImageFile = ImageFile.convert('YCbCr')
ImageFileYCbCr = numpy.array(ImageFile)
ImageFileYCbCr

导致
array([[[103, 140, 133,  95],
    [140, 133,  91, 141],
    [132,  88, 141, 131],
    ..., 
    [129,  65, 146, 129],
    [ 64, 146, 130,  65],
    [146, 129,  64, 147]],

   [[129,  64, 147, 129],
    [ 62, 149, 130,  62],
    [149, 130,  62, 149],
    ..., 

当我将其分成各个通道时

ImageFileY = copy.deepcopy(ImageFileYCbCr) # to make a separate copy as array is immutable
ImageFileY[:,:,1] *= 0
ImageFileY[:,:,2] *= 0
ImageFileY[:,:,3] *= 0
ImageFileYOnly = Image.fromarray(ImageFileY)
ImageFileYOnly.show()

这导致了一个红色通道,就像是RGB一样。我该如何分别获取Y、Cb和Cr值?

编辑:Numpy版本为1.3,Python版本为2.6,操作系统为Linux Backtrack 5。


“...这不是我期望的,因为根据http://www.google.com/url?sa=t&rct=j中的文档说明不是这样的...” 那个链接带我到了一个空白页面。看着url=参数,我猜你想链接到这个pdf - Kevin
请看这里:https://dev59.com/hE3Sa4cB1Zd3GeqPxK2G,可能会有所帮助。 - pandita
哦,你说得对,Kevin。我会编辑它的。谢谢。 - 絢瀬絵里
如果我在图像上调用 getbands(),它会返回 ('Y', 'Cb', 'Cr'),而 getpixel((0,0)) 返回一个有 3 个成员的元组,这表明有 3 个波段。错误一定出现在转换为 numpy 的过程中。 - Mark Ransom
马克,有什么建议吗? - 絢瀬絵里
2个回答

10

https://mail.python.org/pipermail/image-sig/2010-October/006526.html

这是Numpy的一个旧bug。要修复它:

>>> import numpy
>>> import Image as im
>>> image = im.open('bush640x360.png')
>>> ycbcr = image.convert('YCbCr')

>>> B = numpy.ndarray((image.size[1], image.size[0], 3), 'u1', ycbcr.tostring())
>>> print B.shape
(360, 640, 3)
>>> im.fromarray(B[:,:,0], "L").show()

2
在 PIL 的后续版本中(1.1.7,可能更早),已删除 tostring() 方法,因此第 5 行应该是:B = numpy.ndarray((image.size[1], image.size[0], 3), 'u1', ycbcr.tobytes()) - 4Oh4

4

供Google的未来用户参考:

现在似乎可以运行。

我使用的是 Pillow 6.1.0 和 numpy 1.17.0。执行:

img = np.array(Image.open(p).convert('YCbCr'))

给出相同的结果

img = Image.open(p).convert('YCbCr')
img = np.ndarray((img.size[1], img.size[0], 3), 'u1', img.tobytes())

并且,它与RGB不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接