数字音视频技术: 谈谈 YUV的采样格式和存储格式

一. YUV是什么

YUV 是一种颜色的编码方式,常用于各种图像及视频处理中,其中的“Y”代表明亮度(Luminance、Luma), 也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma)。YUV 还有一些别的名字,比如: YCbCr,YPbPr, 在不同的专业领域,叫法也不一样,不过可以把它们理解成同样的东西。

二. YUV的由来

说起YUV,就必然需要提到另一种编码格式:RGB,我们知道RGB由 3 种原色 (红色、绿色和蓝色)组成,通过这三种颜色可以组合“制造”所有其他颜色。RGB编码方案是将像素的信息分为 3 个值:一个用于红色,一个用于绿色,一个用于蓝色。因此,RGB 视频流的每个图像都是3 个图像的 总和 :一个 红色、一个 绿色 和一个 蓝色。

 

那为什么会有YUV这个东西? YUV的发明是由于彩色电视与黑白电视的过渡时期, 早期的黑白电视只能显示黑色和白色两种颜色,随着技术的发展,彩色电视出现了,但对于电视台来说,不可能同时广播两套数字电视信号(当然也不是不行,但是同一个节目信号广播两次也是浪费),于是人们就在思考能否能以更简便的方式来改进现有的技术方案,即是说,广播电视中心只需要广播一套电视信号就能同时满足黑白电视和彩色电视的显示需求。那具体如何实现呢?这时候YUV就出来了,简单的说就是,我们用Y表示黑白图像,用UV表示彩色图像,你要是黑白电视,那你接收到YUV信号后,只需要拿到Y就可以了,因为Y代表的就是黑白图像,UV可以直接扔掉;如果是彩色电视,那你可以收到YUV三个信号后再叠加显示,就可以显示出彩色图像。这样便一举解决了彩色电视与黑白电视的兼容问题。

用下面的图示可能更好理解:

其中的Y表示一幅灰度图,如果叠加了UV,就可以组合成一幅彩色画面,但对于黑白电视来说,只要Y就行。整个数字电视信号的传播过程可以用下图表示:

YUV除了可以分离黑白信息和彩色信息满足兼容性这个优势以外,还可以根据需要在采样时进行压缩,进而减少传输带宽,这是它的另一个优势。

三. YUV的采样格式

上面提到,YUV 可以根据需要在采样时进行压缩,进而减少传输带宽,这是什么意思呢? 我们知道,图像是由多个像素点组成的,每个像素点可以由RGB三种颜色搭配,进而组合成各种各样的颜色。

从程序上讲,RGB三原色,每个颜色其实都可以用一个字节(0~255)来表示,那么一个像素点就是3个字节(不包含透明通道),一个3 * 3 像素的RGB图像可以表示如下 :

如果是一幅  1280 * 720 大小的图片,就占用 1280 * 720 * 3 / 1024 / 1024 = 2.63 MB 存储空间。如果按每秒30帧计算的话,1s的视频大小就是 2.63 * 30 = 78.9MB, 那1分钟就是:78.9 * 60 = 4734 MB,可以看到1分钟的传输量就将近5个G了,在本世纪初那个拨号上网的年代,这么大的网络带宽肯定是不可接受的,这还仅仅是网络传输,如果存储到本地,那占用的硬盘空间更是不可想象(毕竟电影基本都是30分钟以上)。因此对原始图像进行重新采样是很有必要的,不仅仅可以减少网络带宽,还可以减少存储占用的空间。

在此之前,补充一下从RGB转换为YUV的转换公式,通过一定的公式可以把原有的RGB图像转换为YUV图像:

具体可移步维基百科:https://zh.wikipedia.org/wiki/YUV

那YUV是如何做到减少传输带宽和存储空间的呢?

经过研究表明,我们人眼对色度(UV)的敏感程度低于对亮度(Y)的敏感程度。主要原因是视网膜杆细胞多于视网膜锥细胞,其中的视网膜杆细胞的作用就是识别亮度,视网膜锥细胞的作用就是识别色度。因此,人眼对亮度的分辨要比对颜色的分辨要精细。利用这个原理,在进行色彩采样的时候,就可以把色度信息适当减少,这样子就可以省下了部分编码存储空间,同时最终的显示效果,人眼也不太容易察觉。因此,YUV在编码时,每一个像素点的采样并不是都需要包含Y、U、V三个分量,可以每个Y分量,都对应自己的UV分量,也可以几个Y分量共享UV分量。当然,这里的共享,是指解码YUV进行像素渲染时的共享。而不同的Y、UV组合,对应了几种不同的YUV采样格式

