LV020-YUV的格式
一、YUV采样模式
1. 采样模式有哪些?
1.1 四种采样模式
YUV 有 4 种采样模式:
- YUV4:4:4 ,表示完全采样,一个像素 占 3 个字节。
- YUV4:2:2,表示2:1的水平采样,垂直完全采样,平均一个像素占 2 个字节。
- YUV4:2:0,表示2:1的水平采样,垂直2:1采样,平均一个像素占 1.5 个字节。
- YUV4:1:1,表示4:1的水平采样,垂直完全采样,但是这种我只是在维基百科的词条中看到有,实际并没有接触过。
主流的采样模式就是前面三种,YUV444、YUV422和YUV420。这些是什么意思?后面会详细学习,这样的采样模式主要是因为由于人眼对 Y 的敏感度远超于对 U 和 V 的敏感,所以有时候可以多个 Y 分量共用一组 UV,这样既可以极大得节省空间,又可以不太损失质量。这三种格式就是按照人眼的特性制定的。
YUV格式之所以能够采用不同的采样模式,核心原因在于人眼的生理特性:
(1)人眼对亮度(Y)的敏感度远高于对色度(U/V)的敏感度
- 亮度分量(Y)包含图像的细节信息,人眼对此非常敏感
- 色度分量(U/V)包含颜色信息,人眼对此相对不敏感
(2)视觉感知的不对称性
- 人眼能够分辨出微小的亮度变化,但对颜色的细微变化不敏感
- 即使大幅减少色度信息,人眼也很难察觉到明显的质量损失
1.2 图片示例
我们可以准备一张图片,使用FFmpeg转换一下,分别得到YUV444、YUV422和YUV420格式的图片,方便后面分析。可以直接在这里下载:yuv-picture.zip:

我们也可以自己找一张jpg图片,转换一下,相关命令如下所示:
ffmpeg.exe -i juren.jpg -s 1920*1080 -pix_fmt yuvj444p juren_yuv_444.yuv
ffmpeg.exe -i juren.jpg -s 1920*1080 -pix_fmt yuvj422p juren_yuv_422.yuv
ffmpeg.exe -i juren.jpg -s 1920*1080 -pix_fmt yuvj420p juren_yuv_420.yuv从上图可以看到,yuv420 比 yuv444 的 数据量少了一半,我们用 7yuv 看一下图片质量的差异:
- juren_yuv_444.yuv(注意格式那里选YUV444 planar)

- juren_yuv_420.yuv(注意格式那里选YUV420 planar I420)

观察上面两张图,至少我是没有觉察到有什么变化,所以重点:YUV420 比 YUV444 少了一半数据,视觉体验几乎没有变化。
2. 不同采样模式
2.1 YUV444
YUV 4:4:4 采样,意味着 Y、U、V 三个分量的采样比例相同,因此在生成的图像里,每个像素的三个分量信息完整,都是 8 bit,也就是一个字节。
这种格式占用空间最大,每个像素点有一个Y分量 + 一个U分量 + 一个V分量所以和 RGB 一样每个像素点占用3个字节!但是根据UV存储顺序不一样,又可能会有两种不同的格式,这种的就属于存储格式了,后面再说。

如上图所示,YUV444就是每个像素点都包含了三个完整的YUV分量,每一个Y分量用一组UV分量,所以
单个像素点占用的空间为: pixel = 1Byte(Y) + 1Byte(U) + 1Byte(V) = 3Byte
一帧图像占用的空间为 : frameSize = (frameWidth * frameHeight * 3)Byte例如
假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3] 那么采样的码流为:Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 最后映射出的像素点依旧为 [Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]
2.2 YUV422
YUV 4:2:2 采样,意味着 UV 分量是 Y 分量采样的一半,Y 分量和 UV 分量按照 2 : 1 的比例采样。如果水平方向有 10 个像素点,那么采样了 10 个 Y 分量,而只采样了 5 个 UV 分量。

YUV422就是UV分量是Y分量的一半,按照上图的样子,应该是相邻两个Y共用一个UV:

