第四章 AWB核心算法原理:灰度世界法、完美反射法、色温估计法
各位同学,欢迎来到自动白平衡的核心章节。
说实话,AWB算法市面上有几十种变体。但万变不离其宗,绝大多数商业方案,底层都离不开今天要讲的三个老祖宗:灰度世界法、完美反射法、色温估计法。我自己刚入行时,也是从这三个算法开始啃起的。嗯,今天咱们就把它们彻底吃透。
4.1 灰度世界法(Gray World)
这个算法的假设很简单:一张色彩丰富的自然图像,所有像素的R、G、B平均值应该趋于相等,即呈现灰色。
你想想看,如果画面整体偏蓝,那蓝色通道的平均值肯定比红色和绿色高。我们只要算出各通道的增益,把偏高的压下来,偏低的拉上去,白平衡就校正了。
4.1.1 数学原理
假设输入图像为 I,尺寸为 M×N。我们计算三个通道的均值:
R_avg = mean(I(:,:,1))
G_avg = mean(I(:,:,2))
B_avg = mean(I(:,:,3))
然后计算各通道的增益:
K_r = G_avg / R_avg
K_g = 1.0 // 绿色通道通常作为参考
K_b = G_avg / B_avg
最后应用增益:
I_corrected(:,:,1) = I(:,:,1) * K_r
I_corrected(:,:,2) = I(:,:,2) * K_g
I_corrected(:,:,3) = I(:,:,3) * K_b
核心要点:灰度世界法计算量极小,适合硬件实现。但它的致命伤是——如果场景本身就不是「灰度世界」呢?比如一片蓝天、一片绿草地,算法就会误判。
我的经验:我在项目中遇到过,用灰度世界法处理日落场景,结果把暖色调全拉成了冷白色,画面完全失去了氛围感。后来我加了一个「场景分类器」,检测到单色场景时自动降低灰度世界法的权重。
4.1.2 改进策略
纯灰度世界法太「耿直」了。实际工程中,我们通常会做两点改进:
- 剔除过亮过暗像素:把亮度最高的5%和最低的5%像素排除掉,避免高光或暗部噪声干扰均值计算。
- 动态阈值裁剪:只保留色度在某个范围内的像素参与计算。比如只选那些「看起来像灰色」的像素。
避坑指南:我曾经在调试一款手机摄像头时,发现灰度世界法在室内灯光下效果很好,一到户外就偏色严重。排查了半天,原来是镜头上的微尘导致局部偏色,影响了全局均值。所以,输入图像的质量直接影响算法效果,预处理不能省。
4.2 完美反射法(White Patch)
完美反射法的思路和灰度世界法正好相反。它认为:图像中最亮的那个像素点,应该是纯白色的。如果它偏色了,那整个画面肯定也偏了。
说白了,就是找画面里最亮的那块「补丁」,把它校正成白色,然后按这个比例去校正全图。
4.2.1 算法流程
1. 找到图像中亮度最大的像素点(R_max, G_max, B_max)
2. 计算各通道增益:
K_r = G_max / R_max
K_g = 1.0
K_b = G_max / B_max
3. 应用增益到全图
等等,这里有个问题——如果最亮的像素是车灯、是太阳、是镜面高光呢?这些本身就不是白色,强行校正会出大问题。
关键改进:实际工程中,我们不会只取「最亮的一个点」,而是取亮度前0.1%的像素集合,然后取它们的平均RGB值作为参考白点。这样能有效避免单个噪声点的干扰。
4.2.2 灰度世界 vs 完美反射
| 对比项 | 灰度世界法 | 完美反射法 |
|---|---|---|
| 假设基础 | 图像均值呈灰色 | 最亮像素呈白色 |
| 适用场景 | 色彩丰富的自然场景 | 有明确白色参考的场景 |
| 弱点 | 单色场景失效 | 高光区域误判 |
| 计算量 | 极低 | 低 |
我的习惯:在ISP流水线中,我通常把灰度世界法和完美反射法做加权融合。比如,场景色彩丰富时灰度世界法权重高,场景中有明显高光区域时完美反射法权重高。这个权重怎么调?嗯,靠大量数据标定。
4.3 色温估计法(Color Temperature Estimation)
前面两种方法都是「事后补救」——看到偏色了再校正。色温估计法更聪明,它直接去估计光源的色温,然后查表找到对应的校正参数。
为什么这么做?因为不同色温的光源,在RGB空间中有固定的轨迹。比如:
- 低色温(2000K-3000K):偏红黄色,像蜡烛、白炽灯
- 中色温(4000K-5000K):偏中性,像日光灯、阴天
- 高色温(6000K-8000K):偏蓝色,像晴天阴影、蓝天
4.3.1 色温估计的核心步骤
1. 从图像中提取色度特征(如 R/G, B/G 比值)
2. 将特征映射到色温曲线(普朗克轨迹)
3. 找到最匹配的色温值
4. 根据色温查表得到 R、B 增益
5. 应用增益校正全图
关键点:色温估计法的精度,完全取决于色温曲线的标定质量。我见过一些方案,标定时只用了几种标准光源(D65、A光源、TL84),结果实际场景中遇到LED灯、节能灯就完全跑偏了。
4.3.2 实战中的色温曲线标定
我个人建议,标定时至少要覆盖以下光源:
- 标准光源:D65(6500K)、A光源(2856K)、TL84(4000K)
- 常见光源:冷白LED(5000K)、暖白LED(3000K)、荧光灯(4200K)
- 极端光源:蜡烛光(1800K)、蓝天阴影(7500K)
避坑指南:我曾经在调试一款安防摄像头时,发现色温估计法在室内混合光源下(一半日光灯、一半窗边自然光)完全失效。因为画面中同时存在两种色温,算法不知道该听谁的。后来我引入了多区域色温估计,把画面分成9宫格,每个格子独立估计色温,再根据置信度做融合。效果好了很多。
4.4 三种算法的融合策略
讲到这里,你应该明白了——没有一种算法是万能的。实际产品中,我们通常做的是多算法融合。
我常用的融合框架是这样的:
1. 先用色温估计法,得到初步的色温和增益
2. 用灰度世界法计算全局统计量,验证色温估计的合理性
3. 用完美反射法检测高光区域,修正局部偏差
4. 根据场景置信度,加权融合三个结果
5. 最后做时域滤波,防止增益突变导致闪烁
我的经验:这个融合框架我用了好几年,在手机、安防、车载项目上都验证过。核心就一句话——不要迷信任何一个算法,让数据说话。每个算法都有自己的「舒适区」,我们要做的就是把它们组合起来,取长补短。
4.5 本章小结
今天咱们聊了AWB的三个核心算法:
- 灰度世界法:简单粗暴,适合色彩丰富的场景
- 完美反射法:找最亮点,适合有白色参考的场景
- 色温估计法:直接猜光源,精度高但依赖标定
下一章,我会带大家深入AWB的工程实现细节,包括如何做场景分类、如何做时域平滑、如何与AE/AF联动。嗯,到时候见。
课后思考:如果让你设计一个AWB算法,你会优先选择哪种方法?为什么?欢迎在评论区和我讨论。