边缘情况下ycbcr到rgb颜色转换错误

2024-05-12 21:13:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我在将rgb照片转换为ycbcbr、修改y通道并转换回rgb时遇到了一些问题,通常它工作得很好,但对于某些边缘情况,它返回负值或大于255的值,因此当我将其转换回matplotlib的uint8时,它会显示亮点。在

RGB到YCbCr

def rgb2ycbcr(data):
    res = np.empty(data.shape)
    res[...,0] = (data[...,0] * 0.299 + data[...,1] * 0.587 + data[...,2] * 0.114)
    res[...,1] = 128 + (data[...,0] * -0.169 + data[...,1] * -0.331 + data[...,2] * 0.5)
    res[...,2] = 128 + (data[...,0] * 0.5 + data[...,1] * -0.419 + data[...,2] * -0.081)
    return res

以及YCbCr到RGB:

^{pr2}$

奇怪的是,当我不接触Y通道时,照片转换正常(我知道当我修改Y通道时,我会将值保持在范围内)


Tags: 亮点datamatplotlibdef情况resrgb照片
1条回答
网友
1楼 · 发布于 2024-05-12 21:13:00

由于精度问题,您将得到负值和大于1的值,因此您必须舍入/转换为整数:

RGB = np.asarray([[0, 0, 0], [255, 255, 255]])
print(rgb2ycbcr(ycbcr2rgb(RGB)))

[[-0.1423 0.6689 0.1714]
[255.1412 254.3363 254.8299]]

现在的一个主要问题是,您使用的常量舍入太多,与Recommendation ITU-T T.871不一致,因此根据4个小数舍入引用稍微调整代码:

^{pr2}$

您仍然需要转换为整数,但应该在一个更好的地方。 我注意到您正在修改dataycbcr2rgb中的适当位置,您应该在输入定义时复制一个数组,否则您将有非常严重的意外。在

我建议在不从Recommendation ITU-T T.871取整的情况下实现该版本。在

我们维护的Colour有一个非常solid and complete implementation of Y'CbCr,您可以使用它来验证您的计算:

RGB = np.asarray([[0, 0, 0], [255, 255, 255]])

print(colour.YCbCr_to_RGB(
    colour.RGB_to_YCbCr(
        RGB,
        K=colour.YCBCR_WEIGHTS['ITU-R BT.601'],
        in_bits=8,
        in_int=True,
        in_legal=False,
        out_bits=8,
        out_int=True,
        out_legal=True),
    K=colour.YCBCR_WEIGHTS['ITU-R BT.601'],
    in_bits=8,
    in_int=True,
    in_legal=True,
    out_bits=8,
    out_int=True,
    out_legal=False))

[[  0   0   0]
[255 255 255]]

我还建议使用BT.709权重,而不是ITU-T T.871/BT.601中的权重,前者更广泛。在

相关问题 更多 >