一般的视频采集芯片输出的码流一般都是 YUV
格式数据流, 后续视频处理也是对 YUV
数据流进行编码和解析. 所以, 了解 YUV
数据流对做视频领域的人而言, 至关重要
在介绍 YUV
格式之前, 首先介绍一下我们熟悉的 RGB
格式
RGB
RGB
分别表示红 (R)、绿 (G)、蓝 (B), 也就是三原色, 将它们以不同的比例叠加, 可以产生不同的颜色
那么,一张 1920 * 1280 大小的图片, 就占用 1920 * 1280 * 3 / 1024 / 1024 = 7.03MB 存储空间
YUV
YUV
编码采用了明亮度和色度表示每个像素的颜色。
其中 Y
表示明亮度 (Luminance 、Luma), 也就是灰阶值
U
、V
表示色度 (Chrominance 或 Chroma), 描述的是色调和饱和度
YCbCr
其实是 YUV
经过缩放和偏移的翻版. 其中 Y
与 YUV
中的 Y
含义一致,Cb
,Cr
同样都指色彩, 只是在表示方法上不同而已. YCbCr
其中 Y
是指亮度分量, Cb
指蓝色色度分量, 而 Cr
指红色色度分量
YUV 优点
对于 YUV
所表示的图像, Y
和 UV
分量是分离的. 如果只有 Y
分量而没有 UV
分离,那么图像表示的就是黑白图像. 彩色电视机采用的就是 YUV
图像, 解决与和黑白电视机的兼容问题, 使黑白电视机也能接受彩色电视信号
人眼对色度的敏感程度低于对亮度的敏感程度. 主要原因是视网膜杆细胞多于视网膜锥细胞, 其中视网膜杆细胞的作用就是识别亮度, 视网膜锥细胞的作用就是识别色度. 所以, 眼睛对于亮度的分辨要比对颜色的分辨精细一些
利用这个原理, 可以把色度信息减少一点, 人眼也无法查觉这一点
所以, 并不是每个像素点都需要包含了 Y
、U
、V
三个分量, 根据不同的采样格式, 可以每个 Y
分量都对应自己的 UV
分量, 也可以几个 Y
分量共用 UV
分量. 相比 RGB
, 能够节约不少存储空间
YUV 采样格式
YUV 图像的主流采样方式有如下三种
- YUV 4:4:4 采样
- YUV 4:2:2 采样
- YUV 4:2:0 采样
YUV 4:4:4
YUV 4:4:4 表示 Y、U、V 三分量采样率相同,即每个像素的三分量信息完整,都是 8bit, 每个像素占用 3 个字节, 如图所示:
四个像素为: [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]
可以看到这种采样方式与 RGB 图像大小是一样的
YUV 4:2:2
YUV 4:2:2 表示 UV 分量的采样率是 Y 分量的一半, 如图所示:
四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
采样的码流为: Y0 U0 Y1 V1 Y2 U2 Y3 U3
映射出的像素点为:[Y0 U0 V1]、[Y1 U0 V1]、[Y2 U2 V3]、[Y3 U2 V3]
其中, 每采样一个像素点, 都会采样其 Y 分量, 而 U、V 分量都会间隔采集一个, 映射为像素点时, 第一个像素点和第二个像素点共用了 U0、V1 分量, 以此类推… 从而节省了图像空间
可以看出, 比 RGB
节省了三分之一的存储空间
YUV 4:2:0 (主流 + 划重点)
YUV 4:2:0 并不意味着不采样 V 分量. 它指的是对每条扫描线来说, 只有一种色度分量以 2:1 的采样率存储, 相邻的扫描行存储不同的色度分量. 也就是说, 如果第一行是 4:2:0
, 下一行就是 4:0:2
, 在下一行就是 4:2:0
,以此类推:
图像像素为:
[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
映射出的像素点为:
[Y0 U0 V5]、[Y1 U0 V5]、[Y2 U2 V7]、[Y3 U2 V7]
[Y5 U0 V5]、[Y6 U0 V5]、[Y7 U2 V7]、[Y8 U2 V7]
其中, 每采样一个像素点, 都会采样 Y
分量, 而 U
、V
分量都会隔行按照 2:1
进行采样
相比 RGB
, 节省了一半的存储空间
其中YUV420P和YUV420SP根据U、V的顺序, 又可分出2种格式:
YUV420P
: U前V后即YUV420P
, 也叫I420
, V前U后, 叫YV12
YUV420SP
: U前V后叫NV12
, V前U后叫NV21
数据排列如下:
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P
NV12: YYYYYYYY UV UV =>YUV420SP
NV21: YYYYYYYY VU VU =>YUV420SP
为啥会有这么多格式,经过大量搜索发现原因是为了适配不同的电视广播制式和设备系统, 比如 ios 下只有这一种模式
NV12
, 安卓的模式是NV21
, 比如YUV411
、YUV420
格式多见于数码摄像机数据中, 前者用于NTSC
制, 后者用于PAL
制 (NTSC、PAL、SECAM三大制式简介)
YUV 存储格式
YUV
数据有两种存储格式: 平面格式
(planar format) 和打包格式
(packed format)
planar format
: 先连续存储所有像素点的Y
, 紧接着存储所有像素点的U
, 随后是所有像素点的V
packed format
: 每个像素点的Y
、U
、V
是连续交错存储的
因为不同的采样方式和存储格式, 就会产生多种 YUV
存储方式, 这里只介绍基于 YUV422
和 YUV420
的存储方式
YUV420P 和 YUV420SP
YUV420P
是基于 planar
平面模式进行存储,先存储所有的 Y
分量,然后存储所有的 U
分量或者 V
分量
YUV 与 RGB 转换
YUV
与 RGB
之间的转换, 就是将 图像所有像素点的 R
、G
、B
分量和 Y
、U
、V
分量相互转换
常规转换: (YUV转换RGB)
YUV420
转换 RGB
:
R = Y + 1.402 * 0.5V
G = Y -0.34413 * 0.5U - 0.71414 * 0.5V
B = Y + 1.772 * 0.5U
YUV420P
转换 RGB
:
fYmul = y * 1.1643828125;
r = fYmul + 1.59602734375 * v - 0.870787598;
g = fYmul - 0.39176171875 * u - 0.81296875 * v + 0.52959375;
b = fYmul + 2.01723046875 * u - 1.081389160375;
参考资料: