BT.601 / T.871:与RGB(16位)之间的转换

问题描述 投票:1回答:1

我正在尝试在16位输入的RGB和YCbCr之间进行T.871转换。对于8位信号,这些方程式很容易读取。如果我们在第4页的T.871第§7节中进行检查,则会得到:

Y  = Min( Max( 0, Round( 255 * E'Y ) ), 255 )
Cb = Min( Max( 0, Round( 255 * E'Cb + 128 ) ), 255 )
Cb = Min( Max( 0, Round( 255 * E'Cr + 128 ) ), 255 )

[...]

Y  = Min(Max( 0, Round(   0.299 * R + 0.587 * G + 0.114 * B)), 255 )
Cb = Min(Max( 0, Round(( -0.299 * R - 0.587 * G + 0.886 * B)/1.772 + 128 )), 255 )
Cr = Min(Max( 0, Round((  0.701 * R - 0.587 * G - 0.114 * B)/1.402 + 128 )), 255 )

[至小数点后四位的精度可以近似为:

Y  = Min(Max( 0, Round(  0.299  * R + 0.587  * G + 0.114  * B)), 255 )
Cb = Min(Max( 0, Round( -0.1687 * R - 0.3313 * G + 0.5    * B + 128 )), 255 )
Cr = Min(Max( 0, Round(  0.5    * R - 0.4187 * G - 0.0813 * B + 128 )), 255 )

[我可以验证BT.601第2.5.1节中的E'Y,E'Cb和E'Cr的方程式2.5.1亮度的构造[...]:

E'Y = 0.299 * E'R + 0.587 * E'G + 0.114 * E'B

以及第2.5.2节,重新归一化的色差信号的构造[...]:

E'Cr = ( 0.701 * E'R - 0.587 * E'G - 0.114 * E'B) / 1.402
E'Cb = (-0.299 * E'R - 0.587 * E'G + 0.886 * E'B) / 1.772

因此,我对16位信号的(天真的)解释很简单:

 Y  = Min(Max( 0, Round(   0.299 * R + 0.587 * G + 0.114 * B)), 65535 )
 Cb = Min(Max( 0, Round(( -0.299 * R - 0.587 * G + 0.886 * B)/1.772 + 32768 )), 65535 )
 Cr = Min(Max( 0, Round((  0.701 * R - 0.587 * G - 0.114 * B)/1.402 + 32768 )), 65535 ) 

我尝试了快速的C代码来验证这一点,但这似乎上述方程式是不正确的。

所以我的问题是:将RGB 16位信号转换为YCbCr的方程是什么?

参考:

colors rgb color-space
1个回答
0
投票

您的16位转换是正确

  • [为了进行精确比较,我删除了round-将所有值都保留为double类型(仅出于测试目的)。
  • 比较8位和16位Cb,Cr时最重要,最令人困惑的事情是offset:您需要在缩放(或除以256)之前减去偏移量:

假设您有Cb8Cb16,并且要检查比率是否为256,您需要做的第一件事是从128中减去Cb8,然后从32768中减去Cb16。减法运算就像将值居中在零附近。

示例:

Pb8 = Cb8 - 128
Pb16 = Cb16 - 32768

现在您可以比较Pb8Pb16之间的比率:

Pb16 == Pb8*256

我曾经遵循过MATLAB代码(比C更容易:

R = 50;G = 100;B = 150; %Initialize RGB to arbitrary values.

%8 bits conversion
Y  = min(max( 0, (   0.299 * R + 0.587 * G + 0.114 * B)), 255 );
Cb = min(max( 0, (( -0.299 * R - 0.587 * G + 0.886 * B)/1.772 + 128 )), 255 );
Cr = min(max( 0, ((  0.701 * R - 0.587 * G - 0.114 * B)/1.402 + 128 )), 255 );

%Convert RGB to 16 bits.
scale = 256; %Assume conversion from 8 to 16 bits is scale by 256 (not scale by 65535/255).
R = R*scale;
G = G*scale;
B = B*scale;

%16 bits conversion
Y2  = min(max( 0, (   0.299 * R + 0.587 * G + 0.114 * B)), 65535 );
Cb2 = min(max( 0, (( -0.299 * R - 0.587 * G + 0.886 * B)/1.772 + 32768 )), 65535 );
Cr2 = min(max( 0, ((  0.701 * R - 0.587 * G - 0.114 * B)/1.402 + 32768 )), 65535 );

Ydiff = Y*scale - Y2
Cb_diff = (Cb - 128)*scale - (Cb2 - 32768)
Cr_diff = (Cr - 128)*scale - (Cr2 - 32768)

结果:

Ydiff = 0
Cb_diff = 0
Cr_diff = 0

我想以下等式适用没有偏移的CrCb(我叫PbPr)。

E'Cr = ( 0.701 * E'R - 0.587 * E'G - 0.114 * E'B) / 1.402
E'Cb = (-0.299 * E'R - 0.587 * E'G + 0.886 * E'B) / 1.772

对于8位:

Cr = E'Cr + 128
Cb = E'Cb + 128

对于16位:

Cr = E'Cr + 32768
Cb = E'Cb + 32768
© www.soinside.com 2019 - 2024. All rights reserved.