Color Space Mapping YCbCr to RGB

16,086

You have to do your intermediate calculations in floating point. The posterization should tip you off; you have a lot of "hot" (saturated) pixels.

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)
Share:
16,086
yc2986
Author by

yc2986

Updated on June 20, 2022

Comments

  • yc2986
    yc2986 almost 2 years

    I am experimenting with JPEG compression using python. I load in a tiff image and store it as numpy uint8 RGB array. I was doing this for color mapping.

    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)
    

    I did a simple RGB to YCbCr transformation followed with a inverse transformation.

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

    I got these two output image as YCbCr and RGB output after the color space transformation. YCbCr RGB

    It seems that something is wrong with my color conversion and I cannot figure out what is wrong. I was using the JPEG color space conversion provided by Wikipedia. Thanks you for the help.