从前文已经知道,R,G,B,3个分量都跟 亮度密切相关,也就是 3个分量里面都有大量的亮度信息。
RGB 转 YUV 的过程实际上就是 把 RGB 3分量里面的亮度信息 提取出来,放到 Y 分量。再把 RGB 3分量里面的 色调 ,色饱和度 信息提取出来放到 U跟 V分量。
所以这是一个信息提取过程,需要经过大量的实验。
提取 Y 亮度信息的公式如下:Y = Kr * R + Kg * G + Kb * BY=Kr∗R+Kg∗G+Kb∗B上面公式中的 K 是一个权重因子,Kr
代表 红色通道的权重,Kg
代表 绿色通道的权重,Kb
代表 蓝色通道的权重,这三个权重加起来等于 1,如下:Kr + Kg + Kb = 1Kr+Kg+Kb=1Cb
的定义是 B - Y 的差值,如下:Cb = B - YCb=B−YCr
的定义是 R - Y 的差值,如下:Cr = R - YCr=R−YCg
的定义是 G - Y 的差值,如下:Cg = G - YCg=G−Y上面的 Cb
就是 U 分量,Cr
是 V 分量。我们实际编码存储,或者传输的时候,是不需要用到 Cg
的。
从上面的公式可以看出,只需要知道 Y 跟 Cb
就能求 B 的值,知道 Y 跟 Cr
就能求 R 的值。知道 Y ,R 跟 B 就能根据第一条公式求到 G 的值。所以 Cg
没必要存储或者传输。
扩展知识:Cr
+ Cb
+ Cg
其实是一个常量。
因为 K 权重因子是需要经过大量的实验才能得到,经过实验研究后发现,K 权重因子 会影响压缩率,所以产生了以下标准。
1. BT.601标准[1]——标清数字电视(SDTV)Y = 0.299R + 0.587G + 0.114BY=0.299R+0.587G+0.114B2. BT.709标准[2]——高清数字电视(HDTV)Y = 0.2126R + 0.7152G + 0.0722BY=0.2126R+0.7152G+0.0722B3. BT.2020标准[3]——超高清数字电视(UHDTV)Y = 0.2627R + 0.6780G + 0.0593BY=0.2627R+0.6780G+0.0593B因为某些原因,亮度这个信息,不能完完全全 从 RGB 里面提取出来,总会残留一些亮度信息在 RGB 里面没提取到。所以 K 权重因子 根据不同标准也是不同的。
BT.2020标准 生成的 YUV 数据在 编码系统里面的压缩率 是比 BT.709 小的,虽然现在还没开始进行编码压缩,但是确确实实,K权重因子会影响压缩效果。
本文主要讲解的是 BT.601 标准里面的计算公式。
根据 ITU BT.601 标准 的定义,Kb = 0.114 ,Kr = 0.299 ,所以 Kg = 0.587 ,Y 的计算公式如下:Y = 0.299R + 0.587G + 0.114BY=0.299R+0.587G+0.114B可以这么理解上面这个公式,Kr + Kg + Kb 一定是等于1的。上面这个公式认为,在 R 通道里面有 29.9% 的亮度信息,在 G通道 有 58.7% 的亮度信息,在 B通道 有 11.4% 的亮度信息。
所以 Cr
的计算过程如下:Cr = R - YCr=R−YR - Y = R - 0.299R - 0.587G - 0.114BR−Y=R−0.299R−0.587G−0.114BR - Y = 0.701R - 0.587G - 0.114BR−Y=0.701R−0.587G−0.114B
由于 R,G,B 的取值范围是 0 ~ 1,所以当 R = 1,G = 0,B = 0 时,R - Y 能得到最大的值,如下:R - Y = 0.701 * 1 - 0.587 * 0 - 0.114 * 0R−Y=0.701∗1−0.587∗0−0.114∗0
R - Y = 0.701 = max\_valueR−Y=0.701=max_value
当 R = 0,G = 1,B = 1时,R - Y 能得到最小的值,如下:
R - Y = 0.701 * 0 - 0.587 * 1 - 0.114 * 1R−Y=0.701∗0−0.587∗1−0.114∗1
R - Y = -0.701 = min\_valueR−Y=−0.701=min_value
因此 Cr
的空间范围是 -0.701 ~ 7.01
,范围大小是 1.402,但是由于 Cr
需要跟 Y 一起传输,而 Y 的空间范围大小是 1。
所以 Cr = R - Y
要做归一化操作,就是除以 1.402。
所以就有下面的公式了:Cr = (R - Y)/1.402Cr=(R−Y)/1.402
Cr = 0.713 * (R - Y)Cr=0.713∗(R−Y)
所以 Cb
的计算过程如下:Cb = B - YCb=B−YB - Y = B - 0.299R - 0.587G - 0.114BB−Y=B−0.299R−0.587G−0.114BB - Y = -0.299R - 0.587G + 0.886BB−Y=−0.299R−0.587G+0.886B
由于 R,G,B 的取值范围是 0 ~ 1,所以当 R = 0,G = 0,B = 1 时,B - Y 能得到最大的值,如下:B - Y = -0.299 * 0 - 0.587 * 0 + 0.886 * 1B−Y=−0.299∗0−0.587∗0+0.886∗1
B - Y = 0.886 = max\_valueB−Y=0.886=max_value
当 R = 1,G = 1,B = 0 时,B - Y 能得到最小的值,如下:
B - Y = -0.299 * 1 - 0.587 * 1 + 0.886 * 0B−Y=−0.299∗1−0.587∗1+0.886∗0
B - Y = -0.886 = min\_valueB−Y=−0.886=min_value
因此 Cb
的空间范围是 -0.886 ~ 0.886
,范围大小是 1.772,但是由于 Cb
需要跟 Y 一起传输,而 Y 的空间范围大小是 1。
所以 Cb = B - Y
要做归一化操作,就是除以 1.772。
所以就有下面的公式了:Cb = (B - Y)/1.772Cb=(B−Y)/1.772
Cb = 0.564 * (B - Y)Cb=0.564∗(B−Y)
扩展知识:YCrCb 的转换算法,其实是有近似算法的,为了计算速度,某些场景可以使用近似算法。
下面讲一下 如何 把 YCrCb
转成 RGB
。
Y
,Cr
跟 Cb
这 3个是已知值。
因为 Cr = 0.713 * (R - Y)
,所以换算一下,把R 弄到前面,如下:R - Y = Cr /0.713R−Y=Cr/0.713
R = 1/0.713 * Cr + YR=1/0.713∗Cr+Y
R = 1.402 * Cr + YR=1.402∗Cr+Y
因为 Cb = 0.564 * (B - Y)
,所以换算一下,把 B 弄到前面,如下:B = Cb/0.546 + YB=Cb/0.546+Y
B = 1/0.564 * Cb + YB=1/0.564∗Cb+Y
B = 1.772 * Cb + YB=1.772∗Cb+Y
至此, R 跟 B 已经求出来了。把R 跟 B 套进去以下公式:Y = 0.299R + 0.587G + 0.114BY=0.299R+0.587G+0.114B
Y = 0.299*( 1.402 * Cr + Y) + 0.587G + 0.114 * (1.772 * Cb + Y)Y=0.299∗(1.402∗Cr+Y)+0.587G+0.114∗(1.772∗Cb+Y)
Y = (0.419Cr + 0.299Y) + 0.587G + (0.202Cb + 0.114Y)Y=(0.419Cr+0.299Y)+0.587G+(0.202Cb+0.114Y)
Y = 0.419Cr + 0.587G + 0.202Cb + 0.413YY=0.419Cr+0.587G+0.202Cb+0.413Y
0.587Y = 0.419Cr + 0.587G + 0.202Cb0.587Y=0.419Cr+0.587G+0.202Cb
推导到这里,把 G 弄到前面,如下:0.587G = 0.587Y - 0.419Cr - 0.202Cb0.587G=0.587Y−0.419Cr−0.202Cb两边同时除以 0.587 ,如下:G = Y - 0.713Cr - 0.344CbG=Y−0.713Cr−0.344Cb
参考文章: