先给出YUV格式的定义:
YUV是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式采用的颜色空间。
YUV名词解释和原理:
YUV的原理是,将亮度和色度分离,根据人眼的特性,相对于色度,人对亮度更敏感一些。
利用这个特性我们可以适当的减少色度的信息。
在YUV的三个字母中,“Y”表示亮度,“U”和“V”表示色度。
在一些技术文档里,YUV还有其他的一些名字,主要的有这2个:YCbCr和YPbPr。
YCbCr:Y与YUV中的解释一致,表示亮度。
Cb/Cr中,C代表分量,Cb表示的就是蓝色分量信号,Cr表示的是红色分量信号。
Y除了亮度信号外,还叠加了绿色分量信号。数字信号是YCbCr,JPEG和MPEG2都采用的是此格式。
YCbCr表示隔行扫描色差输出,是属于YUV经过缩放和偏移的翻版。
YPbPr:YCbCr在模拟分量视频也称为YPbPr。
YPbPr是将模拟的Y,Pb,Pr信号分开,使用三条线缆来独立输出,
保障了色彩还原的准确性,YPbPr表示逐行扫描色差输出。
YUV的存储格式:
先简要说明一下bpp比特每像素:表示一个像素点所能取到的不同颜色数取决于bpp。Max_bpp = 2^颜色深度。
常见的取值有8bpp =2^8 = 256色,16bpp高彩色,24bpp真彩色,48bpp用于专业扫描仪,TIFF文件。
对于超过8位的深度,这些数位就是三个分量(红绿蓝)的各自的数位的总和。
一个16位的深度通常分为5位红色和5位蓝色,6位绿色(眼睛对于绿色更为敏感)。
24位的深度一般是每个分量8位。
在有些系统中,32位深度也是可选的:这意味着24位的像素有8位额外的数位来描述透明度。
在RGB格式中,一个24bpp像素要占用4个字节空间。
在YUV中可以对于uv色度分量进行压缩,但对图像质量影响不大,所以YUV所占空间要比RGB要小。
YUV存储与RGB格式最大的不同在于,RGB格式每个点的数据是连续保存在一起的,即 RGBRGBRGBRGB....
而在YUV中,每个Y分量独立存储,但是连续几个点的U,V保存在一起,这几点个合起来称为marco-pixel,
这种存储格式称为packed格式(打包格式)。
另外一种存储格式是把一幅图像中Y,U,V分别用三个独立的数组表示。
这种模式称为planar模式(平面格式)。
YUV的采样格式:
先介绍一个好东西:FourCC码。
FourCC全称Four-Character Codes,代表四字符代码 (four character code),
它是一个32位的标示符,其实就是typedef unsigned int FOURCC;是一种独立标示视频数据流格式的四字符代码。
视频播放软件通过查询 FourCC 代码并且寻找与 FourCC 代码相关联的视频解码器来播放特定的视频流。
传统的FourCC码的生成方式为:
#define MAKE_FOURCC(a,b,c,d) \
( ((uint32_t)d) | ( ((uint32_t)c) << 8 ) | ( ((uint32_t)b) << 16 ) | ( ((uint32_t)a) << 24 ) )
下面所用的采样格式也可以通过FourCC码来表示。
我们一般用YUV三者的比率来表示不同的格式,主要有YUV444,YUV422,YUV420,YUV411。
YUV444:
FourCC 码为 AYUV,表示色度UV分量没有减少采样。
即Y,U,V各占一个字节,透明分量Alpha再占一个字节。共占4个字节,这就和RGB 24bpp是一样的。
每个像素都被组织为4个连续字节,组织顺序如下所示:
YUV422:
表示UV分量减半采样。比如第一个点采样YU,第二个点采样YV,这样每个点占2个字节,16位。
2个像素组成了一个宏像素。
支持2个4:2:2格式,FourCC码为:
第一种,YUY2,
第一个字节包含第一个 Y 样例,
第二个字节包含第一个 U (Cb) 样例,
第三个字节包含第二个 Y 样例,
第四个字节包含第一个 V (Cr) 样例,如图所示 :
在小端模式下,(即低地址存放低位,高地址存放高位),看作由两个WORD 值组成的数组,
则第一个 WORD 在最低有效位 (LSB) 中包含 Y0,在最高有效位 (MSB) 中包含 U。
第二个 WORD 在 LSB 中包含 Y1,在 MSB 中包含 V。
第二种,UYVY,只是将YUY2中的亮度和色度的字节序反一下。如图所示:
YUV420:
表示每4个点隔点只取U,隔行后每4个点隔点只取V
这种采样并不是说有Y和Cb,而没有Cr。而是说Cb和Cr分量隔行才采样一次。
比如第一行采样4:2:0,第二行采样4:0:2....以此类推。
举个实例:
原本的8个像素点:
【Y0,U0,V0】【Y1,U1,V1】【Y2,U2,V2】【Y3,U3,V3】
【Y4,U4,V4】【Y5,U5,V5】【Y6,U6,V6】【Y7,U7,V7】
经过YUV420采样,得到:
【Y0,U0】【Y1】【Y2,U2】【Y3】
【Y4,V4】【Y5】【Y6,V6】【Y7】
支持6种4:2:2格式,FourCC码为:
第一种,IMC1,所有 Y 样例都会作为不带正负号的char值组成的数组首先显示在内存中。
后面跟着所有 V (Cr) 样例,然后是所有 U (Cb) 样例。
V 和 U 平面与 Y 平面具有相同的跨距,从而生成如图 8 所示的内存的未使用区域。
如图所示:
第二种,IMC3,和IMC1类似,只是V和U平面进行了交换而已。
第三种,IMC2,此格式与 IMC1 相同,只是 V (Cr) 和 U (Cb) 行在半跨距边界处进行了交错。
换句话说,就是色度区域中的每个完整跨距行都以一行 V 样例开始,
然后是一行在下一个半跨距边界处开始的 U 样例(图 10)。
此布局与 IMC1 相比,能够更加高效地利用地址空间。它的色度地址空间缩小了一半,
因此整体地址空间缩小了 25%。在各个 4:2:0 格式中,IMC2 是第二首选格式,排在 NV12 之后。
如图所示:
第四种,IMC4,和IMC2类似,只是V和U平面进行了交换而已。
第五种,YV12,所有 Y 样例都会作为不带正负号的char值组成的数组首先显示在内存中。
此数组后面紧接着所有 V (Cr) 样例。
V 平面的跨距为 Y 平面跨距的一半,V 平面包含的行为 Y 平面包含行的一半。
V 平面后面紧接着所有 U (Cb) 样例,它的跨距和行数与 V 平面相同。
如图所示:
第六种,NV12,所有 Y 样例都会作为由不带正负号的char值组成的数组首先显示在内存中,并且行数为偶数。
Y 平面后面紧接着一个由不带正负号的char值组成的数组,其中包含了打包的 U (Cb) 和 V (Cr) 样例,
如图 13 所示。
当组合的 U-V 数组被视为一个由小端WORD值组成的数组时,
LSB 包含 U 值,MSB 包含 V 值。NV12 是用于 DirectX VA 的首选 4:2:0 像素格式。如图所示: