YUV(YCbCr)与RGB


  注意!本文所涉及的内容皆为 RGB 和 YUV 总述,并没有涉及 10bit 的内容。

  关于 10bit 的内容参见 Microsoft 的文档 10-bit and 16-bit YUV Video Formats

  本文转载自 CSDN,遵循 CC 4.0 BY-SA 协议。

  RGB、YUV和YCbCr三种颜色空间

  图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别

RGB 颜色系统

  RGB 色彩模式是工业界的一种颜色标准,是通过对红、绿、蓝三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB 即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

RGB16

  RGB16 数据格式主要有二种:RGB565RGB555

  • RGB565

每个像素用 16 比特位表示,占 2 个字节,RGB 分量分别使用 5 位、6 位、5 位。


//获取高字节的5个bit
R = color & 0xF800;
//获取中间6个bit
G = color & 0x07E0;
//获取低字节5个bit
B = color & 0x001F;

  • RGB555

每个像素用 16 比特表示,占 2 个字节,RGB 分量都使用 5 位(最高位不用)。


//获取高字节的5个bit
R = color & 0x7C00;
//获取中间5个bit
G = color & 0x03E0;
//获取低字节5个bit
B = color & 0x001F;

RGB24

RGB24 图像每个像素用 8 比特表示,占 1 个字节,注意:在内存中 RGB 各分量的排列顺序为:BGR BGR BGR

RGB32

RGB32 每个像素用 32 比特表示,占 4 个字节,R,G,B 分量分别用 8 个 bit 表示,存储顺序为 B,G,R,最后 8 个字节保留。注意:在内存中RGB各分量的排列顺序为:BGRA BGRA BGRA

  • ARGB32

本质就是带 alpha 通道的 RGB24 ,与 RGB32 的区别在与,保留的 8 个 bit 用来表示透明,也就是 alpha 的值。

  在内存中的分量排列顺序如下:


R = color & 0x0000FF00;
G = color & 0x00FF0000;
B = color & 0xFF000000;
A = color & 0x000000FF;

YUV 和 YCbCr

  YUV 是北美 NTSC 系统和欧洲 PAL 系统中模拟电视信号编码的基础。

  在 YUV 空间中,每一个颜色有一个亮度信号 Y,和两个色度信号 U 和 V。亮度信号是强度的感觉,它和色度信号断开,这样的话强度就可以在不影响颜色的情况下改变。

  YUV 使用 RGB 的信息,但它从全彩色图像中产生一个黑白图像,然后提取出三个主要的颜色变成两个额外的信号来描述颜色。把这三个信号组合回来就可以产生一个全彩色图像。

  Y 通道描述 Luma 信号,它与亮度信号有一点点不同,值的范围介于亮和暗之间。 Luma 是黑白电视可以看到的信号。U (Cb) 和 V (Cr) 通道从红 (U) 和蓝 (V) 中提取亮度值来减少颜色信息量。这些值可以从新组合来决定红,绿和蓝的混合信号。

  YCbCr 颜色空间是 YUV 的国际标准化变种,在数字电视和图像压缩(比如 JPEG )方面都有应用。

  YCbCr 是在世界数字组织视频标准研制过程中作为 ITU - R BT 601 建议的一部分, 其实是YUV 经过缩放和偏移的翻版。其中 Y 与 YUV 中的Y含义一致, Cb , Cr 同样都指色彩, 只是在表示方法上不同而已。在 YUV 家族中, YCbCr 是在计算机系统中应用最多的成员, 其应用领域很广泛,JPEG、MPEG 均采用此格式。一般人们所讲的 YUV 大多是指 YCbCr

YCbCr 采样格式

  主要的采样格式有 YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1 和 YCbCr 4:4:4。其中YCbCr 4:1:1 比较常用,其含义为:每个点保存一个 8bit 的亮度值(也就是Y值), 每 2 x 2 个点保存一个 Cr和Cb值, 图像在肉眼中的感觉不会起太大的变化。所以, 原来用 RGB(R,G,B 都是 8bit unsigned) 模型, 每个点需要 8 x 3 = 24 bits, 而现在仅需要 8 + (8/4) + (8/4) = 12bits, 平均每个点占 12bits。这样就把图像的数据压缩了一半。

  上边仅给出了理论上的示例,在实际数据存储中是有可能是不同的,下面给出几种具体的存储形式:

YUV 4:4:4

  YUV 三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。

  下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]

  存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3

