How to convert Y Cb Cr to RGB in MATLAB manually?

1.3k Views Asked by At

I've been tasked with performing a 4:2:0 chroma subsampling (color compression) on a series of JPEGs.

The first step is to ensure that I can generate my Y, Cb, and Cr values and then convert back to RGB and display the image. Then I can go back and add my subsampling logic.

I'm pretty sure that I have the right formulas for generating the Y, Cb, and Cr values but I cannot figure out the correct way to return to RGB and print.
We are not allowed to use any built in functions (which is what normally shows up in help to this problem).

I've attached code of how I'm getting my Y Cb and Cr values and how I'm trying to get back to RGB.
Currently, I get a green screen when running "imshow" on newImage after this excerpt.

%Obtain R,G,B values
R=double(orig(:,:,1))./255;
G=double(orig(:,:,2))./255;
B=double(orig(:,:,3))./255;

%Calculate Y,Cb, Cr values
Y = (0.299*R) + (0.587*G) + (0.114*B) + 0;
Cb = (-0.168736*R) + (-0.331264*G) + (0.5*B) + 0.5;
Cr = (0.5*R) + (-0.418688*G) - (0.081312*B) + 0.5;

%Calculate new R,G,B
new_R = Y + (1.402*(Cr-128));
new_G = Y-(0.34414*(Cb-128))-(0.71414*(Cr-128));
new_B = Y+(1.772*(Cb-128));

%Fill new Image
newImage(:,:,1) =double(new_R).*255;
newImage(:,:,2) = double(new_G).*255;
newImage(:,:,3) = double(new_B).*255;

Where orig is the original image and newImage is what I'm running "imshow" on right after this excerpt.

1

There are 1 best solutions below

0
On

You need to adjust the conversion formula to the range of RGB components:

  • If color components range is [0, 255], you need to add 128 to Cb, Cr when converting RGB to YCbCr (and subtract 128 when converting back).
  • If color components range is [0, 1], you need to add (or subtract) 0.5

In your post you are using range [0, 1] for converting RGB to YCbCr, but the formula you are using to convert back from YCbCr to RGB matches range [0, 255] (you are subtracting 128).

You may fix it by subtracting 0.5 instead of 128.

Example:

%Sample values for testing (in range [0, 1]):
R = 0.3;
G = 0.6;
B = 0.8;

%Calculate Y,Cb, Cr values
Y = (0.299*R) + (0.587*G) + (0.114*B) + 0;
Cb = (-0.168736*R) + (-0.331264*G) + (0.5*B) + 0.5;
Cr = (0.5*R) + (-0.418688*G) - (0.081312*B) + 0.5;

%Calculate new R,G,B
new_R = Y + (1.402*(Cr-0.5));
new_G = Y-(0.34414*(Cb-0.5))-(0.71414*(Cr-0.5));
new_B = Y+(1.772*(Cb-0.5));

display([new_R, new_G, new_B])

Result:

0.3000    0.6000    0.8000

As you can see, new RGB equals original RGB values.