前言:
在「简单了解 iOS CVPixelBuffer (上)」)中,我们了解了CVPixelBuffer
如何创建、修改、以及检查CVPixelBuffer相关的参数。在上篇文末我们有讲到在这篇文章中,我们将了解颜色空间RGB和YUV的区别以及相关的背景知识,然后回过头来再看CVPixelBuffer
中的kCVPixelFormatType
相关的类型。
相信大家对于RGB都不陌生吧,那么YUV大家是否了解呢,它为我们做了些什么?
在开篇我先提出一个问题:为什么要使用YUV呢? 这个问题在我们了解了颜色空间之后,相信大家心中就已经有了答案。接下来开始我们的正文。
颜色空间
颜色空间一词源于英文的Color Space
,在色彩学中,人们建立了多种颜色模型,以一维、二维、三维甚至四维空间坐标来表示某一色彩,这种用坐标系统来定义的颜色范围即颜色空间。
我们经常用到的颜色空间主要有RGB、YUV、CMYK、HSB、HSL
等,其中RGB
和YUV
是视频中使用较多的两种色彩空间。
RGB
RGB
是由红(Red)、绿(Green)、蓝(Blue)三种颜色组成,我们称为三原色。每个颜色可以取值不同,将三种颜色相混合后,会组成其他的不同的颜色。使用 RGB
表示的图像中,每个像素都有红、绿、蓝三种颜色,每个颜色占8 bit
,即1 byte
。所以一个像素占用3 byte
。
红、绿、蓝三个颜色通道每种颜色各分为256阶亮度,取值为0-255
。
在存储时,我们常常以R
G
B
或者B
G
R
的顺序进行排列,所以在前文中,我们有看到pixelFormatType有kCVPixelFormatType_32RGBA
、kCVPixelFormatType_32BGRA
两种相似的类型(这里的A指的是Alpha
,Alpha
通道一般用作不透明度参数),其实这两个类型只是它们的编码上的顺序不同;
接下来我们熟悉下另一个颜色空间。
YUV
YUV 是 Y’UV、YUV、YCbCr、YPbPr 等色彩空间的统称
YUV
是由 Y
和 UV
组成,前者表示明亮度 (Luminance、Luma)
,后者表示色度(Chrominance、Chroma)
,色度包括两个⽅面:色调、饱和度。
使用YUV的图像,每个像素点都包含 Y、U、V
分量,Y
和UV
分量是分离的,如果只有Y
没有UV
,那么图像就像以前的黑白电视机一样。为了兼容老式电视机,彩色电视机采用的也是 YUV
的颜色空间,不过UV
是存在的。
采样格式
YUV采样格式是个重点,YUV采样格式有三种:
- YUV 4:4:4
- YUV 4:2:2
- YUV 4:2:0
YUV444
YUV444代表每个Y分量分别对应一个U分量和一个V分量。
以4个像素为例:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为:Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3
YUV422
YUV422代表每两个Y分量分别共用一个U分量和一个V分量。
以4个像素为例:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
存放的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3
映射出像素点为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]
YUV420
YUV420代表每四个Y分量分别共用一个U分量和一个V分量。
以8个像素为例: [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]
综上来看,YUV444的存储的数据量和RGB相同,YUV422是RGB的2/3,YUV420是RGB的1/2。
存储方式
YUV有两种存储方式,一种是打包(packed
),一种是平面(planar
).
packed
: 先连续存储所有Y分量,然后交叉存储U、V分量;planar
:先连续存储所有Y分量,然后在连续存储U、V分量(保证了每个区块连续);
在懂得这些颜色空间的编码格式以及存储方式之后,我们再来看上文中的这些类型的定义,就可以依据这些理论推导出来这些类型代表什么了;
比如说:444、422、420
表示不同的采样格式(压缩比)8、10、16
表示bit位数Planar、BiPlanar
表示平面、双平面VideoRange、FullRange
其意义是YUV颜色空间中亮度部分 Y
的取值范围,fullRange
的取值范围为luma=[0,255] chroma=[1,255]
,而videoRange
的取值范围为luma=[16,235] chroma=[16,240]
。
1 | kCVPixelFormatType_422YpCbCr8 = '2vuy', /* Component Y'CbCr 8-bit 4:2:2, ordered Cb Y'0 Cr Y'1 */ |
写在最后
看到这里,为什么要使用YUV呢? 我想每个人心中都已经有了答案。
YUV的优势基本上也已经一目了然,因为压缩率比RGB要高很多,所占的数据存储量相对较小,所以适用于内存中传输视频数据或者处理图像等等一系列的操作。