YUV 4:2:2

  每个色差信道的抽样率是亮度信道的一半,所以水平方向的色度抽样率只是4:4:4的一半。对非压缩的8比特量化的图像来说,每个由两个水平方向相邻的像素组成的宏像素需要占用4字节内存(例如下面映射出的前两个像素点只需要Y0、Y1、U0、V1四个字节)。

  下面的四个像素为: [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]

YUV 4:1:1

  4:1:1的色度抽样,是在水平方向上对色度进行4:1抽样。对于低端用户和消费类产品这仍然是可以接受的。对非压缩的8比特量化的视频来说,每个由4个水平方向相邻的像素组成的宏像素需要占用6字节内存

  下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]

  存放的码流为: Y0 U0 Y1 Y2 V2 Y3

  映射出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2]

YUV4:2:0

  4:2:0 并不意味着只有 Y,Cb 而没有 Cr 分量。它指得是对扫描来说,只有色度分量以 2:1 的抽样率存储。相邻的扫描行存储不同的色度分量,也就是说,如果一行是 4:2:0 的话,下一行就是 4:0:2,再下一行是 4:2:0。对每个色度分量来说,水平方向和竖直方向的抽样率都是 2:1,所以可以说色度的抽样率是 4:1。对非压缩的 8 比特量化的视频来说,每个由 2x2 个 2 行 2 列相邻的像素组成的宏像素需要占用 6 字节内存。

  下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] [Y5 U5 V5] [Y6 U6 V6] [Y7U7 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] [Y7U2 V7] [Y8 U2 V7]

格式转换

小技巧

  • RGB 三个色值,如果都是 0 则显示黑色;如果都是 255 则为白色;如果是 在0-255范围内的等值的时候是没有色相,是灰色的

  • YCbCr422 要将 Cb = 0x80 Cr = 0x80 才能看到灰度图。(有人会写成 YUV422,其实是 YCbCr422)

这些小技巧,可以通过以下公式证明。

YCbCr 与 RGB 的转换

  转换公式一定要依据 ITU 的标准,常看到的是ITU.BT-601,ITU.BT-709 和 ITU.BT-2020。

  这里重点介绍 ITU.BT-601[50]。

20161012193325724

  把上述矩阵展开成方程式,如下所示


Y = 0.299 R + 0.587 G + 0.114 B
Cb = -0.1687 R - 0.3313 G + 0.5 B + 128
Cr = 0.5 R - 0.4187 G - 0.0813 B + 128

R = Y + 1.402 (Cr - 128)
G= Y - 0.34414 (Cb - 128) - 0.71414 (Cr - 128)
B= Y + 1.772 (Cb - 128)

  下边的各个符号都带了一撇,表示该符号在原值基础上进行了伽马校正,伽马校正有助于弥补在抗锯齿的过程中,线性分配伽马值所带来的细节损失,使图像细节更加丰富。在没有采用伽马校正的情况下,暗部细节不容易显现出来,而采用了这一图像增强技术以后,图像的层次更加明晰了。


Y = 0.257 * R' + 0.504 * G' + 0.098 * B' + 16
Cb' = - 0.148 * R' - 0.291 * G' + 0.439 * B' + 128
Cr' = 0.439 * R' - 0.368 * G' - 0.071 * B' + 128
R' = 1.164 * (Y - 16) + 1.596 *(Cr' - 128)
G' = 1.164 * (Y - 16) - 0.813 * (Cr' - 128) - 0.392*(Cb' - 128)
B' = 1.164 * (Y - 16) + 2.017 * (Cb' - 128)
    

H.264,H.265 中 YUV 属于 YCbCr

YUV 与 RGB 的转换

  假设已经经过伽马校正,下边的都是带了一撇。

  如下所示


Y'= 0.299*R' + 0.587*G' + 0.114*B'
U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')
V'= 0.615*R' - 0.515*G' - 0.100*B' = 0.877*(R'- Y')

R' = Y' + 1.140*V'
G' = Y' - 0.394*U' - 0.581*V'
B' = Y' + 2.032*U'
    

  是否上YUV与RGB转换公式需要加上128偏移,保证正值,我还没有相关的证据。

[转载] http://blog.sina.com.cn/s/blog_a85e142101010h8n.html

[转载] http://blog.sina.com.cn/s/blog_5713096b0100059i.html

[转载] http://www.fourcc.org/fccyvrgb.php

[参考] 数字图像处理 Java语言算法描述_清华大学出版社_(美)伯格