YUV图像格式

1,062 阅读7分钟

一、简介

YUV是一种表示颜色的模型。基于人眼对亮度高度敏感,对颜色敏感度低于亮度的生理特征 YUV在对照片或视频编码时候完整保存了像素的亮度分量(Y),根据不同的采样要求保存UV分量。

YUV可跟RBGA互转。但是我们常说的 YUV ,其实指的是 YCbCr,其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量,这里用 YUV 指代 YCbCr 。

二、YUV的采样和存储

由于人眼对 Y 的敏感度远超于对 U 和 V 的敏感,所以有时候可以多个 Y 分量共用一组 UV,这样既可以极大得节省空间,又可以不太损失质量。因此才会出现YUV 420,YUV 422,YUV 444的格式。

2.1 YUV采样方式

YUV 4:4:4:

表示 Y、U、V 三分量采样率相同,即每个像素的三分量信息完整,都是 8bit,每个像素占用 3 个字节。如果水平方向有 100 个像素点,那么采样了 100个 Y 分量,采样了 100 个 UV 分量。这种采样方式如图所示,图中以叉表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量。

image.png

YUV 4:2:2

YUV 4:2:2 采样,意味着 UV 分量是 Y 分量采样的一半,Y 分量和 UV 分量按照 2 : 1 的比例采样。如果水平方向有 100 个像素点,那么采样了 100个 Y 分量,而只采样了 50 个 UV 分量。采样方式如图所示:

image.png

YUV 4:2:0

YUV 4:2:0 采样,并不是指只采样 U 分量而不采样 V 分量。而是指,在每一行扫描时,只扫描一种色度分量(U 或者 V),和 Y 分量按照 2 : 1 的方式采样。比如,第一行扫描时,YU 按照 2 : 1 的方式采样,那么第二行扫描时,YV 分量按照 2:1 的方式采样。对于每个色度分量来说,它的水平方向和竖直方向的采样和 Y 分量相比都是 2:1 。假设第一行扫描了 U 分量,第二行扫描了 V 分量,那么需要扫描两行才能够组成完整的 UV 分量,则YUV 4:2:0采样方式如图所示:

image.png

采样方式比较

对于一张 1920*1280大小的图片,根据前面所述采样方式我们可以得出:

在 YUV 4:4:4 采样时的大小为:(19201280 * 8 + 19201280 * 1 * 8 * 2)/ 8 / 1024 / 1024 = 7.03 MB 。

在 YUV 4:2:2 采样时的大小为:(19201280 * 8 + 19201280 * 0.5 * 8 * 2)/ 8 / 1024 / 1024 = 4.69 MB 。

在 YUV 4:2:0 采样时的大小为:(19201280 * 8 + 19201280 * 0.25 * 8 * 2)/ 8 / 1024 / 1024 = 3.52 MB 。

由此可见YUV 4:4:4采样方式相比 RGB 模型图像并没有节省存储空间,YUV 4:2:2节省了三分之一的存储空间,在传输时占用的带宽也会随之减少;YUV 4:2:0 采样节省了一半的存储空间,因此它也是比较主流的采样方式。

2.2 YUV存储格式

 YUV 数据有两种存储格式:

  1. 平面格式(planar format):先连续存储所有像素点的 Y,紧接着存储所有像素点的 U,随后是所有像素点的 V。从字面意思上来看,planar是平面的意思,对应到存储方式上就是把YUV三种分量分别存储,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。这种在解析时很方便。(该存储方式简称p,如420p)
  2. 打包格式(packed format):每个像素点的 Y、U、V 是连续交错存储的。从字面意思来看,packed是打包的意思,对应到存储方式上就是把YUV三种分量连续交叉存储,这种方式在解析时比较麻烦。
  3. 半平面格式(semi-planar format):是前两者的混合,一部分分量用 planar 方式存储,另一部分分量用 packed 分量存储。也就是先存储Y分量,之后UV分量连续存储。

以yuv为例,三种存储方式如下图所示:

image.png

代码中部分与YUV相关的数据格式:

mialgoengine

enumvalue
CAM_FORMAT_YUV_420_NV2117
CAM_FORMAT_YUV_420_NV1235
CAM_FORMAT_Y16540422489
CAM_FORMAT_YV12842094169

