3、YUV色彩空间:YUV420、YUV422、YUV444的区别,以及它在视频编码中的核心地位

说到图像格式,很多人第一反应就是RGB。毕竟屏幕上的每个像素,最终都要拆成红绿蓝三个分量来显示。但如果你做过视频编码,就会知道——RGB在视频领域其实是个“奢侈品”。

为什么?因为人眼对亮度的敏感度远高于对颜色的敏感度。你想想看,哪怕画面颜色稍微偏一点,你可能都察觉不到;但亮度只要差一点点,画面就会显得“脏”或者“过曝”。YUV色彩空间就是抓住了这个心理,把亮度和颜色分开处理。

3.1 什么是YUV?

YUV其实是一个大家族。Y代表亮度(Luma),U和V代表色度(Chroma)。说白了,Y管画面的明暗细节,U和V管画面的颜色信息。

我在项目中遇到过不少新手,以为YUV就是某种压缩格式。其实不是。YUV只是一种色彩表示方式,就像RGB一样。只不过它天生就适合做压缩——因为我们可以对色度信息“偷工减料”,人眼还看不出来。

核心概念:YUV将亮度与色度分离,使得我们可以对色度进行降采样,从而大幅减少数据量,同时保持视觉质量几乎不变。

3.2 YUV420、YUV422、YUV444的区别

这三个格式的区别,说白了就是“色度采样率”不同。数字越大,色度保留得越完整,数据量也越大。

格式 色度采样方式 数据量(相对于RGB) 典型应用
YUV444 每个像素都有完整的Y、U、V 3倍(无压缩) 专业调色、无损编辑
YUV422 每2个像素共享一组U、V 2倍 广播级视频、高端采集
YUV420 每4个像素共享一组U、V 1.5倍 流媒体、视频通话、H.264/H.265

嗯,这里要注意。YUV420虽然名字里带“420”,但它并不是YUV444的“一半”。实际上,它的色度分辨率在水平和垂直方向都减半了。所以4个像素才共享一组UV。

我的习惯:在移动端做视频处理时,我几乎只用YUV420。因为它的数据量只有RGB的一半,而且绝大多数编码器原生支持。你想想看,一个1080p的RGB帧要6MB,换成YUV420只要3MB——这差距在实时编码里就是生与死的区别。

3.3 为什么YUV在视频编码中占据核心地位?

这个问题其实很简单。视频编码的本质就是“去掉冗余信息”。而YUV天生就给了你一个“合法作弊”的机会——色度可以降采样,人眼还看不出来。

我举个例子。H.264编码器内部,所有运动估计、变换量化、熵编码,都是基于YUV420来做的。为什么?因为标准就是这么定的。你如果非要用RGB或者YUV444去喂编码器,它也能处理,但效率会大打折扣。

为什么会这样?因为编码器在设计时,就假设了色度信息是“稀疏”的。它会把更多的比特分配给Y分量,而给U、V分量更少的比特。这样一来,同样的码率下,YUV420的画面看起来比RGB清晰得多。

我曾经踩过的坑:有一次做视频采集,我直接从摄像头拿到的数据是YUV422的。我心想“422比420好”,就直接喂给编码器了。结果编码器报错,说输入格式不匹配。后来才发现,很多硬件编码器只支持YUV420输入。如果你非要喂422,得先自己做一次降采样。嗯,从那以后我再也不偷懒了。

3.4 实际项目中的选择建议

我个人习惯是这样选的:

  • 做流媒体、视频通话、短视频:无脑选YUV420。这是最通用的格式,兼容性最好,编码效率最高。
  • 做专业调色、电影后期:用YUV444。因为你要保留完整的色度信息,方便后期做色彩校正和特效合成。
  • 做广播级采集、高端直播:用YUV422。它比420保留更多色度细节,又比444节省带宽,是个折中方案。

你想想看,一个视频编码器,如果连YUV420都不支持,那它基本没法用。反过来,如果你在做视频处理时,能熟练地在YUV和RGB之间切换,那你的工具箱就比别人多了一把利器。

一句话总结:YUV420是视频编码的“默认语言”,YUV422是“专业级”,YUV444是“无损级”。选哪个,取决于你的应用场景和带宽预算。

好了,这一章就到这里。下一章我们会深入YUV420的内存布局,看看它在代码里到底是怎么存的。到时候我会给你看一个我当年调试了三天才搞明白的bug——嗯,那个故事挺有意思的。