一、 YUV 与 RGB 之间的转换
YUV 与 RGB 颜色格式之间进行转换时 , 涉及一系列的数学运算 ;
YUV 颜色编码格式 转为 RGB 格式 的 转换公式 取决于 于 YUV 的具体子采样格式 :
- YUV444
- YUV422
- YUV420
1、YUV444 颜色编码格式 转为 RGB 格式
YUV444 格式 转为 RGB 格式 的 转换公式如下 :
- R = Y 1.13983 * (V - 128)
- G = Y - 0.39465 * (U - 128) - 0.58060 * (V - 128)
- B = Y 2.03211 * (U - 128)
UV 色度值 分量 减去 128 , 是因为 这两个分量 都是从 中心值 ( 256 / 2 = 128 ) 进行偏移的 , 计算时 需要 先将这个偏移量减去 , 然后将其转换到正确的范围中 ;
上述 计算 的 颜色 位深度 是 8 bit , 也就是 1 字节 , 取值范围是 0 ~ 255 , 有 256 个值 , 128 的偏移量也就是这个值的中间值 ;
如果计算出来的 RGB 分量 小于 0 , 则 取 0 值 ;
如果计算出来的 RGB 分量 大于 255 , 则 取 255 ;
如果 YUV 解码错误 , 导致 三个分量的值都是 0 , 则最终计算时 , 得到如下 3 个 RGB 分量值 ;
计算出来的 RGB 分量 小于 0 , 则 取 0 值 , 因此 R 和 B 分量都是 0 , 只有 G 的分量是 135.45984 , 屏幕显示绿色 ;
2、RGB 颜色编码格式 转为 YUV444 格式
RGB 格式 转为 YUV444 格式 的 转换公式如下 :
- Y = 0.299 * R 0.587 * G 0.114 * B
- U = -0.14713 * R - 0.28886 * G 0.436 * B 128
- V = 0.615 * R - 0.51498 * G - 0.10001 * B 128
UV 分量 在 计算后 增加一个 中间值 偏移量 , 这个中间值一般是 256 的一半 128 , 确保 UV 值在合适范围之内 ;
上述 计算 的 颜色 位深度 是 8 bit , 也就是 1 字节 , 取值范围是 0 ~ 255 , 有 256 个值 , 128 的偏移量也就是这个值的中间值 ;
3、YUV 格式各分量的取值范围
广播电视标准 : BT601 标准 , BT709 标准 , BT2020 标准 ;
- Y 分量取值范围 : 16 ~ 235 ;
- UV 分量取值范围 : 16 ~ 240 ;
在 FFmpeg 中 , 这种范围称为 " MPEG 范围 "
这类标准是 在 电视信号 中使用的 ;
计算机标准 : 在 FFmpeg 中, 这种范围称为 " JPEG 范围 " ;
- YUV 分量取值范围 : 0 ~ 255 ;
这类 标准 是在 计算机 中使用的 ;
4、转换函数库
实际使用时 , RGB 与 YUV 编码格式转换 , 都是调用接口实现 , 如 FFmpeg 的 swscale 库 , 或者 libyuv 库 ;
- FFmpeg 的 swscale 库 是用于图像缩放和像素格式转换的库 , 该函数库 提供了 高度优化的函数 , 用于在不同的像素格式之间进行转换 , 以及进行图像的大小调整 ;
- libyuv 库 是 Google 提供的一个用于处理 YUV 和 RGB 图像数据之间转换的跨平台库 , 该函数库 支持各种 YUV 格式与 RGB 格式之间的相互转换 , 以及图像的缩放、旋转和裁剪等操作 ;