About YUV Video

  今天在看 Media Foundation 文档的时候翻到一篇叫“About YUV Video”文章,感觉对理解 YUV color space 很有帮助,一激动就翻译了;),晾在这里分享一下。

注 1:为了严格区分 luma、luminance 和 brightness,故保留 luma 和 luminance 未译。
注 2:在表示单独的色彩饱和度时,将 chroma 译作饱和度;在表示 U、V 这两个量时,将 chroma 译作色度。

关于 YUV 视频

数字视频经常被编码成 YUV 格式。这篇文章解释了 YUV 视频的一般概念和一些术语,而不会深入到 YUV 视频处理的数学理论中去。

如果你曾经接触过 CG,你大概比较熟悉 RGB 颜色。一个 RGB 色彩由三个值构成:红、绿和蓝。这些值直接对应于可见光谱的一部分。这三个 RGB 值构成的数学坐标系统称作颜色空间(color space)。红色分量定义了这个坐标系统中的一个轴,蓝色分量定义了第二个,绿色定义了第三个。任何一个 RGB 颜色都会落在这个颜色空间的某处。例如纯品红是 100% 的蓝色,100% 的红色和 0% 的绿色。

尽管 RGB 是一种常见的颜色表示方法,但是用其它坐标系统来表示颜色也是可行的。术语 YUV 代表了一族颜色空间,它们的共同点是把亮度信息和色彩信息分开来编码。跟 RGB 一样,YUV 也用三个值来表示所有颜色。这些值被称为 Y’、U 和 V(事实上,“YUV”这种用法严格来讲是不正确的。在计算机视频里,YUV 几乎总是代表一个我们稍后要进行讨论的叫 Y’CbCr 的颜色空间。尽管如此 YUV 经常被当作一个通用术语来表示那些跟 Y’CbCr 有着相同原来的颜色空间)。

Y’(也被称作 luma)用来表示颜色的亮度值。撇号(’)用来把 luma 跟另外一个意义接近的值加以区分区分,这个值就是 luminance(这个值用 Y 做标记)。Luminance 源自线性 RGB 值,而 luma 源自非线性(gamma-corrected)RGB 值。Luminance 是一个跟真实亮度接近的值,但是由于技术原因,实践中 luma 更常用一些。撇号经常被省略,但是 YUV 颜色空间总是使用 luma 而不是 luminance。

Luma 源自 RGB 颜色,但是要在红、绿、蓝分量上做个加权平均。对于标清(standard-definition)视频, 使用如下公式:

Y’ = 0.299R + 0.587G + 0.114B

这个公式反应了人眼对某些特定波长的光更加敏感这一事实,这关系到我们对颜色中亮度的感知。蓝光看上去最暗淡,绿光看上去最亮,红光则介乎其间。这个公式也反映了被用在早期电视中的磷的特性。一个重新考虑了现代电视技术的新公式被用在高清(high-definition)电视上:

Y’ = 0.2125R + 0.7154G + 0.0721B

跟标清电视等价的 luma 定义在一份名为 ITU-R BT.601 的规范中。对于高清电视,相关的规范是 ITU-R BT.709。

U 分量和 V 分量(也被称作饱和度(chroma)和色差(color difference)值),可以通过把原始 RGB 中的红绿分量从 Y 值中减去而得到:

U = Y’ – B

V = Y’ – R

这些值所包含的信息足够把 YUV 值再转换至原始 RGB 值。

YUV 的好处

由于部分历史原因,模拟电视使用 YUV。模拟彩色电视信号被设计成可以向前兼容黑白电视。彩色电视信号在 luma 信号之上叠加了色度信息(U 和 V)。黑白电视会忽略掉色度,把叠加的信号显示成灰度图像(刻意设计过的信号使得色度信号不会干扰到 luma 信号)。彩色电视机能够提取出色度信息从而把信号还原为 RGB。

YUV 还有另外一个跟今天主题更加相关的优点。比起色调的改变,人眼对亮度的改变更加敏感。所以,一幅图像可以携带比 luma 信息更少的色度信息而又不会以牺牲图像质量为代价。例如,比较通用的做法是把水平扫描线上的色度样本数降为 luma 样本数的一半。换句话说,对于一行像素上的每两个 luma 样本,只有一个 U 样本和一个 V 样本与之对应。假定每个值用 8 位来编码,那么每两个像素就需要 4 个字节的空间(两个 Y’,一个 U 和一个 V),这比同等的 24 位 RGB 编码要节约 30% 的空间或者说节约 16 位每像素。

YUV 并不是天生就比 RGB 更加密实。除非色度值被降低采样率,否则一个 YUV 像素跟一个 RGB 像素的尺寸是一样的。从 RGB 到 YUV 的转换是无损的。如果没有降低采样率,一个 YUV 像素可以被无损的转换回 RGB。降低采样率可以让 YUV 图像小一些,同时也会损失一些颜色信息。但是如果转换正确的话,这种损失是难以察觉的。

计算机视频中的 YUV

前面列出来用于 YUV 的公式并不能用来精确的转换数字视频。数字视频通常使用一种叫做 Y’CbCr 的 YUV。本质上,Y’CbCr 要把 YUV 分量缩放到如下取值范围内:

Component Range
Y’ 16-235
Cb/Cr 16-240,128 代表零

这些取值范围假定 Y’CbCr 分量的精度是 8 位。下面是 Y’CbCr 的准确来历,使用 BT.601 中定义的 luma:

  1. 我们把 RGB 的取值范围设定为 [0…1]。换句话说,纯黑是 0,纯白是 1。注意,这里说的是非线性(gamma corrected)RGB 值。

  2. 计算 luma。对于 BT.601,Y’ = 0.299R + 0.587G + 0.114B,参见先前的描述。

  3. 计算中间色度差值(B – Y’)和(R – Y’)。(B – Y’)的取值范围是 +/- 0.886,(R – Y’)是 +/- 0.701。

  4. 按如下方法缩放色度差值:

    Pb = (0.5 / (1 – 0.114)) × (B – Y’)

    Pr = (0.5 / (1 – 0.299)) × (R – Y’)

    这些缩放系数会赋予两个值相同的数值范围,+/- 0.5。它们定义的 YUV 颜色空间叫作 Y’PbPr,这个颜色空间被用在模拟视频分量上。

  5. 缩放 Y’PbPr 值以得到最终的 Y’CbCr值:

    Y’ = 16 + 219 × Y’

    Cb = 128 + 224 × Pb

    Cr = 128 + 224 × Pr

最后的这几个缩放系数用来把数值处理到之前的那个表格里列出的范围内。当然,你也可以不用存储中间结果而把 RGB 直接转换成 Y’CbCr。列在这里的步骤是为了展示 Y’CbCr 是如何从文章一开头的原始 YUV 演化而来的。

下面这个表格展示了不同颜色的 RGB 和 YCbCr 值,同样,这里使用的也是 BT.601 里定义的 luma。

Color R G B Y’ Cb Cr
Black 0 0 0 16 128 128
Red 255 0 0 81 90 240
Green 0 255 0 145 54 34
Blue 0 0 255 41 240 110
Cyan 0 255 255 170 166 16
Magenta 255 0 255 106 202 222
Yellow 255 255 0 210 16 146
White 255 255 255 235 128 128

在上面这张表中,Cb 和 Cr 没有在直觉上反映相应的颜色。例如纯白和纯黑都包含了一个中间值的 Cb 和 Cr(128)。Cb 的最高和最低值分别是蓝色和黄色。Cb 的最高和最低值分别是红色和青色。

Leave a Reply