RGB到YCbCr(YUV)转换

公式

RGB to YCbCr

Y = a * R + b * G + c * B
Cb = (B - Y) / d
Cr = (R - Y) / e

YCbCr to RGB

R = Y + e * Cr
G = Y - (a * e / b) * Cr - (c * d / b) * Cb
B = Y + d * Cb
BT.601/JPEG BT.709 BT.2020
a 0.299 0.2126 0.2627
b 0.587 0.7152 0.6780
c 0.114 0.0722 0.0593
d 1.772 1.8556 1.8814
e 1.402 1.5748 1.4746

d和e这两个参数是为了让Cb和Cr落在-0.5~0.5区间才引入的(使之具有与明度信号Y相同的幅值,便于工程实现),计算方法如下:
d = (1 - c) / 0.5
e = (1 - a) / 0.5

这些系数是怎么来的,为什么要取这些值?
a, b, c这三个系数是在ITU标准中定义的,表明了RGB三原色需要以何种比例混合来生成明度信号Y,这个比例与三原色的选取有关(因为不同波长的光对亮度的贡献也不同),参考规范文档:
https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.601-7-20...
https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.709-6-20...
https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2020-2-2...

备注:BT.709, Rec.709, ITU-T709说的都是一个东西

量化

通过上述公式计算出的Y, Cb, Cr并不是最终结果,ITU规定明度与色度信号并不能占满量程,比如0~1v电压范围,明度信号取值范围是0.06v~0.86v,其有效幅值为满量程的80%,色度信号取值范围稍大,其作用是避免滤波器导致的过冲。

对于数字信号,ITU给出的量化公式如下:

\( D_Y' = INT[(219E_Y' + 16) \cdotp 2^{n-8}] \)
\( D_{CB}' = INT[(224E_{CB}' + 128) \cdotp 2^{n-8}]\)
\( D_{CR}' = INT[(224E_{CR}' + 128) \cdotp 2^{n-8}] \)

上述公式中,\( E_Y' \), \( E_{CB}' \), \( E_{CR}' \)为取值范围[0, 1]的浮点数,n为位深(一般为8bit,10bit和12bit),INT为四舍五入取整(round),\( D_Y' \), \( D_{CB}' \), \( D_{CR}' \)为最终要送编码器的YUV数据。

注意:JPEG并不会将Y, Cb, Cr做量化,即使用满量程[0, 255]。

色度采样

采样间隔

  • 444: 没有对色度信号下采样(没有色度损失)
  • 422: 仅在水平方向对色度信号下采样,采样比为1:2(损失1/2色度)
  • 420: 水平与垂直方向均对色度信号下采样,采样比为1:2(损失3/4色度)
  • 411: 仅在水平方向下采样,采样比为1:4(损失3/4色度,不常用)

RGB到YCbCr(YUV)转换_第1张图片

封装形式

  • packet: YUV按照一定顺序放在一个大数组中
  • planar: YUV分别放在不同的数组中

参考资料:
https://learn.microsoft.com/en-us/windows/win32/medfound/reco...
https://www.cs.auckland.ac.nz/courses/compsci773s1c/lectures/...

实现

FFmpeg

https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/colorspace.h

重点看YUV_TO_RGB1_CCIR()/YUV_TO_RGB1_CCIR_BT709()YUV_TO_RGB2_CCIR(),其实现了BT601和BT709两种色彩空间YUV到RGB的转换。

我自己的实现

https://github.com/zhanwang-sky/jpeg_helper/tree/main/jpeg_helper/yuv_helper

重点看RGB_to_PlanarYUV()PlanarYUV_to_RGB(),实现了I420格式的YUV、RGB转换,可以试试不同色彩空间以及是否做量化(是否使用满量程)对图片颜色的影响。

结论

YUV到RGB转换需考虑色彩空间量化的影响,需搞清楚视频源的色彩标准才能得到正确的结果,此外还需要考虑伽马曲线对图片色彩的影响。

你可能感兴趣的:(RGB到YCbCr(YUV)转换)