I’m confused with how to convert RGB to YCrCb

836 views Asked by At

Given that:

Y = 0.299R + 0.587G + 0.114B

What values do we put in for R,G, and B? I’m assuming 0-255. For arguments sake, if R, G, B are each 50, then does it mean Y=0.299(50) + 0.587(500) + 0.11(50)?

The next two are also confusing. How can B - Y even be possible if Y contains Blue then isn’t B - Y just taking away itself?

Cb = 0.564( B − Y ) Cr =0.713(R−Y)

2

There are 2 answers

0
Rotem On BEST ANSWER

It's just simple (confusing) math ...

Remark: There are few standards of YCbCr following formula applies BT.601, with "full range":

Equation (1): Y = 0.299R + 0.587G + 0.114B

The common definition of YCbCr assumes that R, G, and B are 8 bits unsigned integers in range [0, 255].
There are cases where R, G, B are floating point values in range [0, 1] (normalized values).
There are also HDR cases where range is [0, 1023] for example.

In case R=50, G=50, B=50, you just need to assign the values:
Y = 0.299*50 + 0.587*50 + 0.114*50
Result: Y = 50.

Since Y represents the Luma (line luminescence), and RGB=(50,50,50), is a gray pixel, it does make sense that Y = 50.


The following equations Cb = 0.564(B - Y), Cr = 0.713(R - Y) are incorrect.
Instead of Cb, and Cr they should be named Pb and Pr.

Equation (2): Pb = 0.564(B - Y)
Equation (3): Pr = 0.713(R - Y)

The equations mean that you can compute Y first, and then use the result for computing Pb and Pr.

Remark: don't round the value of Y when you are using it for computing Pb and Pr.

You can also assign Equation (1) in (2) and (3):
Pb = 0.564(B - Y) = 0.564(B - (0.299R + 0.587G + 0.114B)) = 0.4997*B - 0.3311*G - 0.1686*R

Pr = 0.713(R - Y) = 0.713(R - (0.299R + 0.587G + 0.114B)) = 0.4998*R - 0.4185*G - 0.0813*B

There are some small inaccuracies.
Wikipedia is more accurate (but still just a result of mathematical assignments):
Y = 0.299*R + 0.587*G + 0.114*B
Pb = -0.168736*R - 0.331264*G + 0.5*B
Pr = 0.5*R - 0.418688*G - 0.081312*B

In the above formulas the range of Pb, Pr is [-127.5, 127.5].

In the "full range" formula of YCbCr (not YPbPr), an offset of 128 is added to Pb and Pr (so result is always positive).
In case of 8 bits, the final result is limited to range [0, 255] and rounded.

0
Nviable On

What you're referencing is the conversion of RGB to YPbPr.

Conversion to YCbCr is as follows:

Y = 0.299 * R + 0.587 * G + 0.114 * B

Cb = -0.167 * R - 0.3313 * G - 0.5 * B + 128

Cr = 0.5 * R - 0.4187 * G - 0.0813 * B + 128

Yours is YPbPr (which is better for JPEG Compression, see below):

delta = 0.5

Y = 0.299 * R + 0.587 * G + 0.114 * B (same as above)

Pb: (B - Y) * 0.564 + delta

Pr: (B - Y) * 0.713 + delta

The above answer did a better job of explaining this.

I've been looking into JPEG Compression for implementation in Pytorch and found this thread (https://photo.stackexchange.com/a/8357) useful to explain why we use YPbPr for compression over YCbCr.

Pb and Pr versions are better for image compression because the luminance information (which contains the most detail) is retained in only one (Y) channel, while Pb and Pr would contain the chrominance information. Thus when you're doing down-sampling later down the line, there's less loss of valuable info.