目前主流的YUV采样格式分为以下几种:YUV444YUV422YUV420,下面分别对其进行介绍:

YUV444

YUV 4:4:4 采样,意味着 Y, U, V 三个分量的采样比例相同,每1个亮度分量(Y)都对应着一组色度分量(UV), 每4点Y采样,就有相对应的4点U和4点V:

我们以一个黑框代表一个像素点,可以看到,每个像素点都包含Y,U, V 三个分量,一个分量占用1个byte的话,那1个像素点就占用3 byte,那这和上面的RGB存储方式没有什么区别,占用的大小是一样的,并没有起到节省带宽的目的。

YUV422

研究表明,我们对亮度比较敏感,而对色度不怎么敏感, 绝大部分相邻的两个像素,色度信息差异不大,因此可以适当丢弃部分色差数据。具体就是,在水平方向上相邻的两个像素,共享同一个色度分量,即水平方向上亮度分量与色度分量采样比例为2:1, 每两个Y分量共享一组UV分量,如下图所示:

这样的话, 第一和第二个像素点共用一组UV分量,第三和第四个像素点共用了一组UV分量,由于丢弃了部分色度分量,这样就节省了图像空间。相邻2个像素点占用的空间为:(Y+Y+U+V) = 4 byte, 平均一个像素点占用的空间为:4 /2 = 2 byte

YUV420

专家们进一步研究表示,每一行的相邻两个像素与下一行同位置的两个像素数据差异不大,可以进一步的丢数据。具体就是,在第一行采集时,只采集Y和其中一种色度分量(U 或者 V),在第二行采集时,仍然采集Y和其中的另一个色度分量。有点拗口,简单的说就是,第一行只采集Y和U,第二行只采集Y和V。这样采集的效果如下:

那该如何合成一个完整的像素点呢?水平方向上相邻的两个像素点已经无法再合成为一个完整的像素点(因为不是缺少U就是缺少V),

很简单,只要把上下两行的UV分量组合起来就行了。

就是说,第一行的第一个像素点(YU)可以使用第二行第一个像素点的V,组合成一个完整的YUV; 第一行第二个像素点(Y)可以使用第一行第一个像素点的U和第二行第一个像素点的V, 组合成一个完整的YUV,上下两行相邻的4个像素点共享一组UV分量。

这样的话,相邻4个像素点所占用的空间为(Y+Y+Y+Y+U+V)  = 6 byte, 平均每个像素点占用的空间为 6 / 4 = 1.5 byte。可以看到 YUV 4:2:0 采样的图像比YUV444或 RGB 模型图像节省了一半的存储空间,因此它也是比较主流的采样方式。

四. YUV的存储格式

上面介绍了下YUV的采样格式,接下来谈谈YUV的存储格式。为什么要提到存储格式呢?因为采样形式虽然定了,但是存储方案却有很多种,我们有Y,U,V三个分量,在给内存赋值的时候,到底是先存Y,再存U,再存V?还是先存Y,再存V,再存U?还是还把Y存完,再开始存U,然后再存V,类似这样:YYYYYYYYYY, UUUUUUUUUU, VVVVVVVVV , ...

可以看到,存储方式是各种各样的,如果搞不清楚原始的YUV数据究竟是以哪种方式存储的,那么将来在解析恢复成RGB数据的时候,就一定会有问题。像x264的源码文件里,就定义了一堆这样的类型:

