【问题标题】:Color Space Mapping YCbCr to RGB将 YCbCr 映射到 RGB 的色彩空间
【发布时间】:2016-04-27 01:32:13
【问题描述】:

我正在尝试使用 python 进行 JPEG 压缩。我加载 tiff 图像并将其存储为 numpy uint8 RGB 数组。我这样做是为了颜色映射。

def rgb2ycbcr(im):
    cbcr = np.empty_like(im)
    r = im[:,:,0]
    g = im[:,:,1]
    b = im[:,:,2]
    # Y
    cbcr[:,:,0] = .299 * r + .587 * g + .114 * b
    # Cb
    cbcr[:,:,1] = 128 - .169 * r - .331 * g + .5 * b
    # Cr
    cbcr[:,:,2] = 128 + .5 * r - .419 * g - .081 * b
    return np.uint8(cbcr)

def ycbcr2rgb(im):
    rgb = np.empty_like(im)
    y   = im[:,:,0]
    cb  = im[:,:,1] - 128
    cr  = im[:,:,2] - 128
    # R
    rgb[:,:,0] = y + 1.402 * cr
    # G
    rgb[:,:,1] = y - .34414 * cb - .71414 * cr
    # B
    rgb[:,:,2] = y + 1.772 * cb
    return np.uint8(rgb)

我做了一个简单的 RGB 到 YCbCr 的转换,然后是一个逆变换。

img = rgb2ycbcr(img)
imshow(img)
img = ycbcr2rgb(img)
imshow(img)

在色彩空间转换后,我将这两个输出图像分别作为 YCbCr 和 RGB 输出。

我的颜色转换似乎有问题,我无法弄清楚哪里出了问题。我正在使用由提供的 JPEG 颜色空间转换 Wikipedia。谢谢你的帮助。

【问题讨论】:

    标签: python image jpeg color-mapping


    【解决方案1】:

    您必须使用浮点数进行中间计算。分派应该给你提示;你有很多“热”(饱和)像素。

    def rgb2ycbcr(im):
        xform = np.array([[.299, .587, .114], [-.1687, -.3313, .5], [.5, -.4187, -.0813]])
        ycbcr = im.dot(xform.T)
        ycbcr[:,:,[1,2]] += 128
        return np.uint8(ycbcr)
    
    def ycbcr2rgb(im):
        xform = np.array([[1, 0, 1.402], [1, -0.34414, -.71414], [1, 1.772, 0]])
        rgb = im.astype(np.float)
        rgb[:,:,[1,2]] -= 128
        rgb = rgb.dot(xform.T)
        np.putmask(rgb, rgb > 255, 255)
        np.putmask(rgb, rgb < 0, 0)
        return np.uint8(rgb)
    

    【讨论】:

    • 问题我使用上面的方法来转换格式为 (1000, 800, 3) 的彩色 png 图像。但随后 rgb2ycbcr 返回形状 [1000, 3 ] 而不是 [1000,800]。我怀疑我做错了什么,因为答案被标记为正确。
    • @emre,感谢您的回答,想知道您为什么点乘 xform 转置而不仅仅是 xform