单个像素点占用的空间为: pixel = 1Byte(Y) + 1Byte(U)/2 + 1Byte(V)/2 = 2Byte
一帧图像占用的空间为 : frameSize = (frameWidth * frameHeight * 2)Byte举个例子 :
假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]
那么采样的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3
其中,每采样过一个像素点,都会采样其 Y 分量,而 U、V 分量就会间隔一个采集一个。
最后映射出的像素点为 [Y0 U0 V1]、[Y1 U0 V1]、[Y2 U2 V3]、[Y3 U2 V3]
采样的码流映射为像素点,还是要满足每个像素点有 Y、U、V 三个分量。但是可以看到,第一和第二像素点公用了 U0、V1 分量,第三和第四个像素点公用了 U2、V3 分量,这样就节省了图像空间。一张 1280 x 720 大小的图片,在 YUV 4:2:2 采样时的大小为:
(1280x720x8 + 1280x720x8x0.5 + 1280x720x8x0.5) / 8 / 1024 / 1024 = 1.76M可以看到 YUV 4:2:2 采样的图像比 RGB 模型图像节省了三分之一的存储空间,在传输时占用的带宽也会随之减少。
2.3 YUV420
这个格式也是应用最广泛的,视频会议,数字电视,DVD,都用的 YUV420 格式。YUV 4:2:0 采样,并不是指只采样 U 分量而不采样 V 分量。而是指,在每一行扫描时,只扫描一种色度分量(U 或者 V),和 Y 分量按照 2 : 1 的方式采样。比如,第一行扫描时,YU 按照 2 : 1 的方式采样,那么第二行扫描时,YV 分量按照 2:1 的方式采样。对于每个色度分量来说,它的水平方向和竖直方向的采样和 Y 分量相比都是 2:1 。

如上图,假设第一行扫描了 U 分量,第二行扫描了 V 分量,那么需要扫描两行才能够组成完整的 UV 分量。所以四个像素点才能包含一组完整的YUV信息:

第一行的第1,第2 像素,第二行的 第1,第2 像素共用一组 UV,以此类推。为什么不是 第一行的 第 1~ 4 个像素共享 一组 UV?这是因为如果这样搞,空间距离太远,容易造成体验不太好。换行共享 UV 的空间距离短,画面过渡会自然一些。所以四个Y分量共用一组UV分分量:
单个像素点占用的空间为: pixel = 1Byte(Y) + 1Byte(U)/4 + 1Byte(V)/4 = 1.5Byte
一帧图像占用的空间为 : frameSize = (frameWidth * frameHeight * 1.5)Byte举个例子 :
假设图像像素为:
[Y0 U0 V0]、[Y1 U1 V1]、 [Y2 U2 V2]、 [Y3 U3 V3] [Y5 U5 V5]、[Y6 U6 V6]、 [Y7 U7 V7] 、[Y8 U8 V8]
那么采样的码流为:Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8
其中,每采样过一个像素点,都会采样其 Y 分量,而 U、V 分量就会间隔一行按照 2 : 1 进行采样。
最后映射出的像素点为:
[Y0 U0 V5]、[Y1 U0 V5]、[Y2 U2 V7]、[Y3 U2 V7] [Y5 U0 V5]、[Y6 U0 V5]、[Y7 U2 V7]、[Y8 U2 V7]
这些 UV 值都是新值,是以前的 4 个像素的 U 值加起来 除以4 的平均值。其实有好几种求 UV 值算法:
(1)平均值,4 个像素的 U 值加起来 除以 4。
(2)加权,例如,第一第二个像素的 U 权重大点,第三第四个像素的 U 权重小一点。
(3)直接丢弃 第二,第三,第四个像素的 U 值,取 第一个 像素的 U 值。V 值同理。
一张 1280 * 720 大小的图片,在 YUV 4:2:0 采样时的大小为:
(1280 x 720 x 8 + 1280 x 720 x 0.25 x 8 x 2)/ 8 / 1024 / 1024 = 1.32 MB可以看到 YUV 4:2:0 采样的图像比 RGB 模型图像节省了一半的存储空间,因此它也是比较主流的采样方式。
3. 总结
![]() | ![]() |
如上图所示:
| YUV格式 | 每个像素所占字节数 | 说明 |
|---|---|---|
| YUV444 | pixel_size=1Byte(Y)+1Byte(U)+1Byte(V)=3Byte | 每个Y对应一组UV |
| YUV422 | pixel_size=[2Byte(Y)+1Byte(Y)+1Byte(V)]/2=2Byte | 每2个Y对应一组UV |
| YUV420 | pixel_size=[4Byte(Y)+1Byte(Y)+1Byte(V)]/4=1.5Byte | 每4个Y对应一组UV |
二、存储格式
1. 有哪些格式?
上面了解了采样模式了,那采样结束肯定需要存储的啊,怎么存?YUV存储方式主要分为三种:压缩格式(Packed formats) 、平面格式(Planar formats)和半平面(semi-Planar)。
| 存储格式 | 说明 |
| P:Planner | 按平面分开存放,先把Y存完,再存U,再存V,就是先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V,即YYY UUU VVV 这样 |
| SP:semi-Planar | 按半平面存放,只有Y是一个平面,UV数据共用一个平面,UV分量交叉存储。 |
| Packed | 打包格式,就是把YUV三种分量按顺序存储,即YUV YUV YUV ... 这样 |
所以不同的采样方式加上不同的存储方式就会有多种不同的YUV编码方式。
2. 常用的格式
2.1 YUV420
YUV420是使用很多的,它结合不同的存储方式,常用的会有YUV420P和YUV420SP。
2.1.1 YUV420P
YUV420P属于YUV420采样,planar存储,它又会分为YU12(也叫 l420)、YV12两种,YU12 和 YV12 格式都属于 YUV 420P 类型,即先存储 Y 分量,再存储 U、V 分量,区别在于:YU12 是先 Y 再 U 后 V,而 YV12 是先 Y 再 V 后 U 。

I420(属于 YUV 420 Plannar) I420 是 YUV 420 Planar 的一种,YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h * 0.25 长度的 U, 最后是 w * h * 0.25 长度的 V,总长度为 w * h * 1.5。
YV12(属于 YUV 420 Plannar) YV12 是 YUV 420 Planar 的一种,YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h * 0.25 长度的 V, 最后是 w * h * 0.25 长度的 U,总长度为 w * h * 1.5。与 I420 不同的是,YV12 是先 V 后 U。
2.1.2 YUV420SP
YUV420SP属于YUV420采样,semi-Planar存储,分为NV12、NV21,YUV420先存储了 Y 分量,但接下来并不是再存储所有的 U 或者 V 分量,而是把 UV 分量交替连续存储。NV12 是 IOS 中有的模式,它的存储顺序是先存 Y 分量,再 UV 进行交替存储。NV21 是 安卓中有的模式,它的存储顺序是先存 Y 分量,在 VU 交替存储。

NV12(属于 YUV 420 Semi-Planar) NV12 是 YUV 420 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,UV 在排列的时候,从 U 开始。总长度为 w * h * 1.5。
NV21(属于 YUV 420 Semi-Planar) NV21 是 YUV 420 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,与 NV12 不同的是,UV 在排列的时候,从 V 开始。总长度为 w * h * 1.5。
2.2 YUV422
2.2.1 YUV422P
YUV422P属于YUV422采样,它的存储格式是planar,分YU16和YV16两种:

I422(属于 YUV 422 Plannar,也叫YU16) I422 是 YUV 422 Planar 的一种,YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h * 0.5 长度的 U, 最后是 w * h * 0.5 长度的 V,总长度为 w * h * 2。
YV16(属于 YUV 422 Plannar) YV16 是 YUV 422 Planar 的一种,YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h * 0.5 长度的 V, 最后是 w * h * 0.5 长度的 U,总长度为 w * h * 2。与 I422 不同的是,YV16 是先 V 后 U。
2.2.2 YUV422SP
YUV422SP 属于YUV422采样,分为NV16、NV61两种:

NV16(属于 YUV 422 Semi-Planar) NV16 是 YUV 422 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,UV 在排列的时候,从 U 开始。总长度为 w * h * 2。
NV61(属于 YUV 422 Semi-Planar) NV61 是 YUV 422 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,UV 在排列的时候,从 V 开始。总长度为 w * h * 2。
2.2.3 Packed格式

YUVY(属于 YUV 422 Interleaved) YUVY 属于 YUV 422 Interleaved 的一种。事实上,Interleaved 是属于 Packed 的,但是在 422 中,用 Interleaved 更加形象一些。在 Packed 内部,YUV 的排列顺序是 Y U V Y,两个 Y 共用一组 UV。
UYVY(属于 YUV 422 Interleaved) UYVY 属于 YUV 422 Interleaved 的一种。在 Packed 内部,YUV 的排列顺序是 UYVY,两个 Y 共用一组 UV。
三、总结
其中打包格式(如YUYV)多见于老旧采集设备,现代系统已逐步淘汰。其实用的多的还是YUV420,其中NV12,NV21较为常见。

四、YUV图片数据分析
YUV 这种格式的文件,不像 BMP 文件,BMP 虽然里面也是 RGB 的裸数据,但是 BMP 里面有一些头数据,宽高什么的。
但是 YUV文件格式,没有头信息,没有宽高信息,所以用 7yuv 打开 YUV 文件的时候,需要指定宽高,要指定采样格式是 4:4:4。如果我们有一个 YUV图片,但是忘记了 它的宽高跟采样格式,那就无法正常显示这个 YUV图片。
所以,YUV图片文件除了 原始的像素数据,什么都没有的。由于 4:4:4 跟 RGB24 一样,每个像素占 3 字节,图片宽高是 1920x1080 ,所以这个 YUV图片的大小如下:
SIZE=1920x1080x3=6075KB可以看到,它的大小确实也是6075KB左右:

我们用notpad++打开juren_yuv_444.yuv文件,这里还需要用插件来查看十六进制数据才行。

会发现开头数据大量是0,看一下图片会发现开头大部分都是全黑的像素点,那我们来修改一下这个YUV文件,在最开始修改的话不是很好改,我们大概确定一个位置,我们想在第20行开始将像素点全部改为FF,这样起始地址大概就是1920x3x20=115200=1C200,我们大概就从这个地址附近选一个开始,直接插入FF数据,我们放大一点看:

发现确实出现了白线。
参考资料
数字音视频技术: 谈谈 YUV的采样格式和存储格式 - 夜行过客 - 博客园

