颜色空间映射:YCbCr 到 RGB

7
我正在使用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格式的。 YCbCr RGB 看起来我的颜色转换出了问题,但我无法确定具体哪里出错了。我使用了维基百科提供的JPEG色彩空间转换方法。 谢谢您的帮助。
1个回答

24

你需要使用浮点数进行中间计算。色彩分层应该会提示你,你有很多“热”(饱和)像素。

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)

我使用上述代码将一个彩色png图像转换,格式为(1000, 800, 3)。但是rgb2ycbcr返回的形状却是[1000, 3],而不是[1000, 800]。我开始怀疑自己哪里做错了,因为答案被标记为正确。 - partizanos
@emre,感谢您的回答。我想知道为什么要对xform转置进行点乘,而不是只对xform进行点乘。 - ozmank

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