Converting Between RGB and YUV
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
As we saw earlier, all three RGB components are closely related to brightness; each contains a large amount of brightness information.
RGB-to-YUV conversion extracts the brightness information from the three RGB components and places it in Y. It then extracts hue and saturation information and places it in U and V.
This is therefore an information-extraction process based on extensive experiments.
The formula for extracting brightness Y is:
In this formula, K is a weighting factor. Kr is the weight of the red channel, Kg is the weight of the green channel, and Kb is the weight of the blue channel. The three weights sum to 1:
Cb is defined as the difference B - Y:
Cr is defined as R - Y:
Cg is defined as G - Y:
Cb above is the U component, and Cr is the V component. We do not need Cg when encoding, storing, or transmitting the data.
The formulas show that B can be recovered from Y and Cb, R from Y and Cr, and G from Y, R, and B using the first formula. Therefore Cg need not be stored or transmitted.
Additional knowledge: Cr + Cb + Cg is actually a constant.
The K weighting factors are determined through extensive experiments. Research found that they affect the compression ratio, which led to the following standards.
1. BT.601 [1] - standard-definition television (SDTV)
2. BT.709 [2] - high-definition television (HDTV)
3. BT.2020 [3] - ultra-high-definition television (UHDTV)
For various reasons, brightness cannot be extracted perfectly from RGB; some brightness information remains in the RGB components. Therefore the K factors differ between standards.
YUV data generated with BT.2020 has a lower compression ratio in an encoding system than data generated with BT.709. Although encoding has not yet begun at this stage, the K factors do affect the eventual compression result.
This article focuses on the formulas in the BT.601 standard.
According to ITU BT.601, Kb = 0.114 and Kr = 0.299, so Kg = 0.587. The formula for Y is:
The weights always sum to 1. This formula says that the R channel contains 29.9% brightness information, G contains 58.7%, and B contains 11.4%.
The derivation of Cr is:
Because R, G, and B range from 0 to 1, R - Y is largest at R = 1, G = 0, B = 0:
It is smallest at R = 0, G = 1, B = 1:
Thus the range of Cr is -0.701 ~ 0.701, with a width of 1.402. Since Cr must be transmitted together with Y, whose range has width 1, Cr = R - Y must be normalized by dividing by 1.402.
Therefore:
The derivation of Cb is:
B - Y is largest at R = 0, G = 0, B = 1:
It is smallest at R = 1, G = 1, B = 0:
The range of Cb is -0.886 ~ 0.886, with a width of 1.772. Since Y has a range width of 1, Cb = B - Y is normalized by dividing by 1.772:
Additional knowledge: YCbCr conversion also has approximate algorithms. Approximation can be used in some situations to improve calculation speed.
Now let us convert YCbCr back to RGB. The known values are Y, Cr, and Cb.
Since Cr = 0.713 * (R - Y), rearranging for R gives:
{% math %} R - Y = Cr /0.713 {% endmath %}
{% math %} R = 1/0.713 * Cr + Y {% endmath %}
{% math %} R = 1.402 * Cr + Y {% endmath %}
Since Cb = 0.564 * (B - Y), rearranging for B gives:
R and B are now known. Substitute them into:
Solving for G:
Dividing both sides by 0.587: