3、YUV域基础:颜色空间转换、采样格式与ISP中的位置
好,我们进入YUV域。说实话,很多做图像处理的工程师,做了好几年,对YUV的理解还是停留在“Y是亮度,UV是色度”这个层面。但真要动手做降噪,你会发现,不懂YUV的细节,根本调不好参数。
我个人习惯把YUV域称为“工程域”。为什么?因为人眼对亮度敏感,对颜色不敏感。YUV就是利用这个特性,把亮度和颜色分开处理。你想想看,降噪算法要是直接在RGB上做,三个通道一起抖,计算量大不说,还容易把颜色搞偏。YUV域就不一样了——你可以对Y通道做强降噪,对UV通道做弱降噪,甚至不做。效果又好,速度又快。
3.1 颜色空间转换:RGB → YUV
先看数学。RGB到YUV的转换,本质是一个线性变换。不同标准(BT.601、BT.709、BT.2020)的系数略有不同,但结构一样。我项目中用得最多的是BT.601标准,适合720p及以下分辨率。4K以上我建议用BT.709。
公式长这样(BT.601,有限范围):
Y = 0.299 * R + 0.587 * G + 0.114 * B
U = -0.169 * R - 0.331 * G + 0.500 * B + 128
V = 0.500 * R - 0.419 * G - 0.081 * B + 128
注意那个+128。U和V是有符号数,范围-128~127,加上128后变成0~255的无符号数。很多新手在这里栽跟头——直接拿公式算,结果UV通道一片黑。嗯,我刚开始也犯过这个错。
反过来,YUV到RGB的转换:
R = Y + 1.402 * (V - 128)
G = Y - 0.344 * (U - 128) - 0.714 * (V - 128)
B = Y + 1.772 * (U - 128)
3.2 YUV采样格式:4:4:4 / 4:2:2 / 4:2:0
采样格式,说白了就是“UV通道的分辨率打几折”。人眼对颜色细节不敏感,所以我们可以把UV的分辨率降下来,节省带宽和存储。这是视频编码和ISP pipeline里的基本操作。
| 格式 | Y分辨率 | U分辨率 | V分辨率 | 数据量(相对RGB) | 典型场景 |
|---|---|---|---|---|---|
| 4:4:4 | 全分辨率 | 全分辨率 | 全分辨率 | 100% | 专业调色、屏幕截图 |
| 4:2:2 | 全分辨率 | 水平1/2 | 水平1/2 | 67% | 广播级视频、HDMI采集 |
| 4:2:0 | 全分辨率 | 水平1/2,垂直1/2 | 水平1/2,垂直1/2 | 50% | 消费级视频、JPEG、H.264 |
4:2:0是最常见的格式。你手机拍的照片、录的视频,绝大多数都是4:2:0。为什么?因为省一半带宽,画质损失肉眼几乎看不出来。
但注意——降噪算法如果在4:2:0的YUV上直接做,UV通道的分辨率已经丢了。你处理U和V的时候,其实是在处理“半张图”。我遇到过有人把UV降噪强度设得和Y一样,结果色块边缘出现奇怪的锯齿。后来查了半天,才发现是UV分辨率不匹配导致的。
3.3 YUV在ISP中的位置
ISP pipeline里,YUV域的位置非常关键。它通常在去马赛克(Demosaic)之后、色彩校正(CCM)之后、但还在编码(JPEG/H.264)之前。说白了,RGB域做完颜色还原,转到YUV域做降噪和锐化,最后再编码输出。
我画了一张流程图,帮你理清这个位置关系:
从图上你能看到:RAW进来,先去马赛克变成RGB,再经过CCM做色彩校正,然后转到YUV域。在YUV域里,Y通道和UV通道是分开处理的。Y通道做降噪+锐化,UV通道只做降噪。最后合在一起编码输出。
为什么锐化只做在Y通道?因为锐化本质是增强高频信息。UV通道的高频基本都是噪声,你一锐化,色噪全出来了。我见过有人把锐化做到RGB三个通道上,结果图像边缘出现彩色过冲,看着特别假。
3.4 避坑指南
最后,我总结几个我在项目中踩过的坑:
- 转换精度不够: 我曾经在定点DSP上实现RGB2YUV,直接用8位整数算,结果Y通道出现条带。后来改成16位中间精度,问题解决。
- UV边界处理: 4:2:0的UV分辨率只有Y的1/4。做降噪时,滤波核大小要按UV的实际分辨率来算。别把Y的核直接套到UV上。
- 色彩溢出: YUV转RGB时,如果Y和UV的范围没对齐,转出来的RGB可能超出0~255。一定要做clamp,否则图像会出现诡异的颜色。
- 编码器不认: 有些编码器只接受特定范围的YUV(比如有限范围16~235)。你输出全范围0~255,编码器会裁掉暗部和亮部细节。记得在编码前做range mapping。
嗯,YUV域的基础就这些。记住一句话:YUV域是降噪算法的舒适区。把亮度和颜色分开,你的算法设计会轻松很多。