Camera 数据格式 YUV 详解
概述
上一个小节我们聊到 Camera 项目项目中常用的几种图像颜色的表示方法,并重点讲述了常用的 RAW、RGB、RGBA 格式。YUV 格式伴随着视频行业的快速发展,衍生出非常复杂YUV 格式定义,比如 YUV444、YUV422、YUV420、YUV420、YUV420SP、YUV422P 等等格式。笔者从业多年,经常备受 YUV 格定义的困扰,遂作此外,与大家解惑共勉。
欢迎来到视频世界-初识YUV 格式
RGB 的世界是丰富多彩的,但是代价是数据量太大,比如 RGB888 格式的数据,一个像素对应 24bits 的数据,那么 100w 个像素,即需要 100w * 24bits的数据量。另一个方面,有时颜色信息并不重要,我们只需要物体的轮廓就好了。比如传统的黑白电视,或者一些图像处理中的灰度图:
考虑到减小数据量、并且有时只需要灰度图像就够了的这种需求。所以,相关的视频协议组织定义了 YUV 的颜色格式。其中:
- “Y” 表示明亮度(Luminance、Luma),用于指定该像素感知的明亮程度。
- “U” 和 “V” 则是色度、浓度(Chrominance、Chroma),作用是描述影像色彩、饱和度,用于指定对应像素的颜色。上面的灰度图就是只有 Y 像素值时的图像,没有U、V则无法反映彩色信息,U+V 可以通称为 Chroma。
从原始 YUV 图像中可以分离出对应的 Y、U、V 分量。下图来自 wiki 百科,从上至下,依次是原图、以及Y,Cb和Cr三个分量。
YUV 格式与 RGB 格式的数据可以相互转换
通常我们所用的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
引入 YUV 这种色彩空间的好处有哪些?
- YUV 可以同时兼容黑白和彩色电视。对于黑白电视,其提取 Y 亮度信号(即 Only Y),显示黑白视频,对于彩色电视,其使用完整的 YUV,显示彩色画面。
- 科学研究表明,人眼对 UV 的敏感性小于亮度,这样可以适当减少 UV 的数据量,而不影响人的感官。所以才会有多种格式的 YUV描述,如 YUV420、YUV422、YUV444等。
- YUV 格式和 RGB 格式可以相互转换,但是 YUV 格式可以比 RGB 格式数据量更小,因此可以节省储存空间、传输带宽。
- 一些视频处理器只能输入 YUV 格式的数据。
YUV 格式如何减小图像的数据量
与 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 子采样命名的规则
YUV[j][a][b]的命名规则是:
- j,第一行的参考像素点个数,通常为4
- a,第一行的 j 个参考像素点产生的数据中包含几个chrome (即U+V,下面表述为UV) 分量
- b,与第一行的参考像素点紧挨的第二行的 j 个参考像素点产生的数据中包含几个chrome (即U+V,下面表述为UV) 分量。
YUV444(8bit)
YUV444 是指第一行的 4 个参考像素点在生成YUV数据时,该行的四个像素每个像素点对应 4个Y+4个UV分量,第二行的4个参考像素点在生成YUV数据时,该四个像素每个像素点也对应 4个Y+4个UV分量。如下所示,共有 1~8 八个像素,其每个像素在生成对应的数据时,都保留了独立的 Y、U、V分量。
- YUV444(8bit)是指每个Y、U、V分量值均有 8bit 组成,此时每个像素对应24bits = 3*8(图示在每个带颜色的圆形代表一个 8bit 的值)。
- YUV444(10bit) 是指每个Y、U、V分量值均有 10bit 组成,此时每个像素对应30bits = 3*10,即便每个值都比 8bit 格式多出 2bit 的信息,但是因为这种格式并不能显著改善图像的质量,其实并不常用。我们后续的讨论都基于 8bit 的这种表示方法进行讨论。
- 在YUV444格式中,每个像素点都生成了对应的Y、U、V数据。这种格式主要应用在视频处理设备内部,外部用的不多,避免画面质量在处理过程中降低。
在使用对应的 YUV444 数据时: - 像素1的值在使用时,实际使用的YUV值是,Y1+U1+V1,下标是对应像素的索引。
- 像素2的值在使用时,实际使用的是:Y2+U2+V2。
YUV422
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分量:
- 像素1的值在使用时,实际使用的YUV值是,Y1+U1+V1,下标是对应像素的索引。
- 像素2的值在使用时,实际使用的是:Y2+U1+V1。
相比上述 YUV444 这无疑会导致颜色有一些误差,但是两个相邻像素的颜色在大多数在情况上应该没有什么差异。与此同时,相比 YUV444平均每个像素生成的数据大小为 24bits,YUV422 平均每个像素的数据大小减小为 16bits,数据小了,对于视频信号的传输和存储都是非常有益的。
当然,一些摄像头也许使用下述这种方式生成 YUV422 数据,UV 在哪里产生并不重要,重要的是共享 UV 这种思路:
在使用上述对应的 YUV422 数据时:
- 像素1的值在使用时,实际使用的YUV值是,Y1+U1+V2,下标是对应像素的索引。
- 像素2的值在使用时,实际使用的是:Y2+U1+V2。
- 像素3的值在使用时,实际使用的是:Y3+U3+V4。
- 像素4的值在使用时,实际使用的是:Y4+U3+V4。
误差分析:比较两种 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
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分量:
- 像素1的值在使用时,实际使用的YUV值是,Y1+U1+V1,下标是对应像素的索引。
- 像素2的值在使用时,实际使用的是:Y2+U1+V1。
- 像素3的值在使用时,实际使用的是:Y3+U1+V1。
- 像素4的值在使用时,实际使用的是:Y4+U1+V1。
与YUV422类似,YUV411 在生成数据时也可以如下采样:
在使用对应的数据时:
- 像素1的值在使用时,实际使用的YUV值是,Y1+U3+V1,下标是对应像素的索引。
- 像素2的值在使用时,实际使用的是:Y2+U3+V1。
- 像素3的值在使用时,实际使用的是:Y3+U3+V1。
- 像素4的值在使用时,实际使用的是:Y4+U3+V1。
YUV411的这种子采样模式,相比上述 YUV422 这无疑会导致生成的数据有一些误差,但是几个相邻像素的颜色在大多数在情况上应该没有什么差异。与此同时,相比 YUV422 平均每个像素生成的数据大小为 16bits,YUV411 平均每个像素的数据大小减小为 12bits,数据更小了,对于视频信号的传输和存储都是非常有益的。
YUV420
在电视屏幕、消费电子的屏幕做的越来越大情况下,图像的像素点个数急剧增加。需要进一步减小每个像素点平均的大小。
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分量:
- 像素1的值在使用时,实际使用的YUV值是,Y1+U1+V1,下标是对应像素的索引。
- 像素2的值在使用时,实际使用的是:Y2+U1+V1。
- 像素5的值在使用时,实际使用的YUV值是,Y5+U1+V1,下标是对应像素的索引。
- 像素6的值在使用时,实际使用的是:Y6+U1+V1。
这种子采样方式当然也会有误差,但是几个相邻像素的颜色在大多数在情况上应该没有什么差异。于此同时,相比 YUV422 平均每个像素生成的数据大小为 16bits,YUV420 平均每个像素的数据大小减小为 12bits,数据更小了,对于视频信号的传输和存储都是非常有益的。
另一当面,虽然 YUV420 和 YUV411 在数据大小上都是 12bits,但是其在水平方向上颜色损失更小,因为 YUV420 在水平方向产生了两个 UV 分量,而 YUV411 在水平方向每行上只产生一个 UV 分量。现在的显示技术,通常都是 16:9的大屏幕,即屏幕的长宽比为16:9。这种在水平方向大于垂直方向的屏幕设计,促进了 YUV420 格式在视频领域的发展。
YUV440
在了解上面的示例后,我相信在看到这幅图时,大家应该可以知道它的名字-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互转要考虑两个问题:
- 转换Matrix,是BT601还是BT709,还是4K时代的BT2020,不同的matrix的色彩范围不一样,数值也有差;
- 范围Range,YUV里TV和PC显示器的显示数值范围不一样,在8bit位深的情况下,TV的range是16-235(Y)、16-240(UV),而PC的range是0-255,RGB没有range之分,全是0-255!
-
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 的颜色失真小一些。
总结
- 视频行业的发展提出了 YUV 的数据格式。YUV 格式相比 RGB 数据更容易缩小数据量,并且保持图像的信息。
2)YUV 格式 “Y” 表示明亮度(Luminance、Luma),用于指定该像素感知的明亮程度。“U” 和 “V” 则是色度、浓度(Chrominance、Chroma),作用是描述影像色彩、饱和度,用于指定对应像素的颜色。
3)YUV 通过 Subsampling,即子采样来降低数据量的大小,根据子采样的方式,可以分为:YUV444、YUV422、YUV411、YUV420、YUV440 等。