RGB与YUV相互转换

简介: 本文介绍YUV跟RGB互转的各种公式,以及推导原理

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

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

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

提取 Y 亮度信息的公式如下:Y = Kr * R + Kg * G + Kb * BY=KrR+KgG+KbB上面公式中的 K 是一个权重因子,Kr 代表 红色通道的权重,Kg 代表 绿色通道的权重,Kb 代表 蓝色通道的权重,这三个权重加起来等于 1,如下:Kr + Kg + Kb = 1Kr+Kg+Kb=1Cb 的定义是 B - Y 的差值,如下:Cb = B - YCb=BYCr 的定义是 R - Y 的差值,如下:Cr = R - YCr=RYCg 的定义是 G - Y 的差值,如下:Cg = G - YCg=GY上面的 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=RYR - Y = R - 0.299R - 0.587G - 0.114BRY=R0.299R0.587G0.114BR - Y = 0.701R - 0.587G - 0.114BRY=0.701R0.587G0.114B

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

R - Y = 0.701 = max\_valueRY=0.701=max_value

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

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

R - Y = -0.701 = min\_valueRY=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=(RY)/1.402

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


所以 Cb 的计算过程如下:Cb = B - YCb=BYB - Y = B - 0.299R - 0.587G - 0.114BBY=B0.299R0.587G0.114BB - Y = -0.299R - 0.587G + 0.886BBY=0.299R0.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 * 1BY=0.29900.5870+0.8861

B - Y = 0.886 = max\_valueBY=0.886=max_value

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

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

B - Y = -0.886 = min\_valueBY=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=(BY)/1.772

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

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


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

YCrCb 这 3个是已知值。

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

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

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

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

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

B = 1.772 * Cb + YB=1.772Cb+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.402Cr+Y)+0.587G+0.114(1.772Cb+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.587Y0.419Cr0.202Cb两边同时除以 0.587 ,如下:G = Y - 0.713Cr - 0.344CbG=Y0.713Cr0.344Cb


参考文章:

1,RGB转YUV及YUV格式

目录
相关文章
|
存储 编解码 Android开发
NV21、NV12、YV12、RGB、YUV、RGBA、RGBX8888等图像色彩编码格式区别
NV21、NV12、YV12、RGB、YUV、RGBA、RGBX8888都是常见的图像颜色编码格式,它们之间的主要区别在于色彩空间和数据排列方式。
208 0
|
编解码 API 开发工具
NV21、NV12、YV12、RGB565、YUV等颜色编码格式区别和接口设计探讨
NV21、NV12、YV12、RGB565、YUV分别是不同的颜色编码格式,这些颜色编码格式各有特点,适用于不同的应用场景。选择合适的颜色编码格式取决于具体的需求和环境:
228 1
FreeSwitch中,RGB颜色转换为YUV
FreeSwitch中,RGB颜色转换为YUV
88 0
CMKY与RGB的转换
CMKY与RGB的转换
105 0
RGB转换为NV12的代码
RGB转换为NV12的代码
247 0
YUV 与 RGB的转换
RGB 转换成 YUV Y = (0.257 * R) + (0.504 * G) + (0.
5421 0
|
编解码
理解 RGB & YUV 颜色编码
理解 RGB & YUV 颜色编码
458 0
理解 RGB & YUV 颜色编码
使用FFMPEG的sws_scale函数实现各种原始颜色格式互转(YUV\RGB\)
使用FFMPEG的sws_scale函数实现各种原始颜色格式互转(YUV\RGB\)
842 0
|
编解码 芯片