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
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
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
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);
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 :)