RGB转YUV

今天对颜色一些格式转换有些不明白的地方,在网上找了一些文章,感谢原作者,现张贴如下:
颜 色空间是一个三维坐标系统,每一种颜色由一个点表示。在 RGB 颜色空间中,红,绿,蓝是基本元素。RGB 格式是显示器通常使用的格式。在 YUV 空间中,每一个颜色有一个亮度信号 Y,和两个色度信号 U 和 V。亮度信号是强度的感觉,它和色度信号断开,这样的话强度就可以在不影响颜色的情况下改变。YUV 格式通常用于 PAL制,即欧洲的电视传输标准,而且缺省情况下是图像和视频压缩的标准。

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

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

YUV和RGB的转换:
Y = 0.299 R + 0.587 G + 0.114 B
U = -0.1687 R - 0.3313 G + 0.5 B + 128
V = 0.5 R - 0.4187 G - 0.0813 B + 128
R = Y + 1.402 (V-128) G
= Y - 0.34414 (U-128) - 0.71414 (V-128) B
= Y + 1.772 (U-128)
以前,一直没明白yuvYcbCr之间的差异,想必有些朋友也会有同样的疑惑。所以,我看完之后就记载下来了。
一、和rgb之间换算公式的差异
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'
yCbCr<-->rgb
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)
Note: 上面各个符号都带了一撇,表示该符号在原值基础上进行了gamma correction
二、来源上的差异
yuv色彩模型来源于rgb模型,
该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。
应用:basic color model used in analogue color TV broadcasting.
YCbCr模型来源于yuv模型。YCbCr is a scaled and offset version of the YUV color space.
应用:数字视频,ITU-R BT.601 recommendation

通过上面的比较可以确定,我们在h.264,mpeg等编码标准中用的yuv其实是YcbCr,大家不要被名称搞混淆了。
<think>嗯,用户想知道如何将RGB颜色空间换为YUV颜色空间。首先,我需要回忆一下这两种颜色空间的基本概念。根据引用[2],RGB是基于红、绿、蓝三原色的加色系统,而YUV则是用亮度和色差来描述颜色。Y代表亮度,U和V是色度分量。 接下来,我得找出具体的换公式。用户提供的引用[1]里有YUVRGB的公式,但用户需要的是反向换,也就是RGBYUV。通常,这些换是可逆的,可以通过矩阵运算来实现。不过要注意引用[3]提到的非线性RGB,即经过伽马校正的R'G'B',可能需要调整公式。 根据常见的换方法,RGBYUV的公式可能与引用[1]中的相反。比如,亮度Y通常是R、G、B的加权和,而色度U和V则是基于颜色差异。常见的系数可能是Y = 0.299R + 0.587G + 0.114B,U = (B - Y) * 0.564,V = (R - Y) * 0.713。不过需要确认这些系数是否正确,并参考引用中的信息。 另外,引用[4]提到在编程实现时,数据类型的溢出问题,需要将unsigned char改为int类型处理中间结果,避免数值超过255或低于0。所以在代码实现时,需要注意变量类型和范围限制。 可能还需要考虑不同的YUV标准,比如YCbCr和YPbPr的区别,如引用[3]所述,不同的标准可能使用不同的系数矩阵。因此,在给出换公式时,需要明确使用的是哪一种标准,并选择合适的系数。 总结步骤应该是:1. 确定RGB是线性还是非线性,是否需要伽马校正;2. 选择合适的换矩阵;3. 实现矩阵运算,注意数据类型和溢出处理;4. 验证换结果是否正确,可能通过引用中的例子或实验来测试。 现在需要将这些整理成结构清晰的回答,包括公式、步骤、代码示例和注意事项,并生成相关问题。</think>### RGBYUV颜色空间的实现方法 #### 一、理论基础 RGBYUV换基于颜色空间的线性变换关系。根据亮度分量(Y)和色度分量(U/V)的定义,换公式可表示为矩阵运算: $$ \begin{bmatrix} Y \\ U \\ V \end{bmatrix} = \begin{bmatrix} 0.299 & 0.587 & 0.114 \\ -0.147 & -0.289 & 0.436 \\ 0.615 & -0.515 & -0.100 \end{bmatrix} \begin{bmatrix} R \\ G \\ B \end{bmatrix} + \begin{bmatrix} 0 \\ 128 \\ 128 \end{bmatrix} $$ [^2][^3] 其中: - $Y$ 取值范围 $0 \sim 255$ - $U/V$ 取值范围 $0 \sim 255$(偏移后) #### 二、实现步骤 1. **数据范围处理**:将原始RGB值从 $0 \sim 255$ 映射到 $-128 \sim 127$ 2. **矩阵乘法**:应用换矩阵计算原始YUV值 3. **偏移调整**:对U/V分量加128保证正值 4. **边界约束**:通过饱和运算确保结果在 $0 \sim 255$ 范围内 #### 三、C语言实现示例 ```c void RGB2YUV(int R, int G, int B, int* Y, int* U, int* V) { // 核心换计算 *Y = 0.299*R + 0.587*G + 0.114*B; *U = -0.147*R - 0.289*G + 0.436*B + 128; *V = 0.615*R - 0.515*G - 0.100*B + 128; // 数值饱和处理 *Y = (*Y > 255) ? 255 : (*Y < 0 ? 0 : *Y); *U = (*U > 255) ? 255 : (*U < 0 ? 0 : *U); *V = (*V > 255) ? 255 : (*V < 0 ? 0 : *V); } ``` #### 四、注意事项 1. **数据类型**:必须使用int类型处理中间结果,防止溢出(如直接使用unsigned char会导致计算结果错误)[^4] 2. **伽马校正**:若原始RGB是经过伽马校正的非线性值(R'G'B'),需先进行逆伽马校正[^3] 3. **标准差异**:不同标准(YCbCr/YPbPr)系数略有不同,需确认具体应用场景 #### 五、验证方法 1. **极端值测试**:例如纯红色(255,0,0)应满足: $$ Y = 0.299×255 ≈ 76 $$ $$ V = 0.615×255 + 128 ≈ 255 $$ 2. **反向验证**:将YUV换回RGB后与原值对比误差
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值