音视频开发笔记

WebRTC 视频基础之一: YUV 格式

2021-09-05  本文已影响0人  老瓦在霸都

图像格式

最简单的图像格式是 RGB24, 每个像素用24bits 来表示,三原色的每个颜色用 8 bits 来表示,如果还要表示像素的透明度,就再加 8 bits ,即 RGB32 格式

RGB

这样一个 RGB24 图片可以用一个三维数组来表示,前两个维度表示图像的空间位置,最后一个维度表示颜色

YUV 则是另一种格式,Y 表示亮度,U 表示色度,V 表示浓度, 按照公式,可以把 RGB 转换成 YUV 格式

YCbCr 其实是 YUV 经过缩放和偏移的翻版。其中 Y 与 YUV 中的 Y 含义一致,Cb,Cr 同样都指色彩,只是在表示方法上不同而已。YCbCr 其中 Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量。

常用的格式有

如图所示

在 YUV 格式的图像中,以实心圆代表 Y 分量, 空心圆代表 U 或 V 分量,其采样如下

下面详细说说

YUV 4:4:4

YUV 4:4:4 表示 Y、U、V 三分量采样率相同,即每个像素的三分量信息完整,都是 8bit,每个像素占用 3 个字节。

YUV 4:2:2

YUV 4:2:2 表示 UV 分量的采样率是 Y 分量的一半

YUV 4:2:0

YUV4:2:0并不是说只有U, V一定为0,而是指U:V互相援引,时见时隐,也就是说对于每一个行,只有一个U或者V分量,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0...以此类推。

[Y0 U0 V0]、[Y1 U1 V1]、 [Y2 U2 V2]、 [Y3 U3 V3]
[Y4 U4 V4]、[Y5 U5 V5]、 [Y6 U6 V6] 、[Y7 U7 V7]
Y0 U0 Y1 Y2 U2 Y3 
Y4 V4 Y5 Y6 V6 Y7
[Y0 U0 V4]、[Y1 U0 V4]、[Y2 U2 V6]、[Y3 U2 V6]
[Y4 U0 V4]、[Y5 U0 V4]、[Y6 U2 V6]、[Y7 U2 V6]


Y0, Y1, Y4, Y5 共用 U0, V4

Y2, Y3, Y6, Y7 共用 U2, V6

YUV 图像的存储格式

YUV 的存储格式有以下三种

  1. 紧缩格式 Packed (or 交织格式)
  2. 平面格式 Planar (这种格式的名称常带着字母 "p")
  3. 半平面格式 Semi-planar (这种格式的名称常带着字母 "sp")

不同的存储格式定义了在内存中的YUV分量的排列顺序

从 YUV420P 的名字就可以看出它是 planar 平面格式,根据U和V顺序不同又分为:

  1. YV12:Y1...Y4n V1...Vn U1...Un (例如:YYYYYYYYVVUU)
  2. I420: Y1...Y4n U1...Un V1...Vn (例如:YYYYYYYYUUVV)

一般说的 YUV420p就是指 I420

从 YUV420SP 的名字就可以看出它是 Semi-planar 半平面格式

  1. NV21
  2. NV12

一般说的 YUV420sp就是指 NV12

引用一张图来表示

常用的图像文件

RGB 与 YUV 格式的转换

计算公式如下

Y = k_rR + k_gG + k_bB

U = \frac{B - Y}{2(1-k_b)}

V = \frac{R - Y}{2(1-k_r)}

其中的相关系统,ITU-R 给出的推荐值为

k_r=0.299

k_g=0.587

k_b=0.114

以矩阵计算的方式表示 RGB 转为 YUV 的公式如下

\left [ \begin{matrix} Y \\ U \\ V \\ \end{matrix} \right ] = \left [ \begin{matrix} 0 \\ 128 \\ 128 \\ \end{matrix} \right ] + \left [ \begin{matrix} 0.299 && 0.5870 && 0.1140 \\ -0.1687 && -0.3313 && -0.5000 \\ 0.5000 && -0.4187 && -0.0813 \\ \end{matrix} \right ] * \left [ \begin{matrix} R \\ G \\ B \\ \end{matrix} \right ]

在实际应用中,针对不同的场景和清晰度要求,上述公式会有细微调整

模拟电视

传统上说的 YUV 是用于模拟电视的色彩表示,它与 RGB 之间的转换公式如下

标清视频

对于数字视频,使用颜色格式 YCbCr。 对于标清电视应用 (SDTV),以下等式描述了从 RGB 到 YCbCr 的颜色转换(根据 ITU-R BT.601):

对于使用 RGB 和 YCbCr 颜色格式的基于计算机的应用程序,色度和亮度值的可能范围保留了一些头部和足部的空间,这是为避免过冲提供一些空间所必需的。

如果要使用 8 位的完整可能范围,则不提供足部空间或动态余量。 通常,这种全范围颜色格式用于 JPEG 图像。

RGB 颜色到全范围 YCbCr 颜色的转换由以下等式描述:

高清视频

对于高清电视应用 (HDTV),转换系数以有所不同:

代码示例

void rgb2yuv(double& Y, double& U, double& V, const double R, const double G, const double B)
{
  Y =  0.257 * R + 0.504 * G + 0.098 * B +  16;
  U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
  V =  0.439 * R - 0.368 * G - 0.071 * B + 128;
}

void yuv2rgb(double& R, double& G, double& B, double Y, double U, double V)
{
  Y -= 16;
  U -= 128;
  V -= 128;
  R = 1.164 * Y             + 1.596 * V;
  G = 1.164 * Y - 0.392 * U - 0.813 * V;
  B = 1.164 * Y + 2.017 * U;
}

在工程上,为提高性能,可以先用整数计算,再右移8位

void rgb2yuv(double& Y, double& U, double& V, const double R, const double G, const double B)
{
    Y = ((66 * R + 129 * G + 25 * B) >> 8) + 16;
    U = ((-38 * R + -74 * G + 112 * B) >> 8) + 128;
    V = ((112 * R + -94 * G + -18 * B) >> 8) + 128;
}

参考资料

上一篇下一篇

猜你喜欢

热点阅读