4. 基于统计的色温估计:直方图分析法、色温查找表(LUT)法、贝叶斯色温估计
各位同学,欢迎来到第四章。前面我们聊了物理模型和灰度世界,那些方法在简单场景下够用,但一遇到复杂光源、混合色温,就容易翻车。这一章,我们进入统计学的世界。
说白了,基于统计的方法不跟你讲什么「光源物理特性」,它直接拿大量数据说话。你给它看一堆图,它告诉你「这场景色温大概 4500K」。怎么做到的?我们一个个拆开看。
4.1 直方图分析法:从像素分布里找线索
直方图分析法,是我个人最早接触的统计类 AWB 方法。它的核心思想很简单:不同色温下,图像 R/G/B 通道的统计分布是有规律的。
举个例子。你在 3000K 的钨丝灯下拍一张白纸,R 通道的像素值普遍偏高,B 通道偏低。在 6500K 的阴天,情况反过来。直方图分析法就是利用这种分布差异来反推色温。
4.1.1 基本流程
- 统计各通道直方图:对 R、G、B 三个通道分别计算直方图,通常用 256 个 bin。
- 提取统计特征:比如均值、中位数、众数、标准差,或者更复杂的偏度、峰度。
- 建立特征-色温映射:用已知色温的标定图像,建立特征向量到色温值的映射关系。
- 估计未知图像色温:提取待测图像的特征,查映射表或拟合函数得到色温。
关键点:直方图分析法对场景内容敏感。如果画面里有一大片红色物体,R 通道直方图会严重右偏,导致色温估计偏低。所以实际工程中,通常先做 白点检测,只统计可能为白色的像素区域。
4.1.2 我踩过的坑
我曾经在一个项目中,用直方图均值做色温估计。实验室里跑得挺好,一上手机就崩了。为什么?因为用户拍了一张全是绿草的照片,G 通道均值爆表,算法直接报色温 10000K。后来我加了白点检测,才把问题压下去。
嗯,这里要注意:直方图分析法不适合纯色场景。你想想看,一张蓝天照片,B 通道直方图集中在高值区,算法会误判为低色温。所以它通常作为辅助手段,跟其他方法融合使用。
4.2 色温查找表(LUT)法:工程界的实用派
色温查找表法,说白了就是「查字典」。你提前标定好各种色温下的统计特征,存成一张表。实际使用时,提取图像特征,去表里找最接近的色温值。
这个方法在工业界用得非常多。为什么?快、稳、可控。你不需要复杂的数学模型,查表加插值就搞定。
4.2.1 LUT 的构建过程
- 选择标定光源:通常用 D65、D50、A 光源、TL84、CWF 等标准光源,覆盖 2500K-10000K 范围。
- 拍摄标定色卡:在每种光源下拍摄标准色卡(如 Macbeth ColorChecker),记录 R/G/B 响应值。
- 计算特征向量:常用特征包括 R/G、B/G 比值,或者更鲁棒的色度坐标(如 CIE xy)。
- 构建 LUT:将特征向量与色温值一一对应,形成查找表。
| 光源 | 色温 (K) | R/G 均值 | B/G 均值 |
|---|---|---|---|
| A | 2856 | 1.45 | 0.62 |
| TL84 | 4000 | 1.18 | 0.85 |
| D50 | 5000 | 1.05 | 0.98 |
| D65 | 6500 | 0.95 | 1.12 |
| D75 | 7500 | 0.88 | 1.25 |
4.2.2 查表与插值
实际使用时,你提取待测图像的 R/G、B/G 比值,在 LUT 中找到最近的几个点,做线性插值或样条插值。我建议用 双线性插值,简单且够用。
// 伪代码:色温 LUT 查表与插值
float estimateColorTemp(float rg_ratio, float bg_ratio, LUTEntry* lut, int lut_size) {
// 找到最近的四个点
int idx[4];
findNearestNeighbors(rg_ratio, bg_ratio, lut, lut_size, idx);
// 双线性插值
float w1, w2, w3, w4;
computeBilinearWeights(rg_ratio, bg_ratio, lut, idx, &w1, &w2, &w3, &w4);
float ct = w1 * lut[idx[0]].colorTemp +
w2 * lut[idx[1]].colorTemp +
w3 * lut[idx[2]].colorTemp +
w4 * lut[idx[3]].colorTemp;
return ct;
}
工程技巧:LUT 的密度很重要。色温变化在低色温区(2500K-4000K)更敏感,建议在这个区间加密采样点。高色温区(7000K-10000K)可以稀疏一些。
4.3 贝叶斯色温估计:概率视角的优雅解法
贝叶斯色温估计,是我个人觉得最有「数学美感」的方法。它把色温估计问题转化为一个概率推理问题:给定当前图像,最可能的色温是多少?
公式长这样:
P(C | I) = P(I | C) * P(C) / P(I)
其中:
- P(C | I):后验概率,给定图像 I 时色温为 C 的概率。这是我们要求的。
- P(I | C):似然,在色温 C 下观察到图像 I 的概率。从标定数据中学习。
- P(C):先验概率,色温 C 出现的概率。比如日光场景下 5000K-6000K 的先验概率更高。
- P(I):证据因子,归一化常数,通常忽略。
4.3.1 先验概率的设定
先验概率怎么定?我建议用 场景统计。你收集大量自然图像,统计它们的色温分布。你会发现,室内场景的色温集中在 3000K-4500K,室外日光场景集中在 5000K-6500K,阴天场景在 6500K-8000K。
也可以根据相机厂商的标定数据来设定。有些厂商会提供「场景模式」的先验,比如「日落模式」下低色温先验概率高。
4.3.2 似然模型的建立
似然 P(I | C) 通常用 高斯混合模型(GMM) 或 核密度估计(KDE) 来建模。你在每种色温下标定大量图像,提取特征(如 R/G、B/G 比值),然后拟合概率密度函数。
举个例子,在 5000K 下,R/G 比值的分布可能是一个以 1.05 为中心的高斯分布。在 3000K 下,中心偏移到 1.45。
注意:贝叶斯方法对先验敏感。如果你把先验设错了,比如在室内场景用了日光先验,估计结果会严重偏蓝。我建议在工程实现中,先做一个 场景分类,再选择对应的先验。
4.3.3 贝叶斯方法的优缺点
| 维度 | 优点 | 缺点 |
|---|---|---|
| 精度 | 理论上限高,融合先验信息 | 对先验和似然模型精度敏感 |
| 鲁棒性 | 对噪声和异常值有一定容忍度 | 需要大量标定数据 |
| 计算量 | 查表+简单概率计算,可优化 | 比 LUT 法稍大 |
| 可解释性 | 概率框架,结果有置信度 | 模型复杂,调试困难 |
4.4 三种方法的对比与选择
在实际项目中,怎么选?我个人的经验是:
- 直方图分析法:适合做 辅助验证,或者跟其他方法做投票融合。单独用容易翻车。
- 色温 LUT 法:工程首选。简单、可控、调试方便。我 80% 的项目都用它。
- 贝叶斯法:适合对精度要求高、有充足标定数据的场景。比如专业相机、医疗影像。
你想想看,如果你的产品要过认证,色温估计必须稳定可靠,LUT 法是最稳妥的。如果你在做算法研究,想发,贝叶斯法更有深度。
4.5 本章知识结构图
下面这张图总结了三种统计方法的流程和关系,方便你对照理解。
4.6 实战建议
最后,给各位一些实战中的建议:
- 数据是王道:无论你用哪种方法,标定数据的质量和数量直接决定效果。我见过太多团队花大量时间调算法,却不愿意花一周时间好好标定。
- 融合才是出路:单一方法都有短板。我建议用 LUT 法做主估计,直方图法做异常检测,贝叶斯法做置信度评估。三个方法投票,效果远好于任何一个。
- 别忘了场景适配:同样的方法,在室内和室外效果可能天差地别。记得根据场景切换参数或先验。