/* Colorspace type */
#define X264_CSP_MASK           0x00ff  /* */
#define X264_CSP_NONE           0x0000  /* Invalid mode     */
#define X264_CSP_I400           0x0001  /* monochrome 4:0:0 */
#define X264_CSP_I420           0x0002  /* yuv 4:2:0 planar */
#define X264_CSP_YV12           0x0003  /* yvu 4:2:0 planar */
#define X264_CSP_NV12           0x0004  /* yuv 4:2:0, with one y plane and one packed u+v */
#define X264_CSP_NV21           0x0005  /* yuv 4:2:0, with one y plane and one packed v+u */
#define X264_CSP_I422           0x0006  /* yuv 4:2:2 planar */
#define X264_CSP_YV16           0x0007  /* yvu 4:2:2 planar */
#define X264_CSP_NV16           0x0008  /* yuv 4:2:2, with one y plane and one packed u+v */
#define X264_CSP_YUYV           0x0009  /* yuyv 4:2:2 packed */
#define X264_CSP_UYVY           0x000a  /* uyvy 4:2:2 packed */
#define X264_CSP_V210           0x000b  /* 10-bit yuv 4:2:2 packed in 32 */
#define X264_CSP_I444           0x000c  /* yuv 4:4:4 planar */
#define X264_CSP_YV24           0x000d  /* yvu 4:4:4 planar */
#define X264_CSP_BGR            0x000e  /* packed bgr 24bits */
#define X264_CSP_BGRA           0x000f  /* packed bgr 32bits */
#define X264_CSP_RGB            0x0010  /* packed rgb 24bits */
#define X264_CSP_MAX            0x0011  /* end of list */
#define X264_CSP_VFLIP          0x1000  /* the csp is vertically flipped */
#define X264_CSP_HIGH_DEPTH     0x2000  /* the csp has a depth of 16 bits per pixel component */

从整体来看,YUV的存储格式可分为三大类:

  • Planar (平面格式)。YUV三个分量分开存放。即先存Y,再存U,再存V,存储形式类似于:YYYYYYYYYYY UUUUUUUUU VVVVVVVVVVV
  • Semi-Planar (半平面格式)。即先存Y,再存UV, 存储形式类似于:YYYYYYYYYYY UVUVUVUVUVUV
  • Packed (打包格式,也有叫做 Interleaved, 交错格式)。即按照YUV YUV 的形式存储,存储形式类似于:YUV YUV YUV YUV YUV

由于采样格式的不同,每种采样格式其实也有不同的存储格式,具体如下:

下面分别对其进行说明:

基于YUV444采样的存储格式

I444 (Plannar)

属于YUV444 Plannar , 顺序存储,即先存储所有的Y,再存储所有的U, 最后再存储所有的V:

Y1 Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
U1 U U U U U
U U U U U U
U U U U U U
U U U U U U
U U U U U U
U U U U U U
V1 V V V V V
V V V V V V
V V V V V V
V V V V V V
V V V V V V
V V V V V V

YV24 (Planar)

属于YUV444 Planar, 顺序存储,即先存所有的Y,再存储所有的V,最后存储所有的U:

Y1 Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
V1 V V V V V
V V V V V V
V V V V V V
V V V V V V
V V V V V V
V V V V V V
U1 U U U U U
U U U U U U
U U U U U U
U U U U U U
U U U U U U
U U U U U U

NV24 (Semi-Planar)

属于 YUV 444 Semi-Planar,顺序存储,先存储所有的Y,然后UV分量交错存放:

Y1 Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
U1 V1 U V U V U V U V U V 
U  V  U V U V U V U V U V 
U  V  U V U V U V U V U V 
U  V  U V U V U V U V U V 
U  V  U V U V U V U V U V 
U  V  U V U V U V U V U V 

NV42 (Semi-Planar)

属于 YUV 444 Semi-Planar,顺序存储,先存储所有的Y,然后VU分量交错存放:

Y1 Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
Y  Y  Y Y Y Y
V1 U1 V U V U V U V U V U
V  U  V U V U V U V U V U
V  U  V U V U V U V U V U
V  U  V U V U V U V U V U
V  U  V U V U V U V U V U
V  U  V U V U V U V U V U

YUV444 (Packed)

属于YUV444 Packed , 就是按照YUV YUV YUV YUV .... 这样的方式存储。

Y1 U1 V1   Y U V   Y U V   Y U V   Y U V   Y U V
Y U V      Y U V   Y U V   Y U V   Y U V   Y U V
Y U V      Y U V   Y U V   Y U V   Y U V   Y U V
Y U V      Y U V   Y U V   Y U V   Y U V   Y U V
Y U V      Y U V   Y U V   Y U V   Y U V   Y U V
Y U V      Y U V   Y U V   Y U V   Y U V   Y U V

