1225 字
6 分钟
AWB 自动白平衡系统:从光源估计到闭环控制

手动白平衡是在已知光源或中性卡时设置通道增益;AWB(Auto White Balance)必须只根据当前图像判断:画面偏黄,究竟来自暖色光源,还是来自夕阳、木墙与黄色物体本身?

因此 AWB 不是一条“把 RGB 均值拉齐”的公式,而是一套带有不确定性的估计与控制系统。

一条完整的 AWB 链路#

工程实现通常包含五个阶段:

  1. 从 RAW 或线性 RGB 中采集分块统计;
  2. 排除饱和、过暗、强色和其他不可信像素;
  3. 根据中性候选、颜色分布与场景先验估计光源;
  4. 把光源估计转换为白平衡增益,并联动 CCM 插值;
  5. 根据置信度、场景变化和历史状态平滑或冻结输出。

这条链路里,“测到了什么”和“是否相信测量”同样重要。单色墙、舞台灯、混合照明都可能让数学上稳定的统计给出语义上错误的答案。

光源估计与白平衡增益#

若中性表面在当前光源下测得 (R,G,B)(R,G,B),一种以绿色通道为基准的增益写法是:

gR=G/R,gG=1,gB=G/Bg_R=G/R,\qquad g_G=1,\qquad g_B=G/B

这说明 WB 与 AWB 的职责不同:WB 应用增益,AWB 决定应该使用哪组增益。

把像素写成列向量 p=[R,G,B]T\mathbf p=[R,G,B]^\mathsf T,最常见的教学模型是对角变换:

p=Dp,D=diag(gR,1,gB)\mathbf p'=\mathbf D\mathbf p, \qquad \mathbf D=\operatorname{diag}(g_R,1,g_B)

若候选集合 Ω\Omega 中确实包含中性表面,则校正后的通道应满足中性约束:

1ΩiΩDpi=k[111],k>0\frac{1}{|\Omega|}\sum_{i\in\Omega}\mathbf D\mathbf p_i =k\begin{bmatrix}1\\1\\1\end{bmatrix}, \qquad k>0

用候选均值 μ=(μR,μG,μB)\boldsymbol\mu=(\mu_R,\mu_G,\mu_B) 代入,就得到 gR=μG/μRg_R=\mu_G/\mu_RgB=μG/μBg_B=\mu_G/\mu_B。下面的 NumPy 函数只实现这个数值内核,输入必须是已经完成黑电平校正、近似线性的 RGB;候选掩码如何产生,留给下一篇讨论。

import numpy as np
def diagonal_wb_gains(linear_rgb, neutral_mask, eps=1e-6):
"""由可信中性候选计算以 G 为锚点的 (gR, gG, gB)。"""
rgb = np.asarray(linear_rgb, dtype=np.float64)
mask = np.asarray(neutral_mask, dtype=bool)
if rgb.ndim != 3 or rgb.shape[-1] != 3:
raise ValueError("linear_rgb 必须是 H×W×3")
if mask.shape != rgb.shape[:2] or not np.any(mask):
raise ValueError("neutral_mask 必须匹配图像且至少包含一个候选")
mean_rgb = rgb[mask].mean(axis=0)
if np.any(mean_rgb <= eps):
raise ValueError("候选均值过暗,通道比不可信")
gains = mean_rgb[1] / mean_rgb
gains /= gains[1] # 明确保持绿色通道为 1
return np.clip(gains, 0.25, 4.0) # 教学用安全范围

对角模型假设同一组通道增益可以解释整幅图像。真实相机还需要传感器标定、光源轨迹、增益限幅,并让 CCM 随估计光源插值;窄带光源与混合光也不能仅靠一个全局对角矩阵完整校正。

色温与 Tint 是两条不同方向

色温主要沿蓝—黄轴变化,Tint 处理绿—洋红偏移。AWB 要估计的是光源,而不是让所有像素变成灰色。

暖色灯光照明的餐厅吊灯实拍照片
原始暖光
校正预览
中性块 · 校正前校正后
R Gain0.82
G Gain1.00
B Gain1.41

实拍照片的冷暖变化用颜色叠层近似,仅用于观察校正方向;中性块与增益才对应简化通道模型,不等同于完整的 Planckian locus 或相机标定模型。

相关色温主要描述蓝—黄方向,Tint 补充绿—洋红方向,但它们仍不能完整表示任意光谱。窄带 LED、荧光灯和混合光可能在相同色温下产生不同的传感器响应,因此真实系统需要相机标定、光源模型和场景先验。

AWB 为什么必须输出置信度#

灰世界、中性点和白点假设都只在部分场景成立。可靠 AWB 不应只输出 (gR,gB)(g_R,g_B),还应输出:

  • 有效统计像素比例;
  • 候选光源之间的一致性;
  • 当前场景是否可能为单色或混合光;
  • 与上一帧结果的变化幅度;
  • 最终估计的置信度与锁定状态。

置信度低时,保持上一组可信增益通常比追逐噪声更安全。视频中的颜色闪烁,很多时候不是估计均值不准,而是状态机过度相信了每一帧。

AWB 与其他模块的边界#

AWB 的输出常同时影响 WB 增益、CCM 选择和色调风格;AE 又会改变统计亮度、饱和比例和信噪比。因此 3A 必须交换状态,但不应让职责混在一起。

  • AWB 估计光源,不负责修正镜头色差;
  • CCM 修正传感器颜色响应,不能代替错误的光源估计;
  • Tone Mapping 能改变观感,却不应成为线性 AWB 统计的输入;
  • 局部色彩风格可以保留暖光氛围,不等于 AWB 估计失败。

最小实现骨架#

stats = collect_linear_rgb_stats(raw, blocks=True)
candidates = reject_unreliable(stats, dark=True, saturated=True, chromatic=True)
illuminant, confidence = estimate_illuminant(candidates, scene_prior)
if confidence >= update_threshold:
target_gains = illuminant_to_gains(illuminant, calibration)
gains = temporal_filter(previous_gains, target_gains, scene_change)
else:
gains = previous_gains

这段骨架有意把“统计”“估计”“决策”“时间控制”分开。这样的系统更容易记录中间状态,也更容易定位偏色究竟来自候选筛选、模型选择还是输出平滑。

后续两篇将分别深入经典统计方法,以及置信度、混合光与视频稳定问题。理解 AWB 的关键,是承认单帧图像无法总是唯一确定光源,并把这种不确定性显式带进系统。

AWB 自动白平衡系统:从光源估计到闭环控制
https://cloudsir.top/posts/how-auto-white-balance-works/
作者
CloudSir
发布于
2026-08-25
许可协议
CC BY-NC-SA 4.0
AWB 如何估计光源?从灰世界到可信像素筛选
CDAF 与 PDAF:两种对焦观测方法