Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color Space Mapping YCbCr to RGB

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.

like image 899
yc2986 Avatar asked Jan 20 '16 23:01

yc2986


People also ask

How do you convert YCbCr to RGB?

RGB = ycbcr2rgb( YCBCR ) converts the luminance (Y) and chrominance (Cb and Cr) values of a YCbCr image to red, green, and blue values of an RGB image.

Why RGB is converted to YCbCr?

Image and Video consumes a lot of data. One of the reasons is because they are represented in the RGB format. However, is not worth to store or transmit information in this color space representaion, once it has a large bandwidth. Thus all the pixels should be converted to YCbCr to accomplish that.

Is YCbCr better than RGB?

The main difference between RGB and YCbCr444 is that RGB can display darker and brighter scenes better than YCbCr444. In YCbCr, Y means brightness (Luma), Cb means blue minus brightness (B-Y), and Cr means red minus brightness(R-Y), while 444 is similar to RGB, theoretically.

Is YCbCr same as RGB?

The difference between YCbCr and RGB is that YCbCr represents color as brightness and two color difference signals, while RGB represents color as red, green and blue. In YCbCr, the Y is the brightness (luma), Cb is blue minus luma (B-Y) and Cr is red minus luma (R-Y).


1 Answers

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)
like image 59
Emre Avatar answered Sep 18 '22 18:09

Emre