YCbCr与RGB的转换

2021年6月9日 / 22次阅读 / Last Modified 2021年6月9日
图像处理

YCbCr与RGB分别表示两种不同的颜色空间,即用什么方式来表示pixel的颜色数据。YCbCr来自YUV这个术语(有人说是用于模拟时代),现在这两个词我感觉基本上指同样的东西。YCbCr的出现(或者YUV是的出现),是为了彩色电视和黑白电视的兼容,Y表示luma,视频码流中的亮度分量,黑白电视只能显示这个;再加上两个颜色分量Cb和Cr,就是彩色的了。

现在计算机内,颜色的显示都是RGB模式,而视频编解码使用的大多都是YCbCr信号(YCbCr提供了最初的数据压缩,主流的420采样模式,直接就砍掉了一半的视频数据,参考学习YCbCr)。因此,就有了相互转换的需要。

下面的转换系数不太对,好晕!看wiki吧:https://en.wikipedia.org/wiki/YUV

有3个转换标准,BT470<BT601(SDTV)和BT709(HDTV)。

BT470:

Y = 0.299*R + 0.587*G + 0.114*B
Cb = 0.564*(B - Y)
Cr = 0.713*(R - Y)
R = Y + 1.402*Cr
G = Y - 0.344*Cb - 0.714*Cr
B = Y + 1.772*Cb

从这个计算公式可看出,Cb和Cr有可能是负数,网上有人通过+128来规避,在转回RGB的时候,在-128。其实没必要,统一看做8bit的unsigned char数据即可!

考虑到计算速度,用矩阵计算的方式来转换也是可以的:

>>> to_yuv
array([[ 0.299,  0.587,  0.114],
       [-0.169, -0.331,  0.5  ],
       [ 0.5  , -0.419, -0.08 ]])
>>>
>>> to_rgb
array([[ 1.   ,  0.   ,  1.402],
       [ 1.   , -0.344, -0.714],
       [ 1.   ,  1.772,  0.   ]])
>>>
>>> a = np.array((12,23,34))
>>> a
array([12, 23, 34])
>>> to_rgb @ to_yuv @ a
array([12.052486, 22.972402, 34.005148])

BT709与BT601,只是转换系数上有点不同:

这个计算有性能需求,基本思路就是想办法避免浮点数计算,避免乘法,或者采用查表的方法!

-- EOF --

本文链接:https://www.pynote.net/archives/3708

留言区

《YCbCr与RGB的转换》有5条留言

您的电子邮箱地址不会被公开。 必填项已用*标注

  • 麦新杰

    Y的范围是 16到235 UV的范围是 16到240 RGB的范围是 0到255 [回复]

  • 麦新杰

    关于YUV的公式,除了有BT601/BT709协议,还有BT2020 协议 。BT2020的YUV转换公式和BT601 BT709都是不同的,但是两者的取值范围是相同的,一般HD视频(1080p)使用BT601 转换, UHDTV(4k或8K)使用BT2020协议转换 , 若视频信号中无色域标志或者色彩转换矩阵 , 默认使用BT601即可, ffmpeg转rgb也是这样操作的。 [回复]

  • 麦新杰

    UV和RGB互转要考虑的东西有两个一个是Matrix,是BT601还是BT709,还是4K时代的BT2020,,Ycgco不同的matrix的色彩范围不一样 数值也有差第二个是range,YUV里TV和PC显示器的数值范围不一样8bit位深的情况下TVrange是16-235(Y)、16-240(UV)PCrange是0-255而RGB没有range之分,全是0-255! [回复]

  • 麦新杰

    https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion,本文python代码部分,对应的数据应该是BT601 [回复]

  • 麦新杰

    https://en.wikipedia.org/wiki/YUV,看这个!! [回复]


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top