RGB与YUV相互转换—音视频基础知识

作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音

从前文已经知道,R,G,B,3个分量都跟 亮度密切相关,也就是 3个分量里面都有大量的亮度信息。

RGB 转 YUV 的过程实际上就是 把 RGB 3分量里面的亮度信息 提取出来,放到 Y 分量。再把 RGB 3分量里面的 色调 ,色饱和度 信息提取出来放到 U跟 V分量。

所以这是一个信息提取过程,需要经过大量的实验。

提取 Y 亮度信息的公式如下: Y=KrR+KgG+KbB Y = Kr * R + Kg * G + Kb * B 上面公式中的 K 是一个权重因子,Kr 代表 红色通道的权重,Kg 代表 绿色通道的权重,Kb 代表 蓝色通道的权重,这三个权重加起来等于 1,如下: Kr+Kg+Kb=1 Kr + Kg + Kb = 1 Cb 的定义是 B - Y 的差值,如下: Cb=BY Cb = B - Y Cr 的定义是 R - Y 的差值,如下: Cr=RY Cr = R - Y Cg 的定义是 G - Y 的差值,如下: Cg=GY Cg = 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.114B Y = 0.299R + 0.587G + 0.114B 2. BT.709标准[2]——高清数字电视(HDTV) Y=0.2126R+0.7152G+0.0722B Y = 0.2126R + 0.7152G + 0.0722B 3. BT.2020标准[3]——超高清数字电视(UHDTV) Y=0.2627R+0.6780G+0.0593B Y = 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.114B Y = 0.299R + 0.587G + 0.114B 可以这么理解上面这个公式,Kr + Kg + Kb 一定是等于1的。上面这个公式认为,在 R 通道里面有 29.9% 的亮度信息,在 G通道 有 58.7% 的亮度信息,在 B通道 有 11.4% 的亮度信息。


所以 Cr 的计算过程如下: Cr=RY Cr = R - Y RY=R0.299R0.587G0.114B R - Y = R - 0.299R - 0.587G - 0.114B RY=0.701R0.587G0.114B R - Y = 0.701R - 0.587G - 0.114B

由于 R,G,B 的取值范围是 0 ~ 1,所以当 R = 1,G = 0,B = 0 时,R - Y 能得到最大的值,如下: RY=0.70110.58700.1140 R - Y = 0.701 * 1 - 0.587 * 0 - 0.114 * 0

RY=0.701=max_value R - Y = 0.701 = max\_value

当 R = 0,G = 1,B = 1时,R - Y 能得到最小的值,如下:

RY=0.70100.58710.1141 R - Y = 0.701 * 0 - 0.587 * 1 - 0.114 * 1

RY=0.701=min_value R - Y = -0.701 = min\_value

因此 Cr 的空间范围是 -0.701 ~ 0.701,范围大小是 1.402,但是由于 Cr 需要跟 Y 一起传输,而 Y 的空间范围大小是 1。

所以 Cr = R - Y 要做归一化操作,就是除以 1.402。

所以就有下面的公式了: Cr=(RY)/1.402 Cr = (R - Y)/1.402

Cr=0.713(RY) Cr = 0.713 * (R - Y)


所以 Cb 的计算过程如下: Cb=BY Cb = B - Y BY=B0.299R0.587G0.114B B - Y = B - 0.299R - 0.587G - 0.114B BY=0.299R0.587G+0.886B B - Y = -0.299R - 0.587G + 0.886B

由于 R,G,B 的取值范围是 0 ~ 1,所以当 R = 0,G = 0,B = 1 时,B - Y 能得到最大的值,如下: BY=0.29900.5870+0.8861 B - Y = -0.299 * 0 - 0.587 * 0 + 0.886 * 1

BY=0.886=max_value B - Y = 0.886 = max\_value

当 R = 1,G = 1,B = 0 时,B - Y 能得到最小的值,如下:

BY=0.29910.5871+0.8860 B - Y = -0.299 * 1 - 0.587 * 1 + 0.886 * 0

BY=0.886=min_value B - Y = -0.886 = min\_value

因此 Cb 的空间范围是 -0.886 ~ 0.886,范围大小是 1.772,但是由于 Cb 需要跟 Y 一起传输,而 Y 的空间范围大小是 1。

所以 Cb = B - Y 要做归一化操作,就是除以 1.772。

所以就有下面的公式了: Cb=(BY)/1.772 Cb = (B - Y)/1.772

Cb=0.564(BY) Cb = 0.564 * (B - Y)

扩展知识:YCbCr 的转换算法,其实是有近似算法的,为了计算速度,某些场景可以使用近似算法。


下面讲一下 如何 把 YCbCr 转成 RGB

YCrCb 这 3个是已知值。

因为 Cr = 0.713 * (R - Y) ,所以换算一下,把R 弄到前面,如下: RY=Cr/0.713 R - Y = Cr /0.713

R=1/0.713Cr+Y R = 1/0.713 * Cr + Y

R=1.402Cr+Y R = 1.402 * Cr + Y

因为 Cb = 0.564 * (B - Y) ,所以换算一下,把 B 弄到前面,如下: B=Cb/0.546+Y B = Cb/0.546 + Y

B=1/0.564Cb+Y B = 1/0.564 * Cb + Y

B=1.772Cb+Y B = 1.772 * Cb + Y

至此, R 跟 B 已经求出来了。把R 跟 B 套进去以下公式: Y=0.299R+0.587G+0.114B Y = 0.299R + 0.587G + 0.114B

Y=0.299(1.402Cr+Y)+0.587G+0.114(1.772Cb+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.413Y Y = 0.419Cr + 0.587G + 0.202Cb + 0.413Y

0.587Y=0.419Cr+0.587G+0.202Cb 0.587Y = 0.419Cr + 0.587G + 0.202Cb

推导到这里,把 G 弄到前面,如下: 0.587G=0.587Y0.419Cr0.202Cb 0.587G = 0.587Y - 0.419Cr - 0.202Cb 两边同时除以 0.587 ,如下: G=Y0.713Cr0.344Cb G = Y - 0.713Cr - 0.344Cb


参考文章:

1,RGB转YUV及YUV格式



感谢 NETINT(镕铭微电子) 赞助《FFmpeg原理》免费版一书的服务器费用,下面是 VPU 产品介绍

版权所属 xianwanzhiyin.net 罗上文 2024 all right reserved,powered by Gitbook该文件修订时间: 2023-07-24 09:40:02

results matching ""

    No results matching ""