上一个小节我们聊到 Camera 项目项目中常用的几种图像颜色的表示方法,并重点讲述了常用的 RAW、RGB、RGBA 格式。YUV 格式伴随着视频行业的快速发展,衍生出非常复杂YUV 格式定义,比如 YUV444、YUV422、YUV420、YUV420、YUV420SP、YUV422P 等等格式。笔者从业多年,经常备受 YUV 格定义的困扰,遂作此外,与大家解惑共勉。
RGB 的世界是丰富多彩的,但是代价是数据量太大,比如 RGB888 格式的数据,一个像素对应 24bits 的数据,那么 100w 个像素,即需要 100w * 24bits的数据量。另一个方面,有时颜色信息并不重要,我们只需要物体的轮廓就好了。比如传统的黑白电视,或者一些图像处理中的灰度图:
考虑到减小数据量、并且有时只需要灰度图像就够了的这种需求。所以,相关的视频协议组织定义了 YUV 的颜色格式。其中:
通常我们所用的YUV格式是 ITU-R 的标准 , 也叫YCbCr(并不总是如此,这需要和具体的产品支持人员确认, 笔者认为 YCbCr 是 YUV 的格式之一,YUV 只是代表一种颜色域空间)。其中 Cb 反映了 RGB 输入信号蓝色部分与信号亮度值 Y 之间的差异;其中 Cr 反映 RGB 输入信号红色部分与信号亮度值 Y 之间的差异。视频行业的标准有很多(背后是不同显示器厂商的较量),不同标准下 RGB 与 YUV 相互转换的公式是不一样的,ITU-R BT.601 标准下 RGB 转 YCbCr 的公式为:
Y : Y = 0.299 x R + 0.587 x G + 0.114 x B + 0
U : Cb = -0.169 x R - 0.331 x G + 0.499 x B + 128
V : Cr = 0.499 x R - 0.418 x G - 0.0813 x B + 128
与 RGB 格式类似,对于彩色图像,要知道一个像素点实际的颜色值,需要知道该像素的Y、U、V 三个值,每个值假设用 8bit 表示,则整体数据量为每个像素对应 24bits,即 24bits/pixel。假设想传输一个 100w 像素的视频,这个数据量对于高清电视,网络摄像头的视频传输而言太大了。
在 RGB 数据生成 YUV 数据时可以通过子采样(Subsampling)来减小平均每个像素对应的数据量。由于人的眼睛对亮度信息比色彩信息更加敏感,因此可以保留更多记录亮度信息的Y值,减少记录色彩信息的U、V值。这种减少U、V数据量的方式就是子(局部)采样。
根据子采样的方式,通常有YUV444、YUV422、YUV411和YUV420几种。简单来说,所谓子采样,就是生成数据时只留下部分U、V数据,使用数据时根据约定的规则使用相邻像素的色彩信息补齐需要的U、V数据的一种方法。莫着急,接下来我们细细道来。
YUV[j][a][b]的命名规则是:
YUV444 是指第一行的 4 个参考像素点在生成YUV数据时,该行的四个像素每个像素点对应 4个Y+4个UV分量,第二行的4个参考像素点在生成YUV数据时,该四个像素每个像素点也对应 4个Y+4个UV分量。如下所示,共有 1~8 八个像素,其每个像素在生成对应的数据时,都保留了独立的 Y、U、V分量。
YUV422 是指第一行的 4 个参考像素点在生成YUV数据时,该行的四个像素对应 4个Y+2个UV分量,同时第二行的4个参考像素点在生成YUV数据时,第二行的四个像素对应 4个Y+2个UV分量。如下所示,共有 1~8 八个像素。其每个像素在生成对应的数据时,都保留了独立的 Y分量,但是水平方向上做了舍弃。具体是指在水平方向上,每4个像素,共用临近的U、V 分量。
在使用对应的 YUV422 数据时,像素1、2共用一组UV分量,像素3、4共用一组UV分量:
相比上述 YUV444 这无疑会导致颜色有一些误差,但是两个相邻像素的颜色在大多数在情况上应该没有什么差异。与此同时,相比 YUV444平均每个像素生成的数据大小为 24bits,YUV422 平均每个像素的数据大小减小为 16bits,数据小了,对于视频信号的传输和存储都是非常有益的。
当然,一些摄像头也许使用下述这种方式生成 YUV422 数据,UV 在哪里产生并不重要,重要的是共享 UV 这种思路:
在使用上述对应的 YUV422 数据时:
误差分析:比较两种 YUV422 格式在子采样方式上的异同?
第一种方式中,像素1对应的数据是Y1+U1+V1、像素2对应的数据是Y2+U1+V1,误差在像素2上发生。在第二种方式中,像素1对应的数据是Y1+U1+V2、像素2对应的数据是Y2+U1+V1,误差在像素1、像素2上均发生。它们虽然数据量相同,但是误差却是不一样的。另外,在软硬件实现上,其实更多的也是第一种方式,即像素1产生 Y+UV 分量,通常 UV 分量是在一个像素点上生成的,不单独记录一个像素点的U、或者V量。在不同的标准、显示器中 YUV422 在实际的采样方式上会有区别,第一种方式是 BT601 标准默认的采样方式。
不管怎么记录这个数据,生成数据时,舍弃同行的相邻像素的U、V值、使用数据时,通过借用相邻像素的U、V值,恢复对应像素的颜色的这种思想是一致的。
YUV411 是指第一行的 4 个参考像素点在生成YUV数据时,该行的四个像素对应 4个Y+1个UV分量,同时第二行的4个参考像素点在生成YUV数据时,第二行的四个像素对应 4个Y+1个UV分量。如下所示,共有 1~8 八个像素。其每个像素在生成对应的数据时,都保留了独立的 Y分量,但是水平方向上做了舍弃。具体是指在水平方向上,每4个像素,共用临近的U、V 分量。
在使用对应的数据时,像素1、2、3、4共用一个 UV 分量,像素5、6、7、8共用一个UV分量:
与YUV422类似,YUV411 在生成数据时也可以如下采样:
在使用对应的数据时:
YUV411的这种子采样模式,相比上述 YUV422 这无疑会导致生成的数据有一些误差,但是几个相邻像素的颜色在大多数在情况上应该没有什么差异。与此同时,相比 YUV422 平均每个像素生成的数据大小为 16bits,YUV411 平均每个像素的数据大小减小为 12bits,数据更小了,对于视频信号的传输和存储都是非常有益的。
在电视屏幕、消费电子的屏幕做的越来越大情况下,图像的像素点个数急剧增加。需要进一步减小每个像素点平均的大小。
YUV420 是指第一行的 4 个参考像素点在生成YUV数据时,该行的四个像素对应 4个Y+2个UV分量,同时第二行的4个参考像素点在生成YUV数据时,第二行的四个像素对应 4个Y+0个UV分量。如下所示,其中的 1~8 八个像素,其每个像素在生成对应的数据时,都保留了独立的 Y分量,但是水平方向、垂直方向上都做了舍弃。具体是指在水平方向上,每2个像素,共用临近的U、V 分量,同时,垂直方向上,隔行生成UV分量的数据。
在使用对应的数据时,像素1、2、5、6共用一组UV分量,3、4、7、8共用一组UV分量:
这种子采样方式当然也会有误差,但是几个相邻像素的颜色在大多数在情况上应该没有什么差异。于此同时,相比 YUV422 平均每个像素生成的数据大小为 16bits,YUV420 平均每个像素的数据大小减小为 12bits,数据更小了,对于视频信号的传输和存储都是非常有益的。
另一当面,虽然 YUV420 和 YUV411 在数据大小上都是 12bits,但是其在水平方向上颜色损失更小,因为 YUV420 在水平方向产生了两个 UV 分量,而 YUV411 在水平方向每行上只产生一个 UV 分量。现在的显示技术,通常都是 16:9的大屏幕,即屏幕的长宽比为16:9。这种在水平方向大于垂直方向的屏幕设计,促进了 YUV420 格式在视频领域的发展。
在了解上面的示例后,我相信在看到这幅图时,大家应该可以知道它的名字-YUV440:
YUV444、YUV422、YUV420 在颜色损失上,最坏情况下,哪个误差最大?
当然是数据量最小的 YUV420。
YUV422(10bit) 这种格式的数据,每个像素平均几个 bit?
欢迎老铁与我学习讨论。
下述生成数据的方式是 YUV420 吗?
是的,YUV的这种定义,只定义了 Y 与UV分量的比例,并没有定义哪个像素点生成U、V分量。只需要看一个各种在有几个Y就知道有几个像素了,知道有几个像素后,了解其与UV分量的关系就知道是哪种采样模式了。
YUV422、YUV420、YUV411 均导致颜色损失,最坏情况下,我们看到的图像可能是什么样的?
不管哪一种子采样,总是保留了 Y 分量(也称Y通道、Y向量、Y channel)的准确。最坏情况下我们也能看清物体的轮廓,只是物体的彩色颜色会是错误的。这正是引入 YUV 这种格式的意义所在,保证物体的轮廓清晰,降低人眼不敏感的色彩信息占用的数据。
图像压缩、视频项目中为什么更喜欢 YUV 格式而不是 RGB?
正是因为 YUV 格式总是能保持物体轮廓(即保留Y向量),适当减少 UV 分量可以带来更小的数据量,所以图像压缩、视频传输类型的项目都是喜欢 YUV 格式。
与上节讲述的 RGB 域类似,YUV 也有 limit range、full range 之分如何选择?
1)limit range 的各个分量的范围为: YUV Y∈[16,235] Cb∈[16-240] Cr∈[16-240] 。也称为TV range 、video range。
limit range 之所以在视频影音领域用的较多,是因为电影电视剧通常有特效需求,limit range 可以更方便的实现特效如隐藏吊威亚细节的处理。BT606 标准中,一些格式通过 I 标识这种 limit range,如I420。
2)full range 的各个分量的范围均为:0-255 。PC机显卡输出的为full range模式。一些格式通过 F 标识这种 limit range,如F420。
YUV 与 RGB 互转要注意什么?
YUV和RGB互转要考虑两个问题:
RGB、YUV 在一次视频传输中的存在形式是如何的?
相机产生的通常是 RGB 数据,在内部或者外部转换为 YUV 数据,将 YUV 数据编码为指定的视频格式如H264之类的,传输到电视上,电视恢复出 YUV 数据,经过专用的模块再转换为 RGB 数据投射到 LCD 屏幕上。
YUV400 这种格式代表什么意思?
没有 UV 分量,实际是 Only Y,也可以表示为 Only luma.
JPEG 适用 YUV 还是 RGB 进行压缩?
YUV。YUV 正是为了保持图像轮廓,减少数据信息提出的表示方法,JPEG 目的是为了减小数据量。因此 JPEG 后台使用的往往是 YUV 数据。如 JPEG 4:2:2, JPEG 4:2:0,分别是对 YUV422、YUV420 压缩得来的,当然,YUV422 所含的颜色信息更多,因此同等压缩级别下,YUV422 的颜色失真小一些。