Metal--RGBA与YUV

在看这篇文章的时候,我们需要带着几个问题。

  • 什么是YUV?
  • 为什么视频采集要用YUV而不用RGBA?
  • RGB和YUV的区别以及关联?

RGB(A)颜⾊编码

三原色指色彩中不能再分解的三种基本颜色,我们通常说的三原色,是色彩三原色以及光学三原色。而光学三原色就指的是红(R),绿(G),蓝(B)。由RGB可以组成任何颜色。
在图像显示中,一张图片可以分解成无数个像素点组成,而这个像素点就可以用RGB来表示。而A表示的透明度Alpha,通常来说在视频的播放中透明度为1,所以我们这里不讨论A

RGB.png

如上图所示,图中的某个像素点是用RGB组成,假如一张图片的尺寸为1280 * 720,那么这个图片的大小是多少呢?

RGB 图像中,每个像素点都有红、绿、蓝三个原⾊,其中每种原⾊都占⽤8 bit,也就是⼀个字节,那么⼀个像素点也就占⽤ 24 bit,也就是三个字节。
那么这个图片的小就是:

//图片大小
1280 * 720 * 3 / 1024 / 1024 = 2.63 MB

竟然有2.63M,这还只是1帧,那么一个小时的电影,一秒有60帧没,那么视频将会占用无比巨大空间,所以用RGBA格式保存视频是不可取的。

YUV颜色编码

定义

YUV 颜⾊编码采⽤的是 明亮度 和 ⾊度 来指定像素的颜⾊。其中,Y 表示明亮度(Luminance、Luma),⽽ U 和 V 表示⾊度(Chrominance、Chroma)。⽽⾊度⼜定义了颜⾊的两个⽅⾯:⾊调饱和度

YUV.png

和 RGB 表示图像类似,每个像素点都包含 Y、U、V 分量。但是它的Y 和 UV 分量是可以分离的,如果没有 UV 分量⼀样可以显示完整的图像,只不过是⿊⽩的

4:4:4采样格式

YUV 4:4:4采样意味着 Y、U、V 三个分量的采样⽐例相同,即每个像素点都会采样Y、U、V分量


4:4:4.png

蓝色的⭕️代表Y分量,☆代表UV分量

假如有A,B,C,D4个点像素为[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采样方式的并没有差别,所以我们一般不用4:4:4的采样方式

4:2:2采样格式

YUV 4:2:2 采样,意味着 UV 分量是 Y 分量采样的⼀半,Y 分量和 UV 分量按照 2 : 1 的⽐例采样。如图所示,假如一行有4个像素点,那么Y分量则是4个,而UV分量则是2个,Y:UV = 2:1

4:2:2.png

蓝色的⭕️代表Y分量,☆代表UV分量

假如有A,B,C,D4个点像素为[Y0,U0,V0],[Y1,U1,V1],[Y2,U2,V2],[Y3,U3,V3]
那么按照YUV4:2:2 采样的码流为: Y0,U0,Y1,V1,Y2,U2,Y3,V3
那么最终还原的结果还是为[Y0,U0,V0],[Y1,U1,V1],[Y2,U2,V2],[Y3,U3,V3]


假如一张图片的尺寸为1280 * 720,那么这个图片的大小是多少呢?

  //图片大小
(1280 * 720 * 8 + 1280 * 720 * 0.5 * 8 * 2)/ 8 / 1024 / 1024 = 1.76 MB

可以看到比RGB采样的方式节省了大约1/3的内存,而且传输时的带宽也能节省。

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 分量。


4:2:0.png

如上图所示,4:2:0的扫描方式,在第一行隔列扫描U点,比如A点扫描U0,C点扫描U1点;在第二行隔列扫描V点,比如E点扫描V0,G点扫描V1点。所以ABEF点共用了U0、V0,CDGH共用了U1、V1。

假如原始像素点为[Y0 U0 V0],[Y1 U1 V1],[Y2 U2 V2],[Y3 U3 V3],[Y5 U5 V5],[Y6 U6 V6],[Y7 U7 V7],[Y8 U8 V8]
那么按照YUV4:2:2 采样的码流为: 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]


假如一张图片的尺寸为1280 * 720,那么这个图片的大小是多少呢?

  //图片大小
(1280 * 720 * 8 + 1280 * 720 * 0.25 * 8 * 2)/ 8 / 1024 / 1024 = 1.32 MB 

可以看到用4:2:0的方式,能节省更多的 内存。

RGB与YUV之间的转换

RGB 到 YUV 的转换,就是将图像所有像素点的 R、G、B 分量转换到 Y、U、V 分量。
公式如下:

  • RGB转YUV
Y = 0.299 * R + 0.587 * G + 0.114 * B 
U = -0.147 * R - 0.289 * G + 0.436 * B 
V = 0.615 * R - 0.515 * G - 0.100 * B
  • YUV转RGB
R = Y + 1.14 * V 
G = Y - 0.39 * U - 0.58 * V 
B = Y + 2.03 * U

总结

通过实际的代码,我们可以看到用YUV的编码方式,从采集源头做起,可以节省相当可观的内存,这些节省的内存不论是对存储还是对传输都有相当大的意义。

你可能感兴趣的:(Metal--RGBA与YUV)