白平衡基础:色温、色调与人眼视觉恒常性

各位同学,咱们今天正式开讲白平衡。说实话,白平衡这玩意儿,在ISP(图像信号处理)流水线里看着不起眼,但你要是调不好,整张图就废了。我当年刚入行时,就吃过这个亏——给一家手机厂商做调试,白天效果还行,一到黄昏室内,人脸直接变成“阿凡达”。嗯,从那以后,我再也不敢小看白平衡了。

1.1 色温与色调:光也是有“性格”的

先说说色温。你想想看,为什么正午的阳光是偏白的,而烛光却是偏黄的?这背后其实是黑体辐射的物理规律。色温的单位是开尔文(K),数值越低,光越偏红黄;数值越高,光越偏蓝。

光源类型 典型色温(K) 视觉感受
烛光 1500 - 2000 温暖、昏黄
白炽灯 2500 - 3000 暖白
日光灯 4000 - 5000 中性白
正午阳光 5000 - 5500 标准白
阴天 6000 - 7000 偏冷、偏蓝
蓝天阴影 8000 - 10000 冷冽、偏蓝紫

色调呢?它和色温是两码事。色调是沿着红-绿-蓝-黄这个色环走的偏移量。我习惯把色温理解为“暖到冷”的一维轴,而色调是“绿到品红”的另一维轴。两者合在一起,才能完整描述一张图的颜色偏差。

核心要点:色温是黑体辐射的物理量,色调是色环上的偏移。白平衡要同时校正这两个维度。

1.2 人眼视觉恒常性:为什么我们看白纸永远是白的?

这个问题很有意思。你拿一张白纸,在烛光下看,它还是白的;在日光灯下看,它也是白的。但相机拍出来呢?烛光下偏黄,日光灯下偏蓝。为什么会这样?

人眼有强大的色彩恒常性机制。说白了,大脑会自动“扣除”环境光的颜色,还原物体本身的颜色。我做过一个实验:在实验室里用不同色温的光照射同一张白卡纸,人眼始终觉得它是白的,但相机拍出来的RAW图,RGB值差异巨大。

相机没有大脑。它只能老老实实地记录光线的物理值。所以我们需要白平衡算法,来模拟人眼的这种“自动扣除”能力。

我的经验:在调试白平衡时,别完全相信人眼在现场的判断。因为人眼会自适应,你看着“正常”的画面,拍出来可能偏色严重。我建议用色卡或灰卡做客观标定。

1.3 白平衡在ISP流程中的位置

咱们来看看白平衡在整个ISP流水线里到底站在哪。我画了一张流程图,帮你理清这个位置关系。

ISP 流水线中白平衡的位置 RAW 输入 黑电平校正 白平衡增益 去马赛克 色彩校正矩阵 Gamma 校正 YUV/RGB 输出 说明: 白平衡增益(红色节点)位于黑电平校正之后、去马赛克之前。 这个位置意味着白平衡是在 RAW 域进行的,直接对 R/G/B 通道施加增益。

从这张图你能看到,白平衡增益模块紧跟在黑电平校正之后。为什么放在这里?我个人理解是:黑电平校正先把传感器的暗电流噪声去掉,然后白平衡再对每个通道做增益补偿。如果顺序反了,黑电平的偏移会被白平衡增益放大,那画面暗部就会偏色得一塌糊涂。

避坑指南:我曾经在一个项目中,把白平衡放在了去马赛克之后。结果呢?边缘伪色严重,而且色彩校正矩阵(CCM)的参数怎么调都不对。后来才发现,白平衡必须在 RAW 域做,因为去马赛克会引入插值误差,这时候再调白平衡,误差会被放大。

1.4 白平衡的数学本质

说白了,白平衡就是给每个像素的 R、G、B 通道乘上不同的增益系数。公式很简单:

R_out = R_in * gain_R
G_out = G_in * gain_G
B_out = B_in * gain_B

但难点在于:这三个增益怎么算?如果场景中有白色物体(比如灰卡),那直接让 R_out = G_out = B_out 就行。但大多数场景里没有灰卡,所以算法得“猜”——猜当前场景的色温,然后查表得到增益。

我常用的方法是:先统计整张图的 R/G 和 B/G 比值,然后映射到色温曲线上。这个映射关系,每个 sensor 都不一样,需要做标定。

关键公式:白平衡的核心是找到正确的 R/G 和 B/G 比值,使得白色物体在图像中呈现为 R=G=B。

1.5 色温估计的两种思路

实际工程中,色温估计主要有两条路:

  • 基于统计的方法:比如灰度世界法、完美反射法。假设场景中所有颜色的平均值是灰色,或者假设最亮的像素是白色。优点是计算快,缺点是在大面积单色场景下会翻车。
  • 基于学习的方法:用 CNN 或 Transformer 直接回归色温值。我最近在项目中试了轻量级网络,效果确实比传统方法好,但功耗和延迟是个问题。

我个人习惯是:在移动端用统计方法做粗调,再用一个小网络做微调。这样既保证了实时性,又提升了准确率。

小技巧:如果你用灰度世界法,记得先剔除过暗和过亮的像素。否则,暗部的噪声和亮部的过曝会严重拉偏统计结果。

1.6 本章小结

好了,这一章的内容就这些。咱们把白平衡的基础打牢了:色温是物理量,色调是偏移量,人眼有恒常性但相机没有,白平衡在 ISP 中处于 RAW 域的关键位置。下一章,我会带你手撕白平衡算法的代码实现,从最简单的灰度世界法开始。

嗯,今天就到这里。有问题随时在群里问我。