白平衡基础:色温、色调与人眼视觉恒常性
各位同学,咱们今天正式开讲白平衡。说实话,白平衡这玩意儿,在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流水线里到底站在哪。我画了一张流程图,帮你理清这个位置关系。
从这张图你能看到,白平衡增益模块紧跟在黑电平校正之后。为什么放在这里?我个人理解是:黑电平校正先把传感器的暗电流噪声去掉,然后白平衡再对每个通道做增益补偿。如果顺序反了,黑电平的偏移会被白平衡增益放大,那画面暗部就会偏色得一塌糊涂。
避坑指南:我曾经在一个项目中,把白平衡放在了去马赛克之后。结果呢?边缘伪色严重,而且色彩校正矩阵(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 域的关键位置。下一章,我会带你手撕白平衡算法的代码实现,从最简单的灰度世界法开始。
嗯,今天就到这里。有问题随时在群里问我。