Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Converting RGB / YBR back and forth

859 views
Skip to first unread message

mathieu

unread,
Sep 9, 2008, 12:07:33 PM9/9/08
to
Hi there,

I am trying to convert back n' forth rgb values to ybr and then back
again to rgb. Comparing the value to the original ones gives me some
error. Could someone please let me know if I have my equation correct:

Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128
Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128

and then back to rgb:

R = Y + 1.40200 * Cr
G = Y - 0.34414 * Cb - 0.71414 * Cr
B = Y + 1.77200 * Cb

For instance computing for rgb=(255,0,255) => 105.315,212.471,234.766
=> (255.001,-0.000788715,254.998)

I understand that this conversion is supposed to be done using
integer, but then what are the proper conversion routine (C) to be
able to find back the original result ?

thanks

Thomas Richter

unread,
Sep 10, 2008, 3:34:39 AM9/10/08
to
mathieu schrieb:

> Hi there,
>
> I am trying to convert back n' forth rgb values to ybr and then back
> again to rgb. Comparing the value to the original ones gives me some
> error. Could someone please let me know if I have my equation correct:
>
> Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
> Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128
> Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128
>
> and then back to rgb:
>
> R = Y + 1.40200 * Cr
> G = Y - 0.34414 * Cb - 0.71414 * Cr
> B = Y + 1.77200 * Cb


Here, in the backwards transformation, you first have to subtract 128
again from Cb and Cr (if unsigned chroma is your convention, that is.
Otherwise, strip the +128 above). I also have 0.34413 as coefficient in
G in front of Cb, but it hardly should make any difference.

> For instance computing for rgb=(255,0,255) => 105.315,212.471,234.766
> => (255.001,-0.000788715,254.998)
>
> I understand that this conversion is supposed to be done using
> integer, but then what are the proper conversion routine (C) to be
> able to find back the original result ?

Well, no, this conversion isn't integer, it is in floating point. What
you can do is to approximate it in fix-point.

So long,
Thomas

mathieu

unread,
Sep 10, 2008, 5:53:43 AM9/10/08
to
On Sep 10, 9:34 am, Thomas Richter <t...@math.tu-berlin.de> wrote:
> mathieu schrieb:
>
> > Hi there,
>
> > I am trying to convert back n' forth rgb values to ybr and then back
> > again to rgb. Comparing the value to the original ones gives me some
> > error. Could someone please let me know if I have my equation correct:
>
> > Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
> > Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128
> > Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128
>
> > and then back to rgb:
>
> > R = Y + 1.40200 * Cr
> > G = Y - 0.34414 * Cb - 0.71414 * Cr
> > B = Y + 1.77200 * Cb
>
> Here, in the backwards transformation, you first have to subtract 128
> again from Cb and Cr (if unsigned chroma is your convention, that is.
> Otherwise, strip the +128 above). I also have 0.34413 as coefficient in
> G in front of Cb, but it hardly should make any difference.
>

it is !

before:
nerrors=16726921
sdiff=19792.6
max=0.00350702
max error=255,0,255
max error2=255.001,-0.000788715,254.998
max yerror=105.315,212.471,234.766


after:
nerrors=16726921
sdiff=17550
max=0.0027743
max error=255,0,255
max error2=255.001,5.5998e-05,254.998
max yerror=105.315,212.471,234.766

number of errors remains the same, but the abs value of all errors is
slightly lower.

> > For instance computing for rgb=(255,0,255) => 105.315,212.471,234.766
> > => (255.001,-0.000788715,254.998)
>
> > I understand that this conversion is supposed to be done using
> > integer, but then what are the proper conversion routine (C) to be
> > able to find back the original result ?
>
> Well, no, this conversion isn't integer, it is in floating point. What
> you can do is to approximate it in fix-point.

When you are doing integer computation you have sometime to do
operation like this:

interger1 * 1./ 3 -> floating point -> floating point * 3. ->
integer2

if you forger to add +0.5 to your floating point operation integer2 !=
integer1.

So basically I can reformulate my question into:
- what are the correct equation to user when doing the transformation
using integer type ? Are some kind of precomputed table available ?

Thanks

mathieu

unread,
Sep 10, 2008, 6:12:45 AM9/10/08
to


and a much better transformation is the following:

const double Y = .2990 * R + .5870 * G + .1140 * B;
const double CB = -.168736 * R - .331264 * G + .5000 * B + 128;
const double CR = .5000 * R - .418688 * G - .081312 * B + 128;

const double R = Y + 1.402 * (Cr-128);
const double G = Y - 0.344136 * (Cb-128) - 0.714136 * (Cr-128);
const double B = Y + 1.772 * (Cb-128);


ref:
http://en.wikipedia.org/wiki/YCbCr

mathieu

unread,
Sep 10, 2008, 6:58:59 AM9/10/08
to

for ref:

http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.txt

30. HOW DO I ENCODE Y'CBCR COMPONENTS FROM COMPUTER R'G'B' ?

In computing it is conventional to use eight-bit coding with black at
code 0
and white at 255. To encode Y'CBCR from R'G'B' in the range [0..255],
using
eight-bit binary arithmetic, scale the Y'CBCR matrix of Eq 3 by
256/255:

{{ 65.738, 129.057, 25.064},
{ -37.945, -74.494, 112.439},
{ 112.439, -94.154, -18.285}}

The entries in this matrix have been scaled up by 256, assuming that
you will
implement the equation in fixed-point binary arithmetic, using a shift
by eight
bits. Add [16, 128, 128] to the product to get Y'CBCR.

To decode R'G'B' in the range [0..255] from Rec. 601 Y'CBCR, using
eight-bit binary arithmetic , subtract [16, 128, 128] from Y'CBCR,
then multiply by the inverse of the matrix above, scaled by 256:

Eq 4

{{ 298.082, 0. , 408.583},
{ 298.082, -100.291, -208.12 },
{ 298.082, 516.411, 0. }}

You can remove a factor of 1/256 from these coefficients, then
accomplish the
multiplication by shifting. Some of the coefficients, when scaled by
256, are
larger than unity. These coefficients will need more than eight
multiplier
bits.

For implementation in binary arithmetic the matrix coefficients have
to be
rounded. When you round, take care to preserve the row sums of [1, 0,
0].

The matrix of Eq 4 will decode standard Y'CBCR components to RGB
components in the range [0..255], subject to roundoff error. You must
take
care to avoid overflow due to roundoff error. But you must protect
against
overflow in any case, because studio video signals use the extremes of
the
coding range to handle signal overshoot and undershoot, and these will
require clipping when decoded to an RGB range that has no headroom or
footroom.

That's all I needed :)

0 new messages