4. AWB 自动白平衡:色温估计、灰度世界与完美反射模型、色温校正矩阵
好,咱们进入第四章。自动白平衡,简称 AWB。这玩意儿说白了,就是让相机在不同光线下,都能把白色拍成白色。你想想看,在暖黄的台灯下拍张白纸,如果相机不做处理,拍出来就是黄乎乎的。AWB 的任务,就是把那层黄色去掉,让白纸还原成白纸。
我个人习惯把 AWB 拆成两大步:第一步是估计色温,搞清楚当前光源是什么颜色;第二步是校正,把偏色的像素拉回中性色。今天咱们就围绕这两个步骤,把几个经典模型讲透。
4.1 色温估计:从物理到算法
色温,单位是开尔文(K)。低色温偏红黄(比如烛光 2000K),高色温偏蓝(比如阴天 7000K)。但算法不直接测温度,它通过分析图像里的颜色分布来反推。
我见过不少新手,一上来就搞复杂的统计模型。其实,色温估计的核心就一句话:找到图像中“本该是白色”的区域。只要找到这些区域,算一下它们的 R/G/B 比值,就能知道光源偏什么色。
关键点:色温估计不是测温度,而是测“光源颜色在图像传感器上的响应”。不同传感器的光谱响应不同,同样的光源,不同 sensor 拍出来的 RAW 数据是不一样的。所以 AWB 参数通常需要针对 sensor 标定。
4.2 灰度世界模型(Gray World)
这是最经典的模型,也是我入行时学的第一个 AWB 算法。它的假设很简单:一幅色彩丰富的自然图像,所有像素的 R、G、B 平均值应该相等。换句话说,整个世界平均下来是灰色的。
公式也很直观:
R_avg = G_avg = B_avg
如果 R_avg 偏大,说明光源偏红,需要降低 R 增益。
增益计算:
gain_R = G_avg / R_avg
gain_B = G_avg / B_avg
最终像素:
R_out = R_in * gain_R
B_out = B_in * gain_B
G_out = G_in (保持不变)
我在项目中遇到过一个问题:如果场景里大面积都是同一颜色(比如一片绿草地),灰度世界模型就会失效。它会强行把绿色拉成灰色,结果整个画面发紫。所以,灰度世界模型只适用于色彩丰富的场景。
我的经验:灰度世界模型适合做粗调,或者作为多模型融合的 baseline。单独用它,风险不小。
4.3 完美反射模型(Perfect Reflector / White Patch)
这个模型换了个思路。它假设:图像中最亮的那个像素,应该是纯白色的。因为最亮的点通常来自镜面反射或白色物体,它应该反射了所有波长的光。
算法步骤:
- 遍历所有像素,找到 R、G、B 各自的最大值:R_max, G_max, B_max。
- 计算增益:gain_R = G_max / R_max, gain_B = G_max / B_max。
- 用增益校正每个像素。
听起来很合理对吧?但坑也不少。如果场景里有一个高亮的红色物体(比如红色车尾灯),R_max 会非常大,导致 gain_R 变得很小,整个画面就会偏青。我曾经在一个夜间街景项目里吃过这个亏,满屏的红色霓虹灯把白平衡带偏了十万八千里。
避坑指南:完美反射模型对高光噪声非常敏感。我建议先做一下高光像素的筛选,排除掉过曝区域(比如像素值接近 1023 的),再用次亮像素来估计。这样鲁棒性会好很多。
4.4 两种模型的对比
咱们用一张表来对比一下这两个经典模型:
| 对比维度 | 灰度世界模型 | 完美反射模型 |
|---|---|---|
| 核心假设 | 平均色为灰色 | 最亮点为白色 |
| 适用场景 | 色彩丰富、均匀的场景 | 存在高光或白色物体的场景 |
| 失效场景 | 大面积单色(草地、蓝天) | 高亮彩色物体(红灯、彩灯) |
| 计算复杂度 | 低(只需一次遍历求均值) | 低(只需一次遍历求最大值) |
| 鲁棒性 | 中等,受大面积色块影响大 | 较差,受高光噪声影响大 |
说白了,这两个模型都是“单点假设”,太理想化了。实际工程中,我很少单独用其中一个。更常见的做法是:把两者结合起来,或者用更鲁棒的统计方法(比如在色温曲线上做匹配)。
4.5 色温校正矩阵(CCM)
好,估计出色温之后,怎么校正?很多人以为就是乘三个增益(R、G、B)。其实,真正的白平衡校正,是在 RGB 颜色空间里做一个 3x3 的线性变换,这就是色温校正矩阵(Color Correction Matrix, CCM)。
为什么不能只用对角增益?因为传感器的色彩通道之间有串扰。红色通道里可能混了一点点绿色和蓝色。只用对角增益,只能调整亮度,无法纠正串扰导致的色偏。
CCM 的形式:
[ R_out ] [ a11 a12 a13 ] [ R_in ]
[ G_out ] = [ a21 a22 a23 ] * [ G_in ]
[ B_out ] [ a31 a32 a33 ] [ B_in ]
其中,a11、a22、a33 是对角增益(类似灰度世界的 gain_R、gain_G、gain_B),而非对角项(a12、a13 等)负责消除通道串扰。
我在项目中遇到过,有些 ISP 芯片只支持对角增益(即 3x3 矩阵的非对角项强制为 0)。这种情况下,白平衡精度会受限,尤其是在极端色温下(比如 2500K 或 7500K),色偏会比较明显。
我的建议:如果硬件支持,尽量用完整的 3x3 CCM。如果只支持对角增益,那就要在色温估计阶段做得更准,或者配合 gamma 校正后的颜色查找表(LUT)来做补偿。
4.6 本章知识体系
下面这张图,把 AWB 的核心流程串起来了:
4.7 工程中的实际考量
最后,聊几个我在项目中踩过的坑:
- 不要只依赖一个模型。我习惯用灰度世界做全局估计,用完美反射做局部校验,两者加权融合。权重根据场景统计信息动态调整。
- 注意 YUV 域的限制。有些 ISP 在 YUV 域做 AWB,但 YUV 的色度分量(Cb、Cr)是差分量,直接调整容易引入色噪。我建议尽量在 RGB 域做校正。
- 标定很重要。同样的算法,换一颗 sensor,效果可能天差地别。一定要用色卡在标准光源下做标定,生成 sensor 专属的 CCM 矩阵。
- 防抖和 AWB 的交互。如果场景在快速变化(比如摇镜头),AWB 的收敛速度要快,否则会出现色温“追不上”的情况。我一般会限制增益的变化速率,防止画面闪烁。
嗯,AWB 这块内容不少,但核心就是色温估计 + 矩阵校正。灰度世界和完美反射是两个基础模型,理解它们,再看更复杂的算法(比如基于色温曲线的贝叶斯估计)就容易多了。