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格式

目录
相关文章
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
860 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
Shell Android开发
Android系统 adb shell push/pull 禁止特定文件
Android系统 adb shell push/pull 禁止特定文件
1328 1
|
监控
zabbix关于Utilization of trapper processes over报警的处理及优化
zabbix关于Utilization of trapper processes over报警的处理及优化
1717 0
zabbix关于Utilization of trapper processes over报警的处理及优化
|
SQL 存储 分布式计算
【收藏】MongoDB 常用查询语句汇总
【收藏】MongoDB 常用查询语句汇总
1747 0
|
6月前
|
监控 算法 关系型数据库
分布式事务难题终结:Seata+DRDS全局事务一致性架构设计
在分布式系统中,CAP定理限制了可用性、一致性与分区容错的三者兼得,尤其在网络分区时需做出取舍。为应对这一挑战,最终一致性方案成为常见选择。以电商订单系统为例,微服务化后,原本的本地事务演变为跨数据库的分布式事务,暴露出全局锁失效、事务边界模糊及协议差异等问题。本文深入探讨了基于 Seata 与 DRDS 的分布式事务解决方案,涵盖 AT 模式实践、分片策略优化、典型问题处理、性能调优及高级特性实现,结合实际业务场景提供可落地的技术路径与架构设计原则。通过压测验证,该方案在事务延迟、TPS 及失败率等方面均取得显著优化效果。
339 61
|
机器人 C++ Python
ROS2教程 02 功能包
本文是关于ROS2(机器人操作系统2)中功能包(package)管理的教程,介绍了如何检查功能包的依赖、创建新功能包、列出可执行文件、列出所有功能包、查询功能包的位置和描述信息,以及为C++和Python功能包配置必要的文件。
559 0
|
存储 自然语言处理 监控
【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
Unity的多语言本地化是一个很实用的功能,它可以帮助游戏支持多种语言,让不同语言的玩家都能够更好地体验游戏。 而实现本地化的方案也有很多种,各个方案之间也各有优劣,后面也会对多个方案进行介绍学习。 本文就来介绍一个专门作用于多语言本地化的Unity官方插件:Localization 。 这个插件方便进行游戏的多语言本地化,让游戏支持多种语言,下面就来看看该插件的使用方法吧!
|
SQL 存储 数据库
SQL语句给予用户权限:技巧、方法与最佳实践
在数据库管理中,为用户分配适当的权限是确保数据安全性和操作效率的关键步骤
YUV 与 RGB的转换
RGB 转换成 YUV Y = (0.257 * R) + (0.504 * G) + (0.
6083 0

热门文章

最新文章