基于YUV422的存储格式

I422 (也叫YU16, Planar)

属于YUV422 Planar, 顺序存储,即先存储所有的Y,再存储所有的U,最后存储所有的V:

还原像素点的时候需要注意,对于像素点Y’00、Y’01 而言,其Cb、Cr的值均为 Cb00、Cr00。

YV16 (Planar)

属于YUV422 Planar, 顺序存储,即先存储所有的Y,再存储所有的V,最后存储所有的U:

 NV16 (Semi-Planar)

属于YUV422 Semi-Planar, 先存储所有的Y,再存储所有的UV,注意UV是交错存储的:

 NV61 (Semi-Planar)

属于YUV422 Semi-Planar, 先存储所有的Y,再存储所有的VU,注意VU是交错存储的:

YUYV (也叫YUY2, Packed)

属于YUV422 Packed, 即按照YU YV YU YV ... 的顺序存储

相邻的两个Y共用其相邻的两个Cb、Cr。对于像素点Y’00、Y’01 而言,其Cb、Cr的值均为Cb00、Cr00,其他的像素点的YUV取值依次类推。

UYVY (Packed)

属于YUV422 Packed, 即按照UY VY UY VY ... 的顺序存储

只不过与YUYV不同的是UV的排列顺序不一样而已,还原其每个像素点的YUV值的方法与上面一样。

VYUY (Packed)

属于YUV422 Packed, 即按照VY UY  VY UY ... 的顺序存储

V1 Y1 U1 Y2   V Y U Y   V Y U Y
V  Y  U  Y    V Y U Y   V Y U Y
V  Y  U  Y    V Y U Y   V Y U Y
V  Y  U  Y    V Y U Y   V Y U Y
V  Y  U  Y    V Y U Y   V Y U Y
V  Y  U  Y    V Y U Y   V Y U Y

基于YUV420的存储格式

I420 (也叫YU12, Planar)

属于YUV420 Planar, 即先存储所有的Y,再存储所有的U,再存储所有的V

其中,Y1,Y2,Y7,Y8  共享U1 V1;Y17,Y18,Y23,Y24 共享U6 V6。

YV12 (Planar)

属于YUV420 Planar, 即先存储所有的Y,再存储所有的V,再存储所有的U:

NV12 (Packed, iOS上常用这种格式)

属于YUV420 Packed, 即先存储所有的Y,再交错存储UV:

 

其中 Y1, Y2, Y7, Y8 共享 U1,V1;Y13,Y14,Y19,Y20 共享U4 ,V4。

NV21 (Packed,Android上常用这种格式)

属于YUV420 Packed, 即先存储所有的Y,再交错存储VU:

    Y1 Y2 Y  Y  Y  Y
    Y3 Y4  Y  Y  Y  Y
    Y  Y  Y  Y  Y  Y
    Y  Y  Y  Y  Y  Y
    Y  Y  Y  Y  Y  Y
    Y  Y  Y  Y  Y  Y
    V1 U1 V  U  V  U
    V  U  V  U  V  U
    V  U  V  U  V  U 

其中Y1,Y2,Y3,Y4共享V1 U1。

下面以一张图总结一下以上四种格式,其中 P (Planar) 代表平面格式,SP (Semi-Planar) 代表半平面格式:

 <完>

参考链接:

1. 维基百科 : YUV

2. Microsoft: Recommended 8-Bit YUV Formats for Video Rendering

3.一文读懂 YUV 的采样与格式

4. 图文详解YUV420 数据格式

5. YUV 格式详解

6. 图解YU12、I420、YV12、NV12、NV21、YUV420P、YUV420SP、YUV422P、YUV444P的区别

7. YUV采样方式和存储格式

8.最简单解释 YUV444,YUV422,YUV420中的4,2,0

9. 图像原始格式(YUV444 YUV422 YUV420)一探究竟

10. YUV Learning Records

 

posted @ 2019-04-03 10:03  夜行过客  阅读(5214)  评论(0编辑  收藏  举报