Reputation: 11
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.
Upvotes: 1
Views: 1472
Reputation: 32124
You need to adjust the conversion formula to the range of RGB components:
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.
Upvotes: 0