分类: C/C++
2014-12-22 10:35:59
原文地址:RGB转换至YCbCr(YUV)的计算公式 作者:czysocket_dara
1. 模拟 RGB 讯号转为模拟 Y, (B-Y), (R-Y)
2. 模拟 (B-Y), (R-Y) 转为模拟 Cb, Cr
3. 模拟 YCbCr 数字化(取样、量化)成为数字 YCbCr
4. 模拟 RGB 数字化(取样、量化)成为数字 RGB
5. 数字 RGB 转为数字 YCbCr
1. 的变换式是
Y = 0.299 * R + 0.587 * G + 0.114 * B
(R - Y) = R - 0.299 * R - 0.587 * G - 0.114 * B
= 0.701 * R - 0.587 * G - 0.114 * B
(B - Y) = B - 0.299 * R - 0.587 * G - 0.114 * B
= - 0.299 * R - 0.587 * G + 886 * B
2. 的变换式是
Cr = 0.713 * (R - Y)
= 0.500 * R - 0.419 * G - 0.081 * B
Cb = 0.564 * (B - Y)
= - 0.169 * R - 0.331 * G + 0.500 * B
就是你写的那个变换式。
上式 Y, R, G, B 的范围是 0.0~1.0,Cb, Cr 的范围是 0.5~-0.5。
模拟的 CbCr 通常表记为 PbPr。
由于这些表记的方法很乱,常有人会混合着用,所以写的时候最好注明是模拟还是数字,例如
3. 的模拟 YCbCr 数字化转换式
Y(d) = 219 * Y(a) + 16
Cb(d) = 224 * Cb(a) + 128
Cr(d) = 224 * Cr(a) + 128
Y(a) 代表 analog,Y(d) 代表 digital。
4. 的模拟 RGB 数字化转换式
R(d) = 219 * R(a) + 16
G(d) = 219 * G(a) + 16
B(d) = 219 * B(a) + 16
R(a), G(a), B(a) 的范围是 0.0~1.0,R(d), G(d), B(d) 的范围是 16~235。
加上 (a), (d),这样表记就清楚多了。
5. 的数字 RGB 转为数字 YCbCr
Y = (77 * R(d) / 256) + (150 * G(d) / 256) + (29 * B(d) / 256)
Cb = - (44 * R(d) / 256) - (87 * G(d) / 256) + (131 * B(d) / 256) + 128
Cr = (131 * R(d) / 256) - (110 * G(d) / 256) - (21 * B(d) / 256) + 128
YCbCr: 16~235, RGB: 16~235
这个转换式是 straight 变换,没有 YC 伸张(Full-range,扩展 RGB: 0~255),有 YC 伸张的算式就是你提出的我以前写的那个算式。
这个表记法有点复杂,有的教科书在介绍亮度和色差的时候前面就先花了很多篇幅在定义表记的用法,例如我上面写的还是不及格,因为 BT.601 的 RGB 都要先经过 gamma correction,是 gamma 校正后的 RGB,要表记为 R'G'B' ^^;
还有那个 Y,是 BT.601 的 Y,所以 Y 的右下角要加上一个底字写 601,或者左上角要写 601,这样人家才知道你是 BT.601 定义的 Y,不是 BT.709 定义的 Y ^^;;
由于名词太多有点乱,许多人会混合着用,同样一个 YUV,有时候我们搞不清楚作者指的到底是数字的 YCbCr,还是模拟的 YPbPr,是 NTSC 的 YIQ,还是 PAL 的 YUV,是 601 的 YUV,还是 709 的 YUV,或者是 SMPTE 240M 的 YUV .... XD
有的时候作者在表记上没有明写,不过根据上下文意,我们可以猜出他说的是哪一个。
您看的那本书 ;) 有注明列的是 ITU-R recommendation BT.601 [1] 的 YCbCr 转换式,所以是模拟转换式,不是 BT.601-5。
当然用比较通用的 PbPr 来表示模拟色差是比较清楚的写法。
ITU 的建议书(recommendation)只要登记成为会员,每年都可以免费下载三本,601, 709, H.263 ..等等都可以免费下载 :D
由 source code 可以得知,XviD 和大部分的软件一样是遵照这本书的标准转换式作的
算式为
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
这个算式是模拟 YCbCr 和模拟 RGB 的转换式,这是很多人会被弄迷糊的地方。