camxhal3

enumvalue
HAL_PIXEL_FORMAT_YCBCR_422_SP16
HAL_PIXEL_FORMAT_YCRCB_420_SP17
HAL_PIXEL_FORMAT_YCBCR_422_I20
HAL_PIXEL_FORMAT_YCBCR_420_88835
HAL_PIXEL_FORMAT_Y8538982489
HAL_PIXEL_FORMAT_Y16540422489
HAL_PIXEL_FORMAT_YV12842094169

注:预览的格式是HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 34,不会经过算法框架后处理(可能是处理时间的原因)

以上格式是依据采样方式和存储方式,以使用较多的YUV_420_NV12为例(HAL_PIXEL_FORMAT_YCBCR_420_888)

采样方式为:每个像素有一个Y值、4个像素共用一对U、V值(4:2:0 4:0:2)

存储方式为:NV12则表明以planer+packed方式存储,Y单独存储、UV间隔存储,且先U后V。

2.3 常见的几种YUV格式分析

下面以一张8*4分辨率的单帧图像分析几种常见格式的yuv图像。

YV12 /YU12

YV12/YU12(也称 I420) 属于 YUV420P ,即 YUV420 采样方式的plane模式,YUV 三个分量分别存储于 3 个不同的矩阵(平面)。YV12储存方式如下图所示:

image.png

这幅图可以看出 Y1、Y2、Y9、Y10 共用V1 和 U1,其他未列出的均类似。

相对应的码流为(篇幅过长省略了Y17-Y32,V5-V8,U5-U8):

Y1Y2Y3Y4Y5Y6Y7Y8Y9Y10Y11Y12Y13Y14Y15Y16 ...V1V2V3V4...U1U2U3U4...

线性数组为其存储顺序,可以看出 Y、U 和 V 都是顺序存储的,往外写的时候,先按顺序将 Y 分量写出,然后再根据 V、U 分别将它们依次写出即可。

NV21 和 NV21

NV12 和 NV21 格式都属于 YUV420SP 类型,手机摄像头采集预览数据就为这两种格式。YUV420SP 格式有 2 个平面,Y 分量存储于一个平面,UV 分量交错存储于另一个平面。

NV12 和 NV21 格式都先存储了 Y 分量,但接下来并不是再存储所有的 U 或者 V 分量,而是把 UV 分量交替连续存储。NV12 是 IOS 中有的模式,它的存储顺序是先存 Y 分量,再 UV 进行交替存储,按照[YYUV]格式进行存放;NV21 是 安卓 中有的模式,它的存储顺序是先存 Y 分量,在 VU 交替存储,按照[YYVU]格式进行存放。NV21储存方式如下图:

image.png

这幅图可以看出与 YV12 不同的时,它的 Y 虽然也是顺序存储,但 U、V 却是交错存储的。同时可以看出 Y1、Y2、Y9、Y10 共用V1 和 U1,其他未列出的均类似。

相对应的码流为(篇幅过长省略了Y17-Y32,V5U5-V8U8):

Y1Y2Y3Y4Y5Y6Y7Y8Y9Y10Y11Y12Y13Y14Y15Y16 ...V1U1V2U2V3U3V4U4...

这种方式存储在往外写出时则先直接顺序写出 Y,然后对 VU 交错写出。

常用格式

格式名存储方式
YU12(I420格式、420P)先把全部的Y分量存完,再存U分量,最后存V分量。
YV21(420P)先把全部的Y分量存完,再存V分量,最后存U分量。
NV12(420sp)(planer+packed)先存储全部的Y分量,然后UV分量交叉存储。(半平面(Semi-Planar))
NV21(420sp)(planer+packed)先存储全部的Y分量,然后VU分量交叉存储。
YUV422Pplaner存储,与YU12存储类似,只是422是两组Y分量共用一组UV分量(4:2:2、4:2:2)
YUYV/YVYU/UYVY间隔存储,先Y、再U、再Y、再V(后面两个类似)

高通的P010 format官方描述

同:存放的数据都是4:2:0 10bit YUV数据

异:Android的数据是16字节对齐的,而高通的对齐方式不太标准,具体差异如图所示:

image.png