4. 基于统计的色温估计:直方图分析法、色温查找表(LUT)法、贝叶斯色温估计

各位同学,欢迎来到第四章。前面我们聊了物理模型和灰度世界,那些方法在简单场景下够用,但一遇到复杂光源、混合色温,就容易翻车。这一章,我们进入统计学的世界。

说白了,基于统计的方法不跟你讲什么「光源物理特性」,它直接拿大量数据说话。你给它看一堆图,它告诉你「这场景色温大概 4500K」。怎么做到的?我们一个个拆开看。

4.1 直方图分析法:从像素分布里找线索

直方图分析法,是我个人最早接触的统计类 AWB 方法。它的核心思想很简单:不同色温下,图像 R/G/B 通道的统计分布是有规律的。

举个例子。你在 3000K 的钨丝灯下拍一张白纸,R 通道的像素值普遍偏高,B 通道偏低。在 6500K 的阴天,情况反过来。直方图分析法就是利用这种分布差异来反推色温。

4.1.1 基本流程

  1. 统计各通道直方图:对 R、G、B 三个通道分别计算直方图,通常用 256 个 bin。
  2. 提取统计特征:比如均值、中位数、众数、标准差,或者更复杂的偏度、峰度。
  3. 建立特征-色温映射:用已知色温的标定图像,建立特征向量到色温值的映射关系。
  4. 估计未知图像色温:提取待测图像的特征,查映射表或拟合函数得到色温。

关键点:直方图分析法对场景内容敏感。如果画面里有一大片红色物体,R 通道直方图会严重右偏,导致色温估计偏低。所以实际工程中,通常先做 白点检测,只统计可能为白色的像素区域。

4.1.2 我踩过的坑

我曾经在一个项目中,用直方图均值做色温估计。实验室里跑得挺好,一上手机就崩了。为什么?因为用户拍了一张全是绿草的照片,G 通道均值爆表,算法直接报色温 10000K。后来我加了白点检测,才把问题压下去。

嗯,这里要注意:直方图分析法不适合纯色场景。你想想看,一张蓝天照片,B 通道直方图集中在高值区,算法会误判为低色温。所以它通常作为辅助手段,跟其他方法融合使用。

4.2 色温查找表(LUT)法:工程界的实用派

色温查找表法,说白了就是「查字典」。你提前标定好各种色温下的统计特征,存成一张表。实际使用时,提取图像特征,去表里找最接近的色温值。

这个方法在工业界用得非常多。为什么?快、稳、可控。你不需要复杂的数学模型,查表加插值就搞定。

4.2.1 LUT 的构建过程

  1. 选择标定光源:通常用 D65、D50、A 光源、TL84、CWF 等标准光源,覆盖 2500K-10000K 范围。
  2. 拍摄标定色卡:在每种光源下拍摄标准色卡(如 Macbeth ColorChecker),记录 R/G/B 响应值。
  3. 计算特征向量:常用特征包括 R/G、B/G 比值,或者更鲁棒的色度坐标(如 CIE xy)。
  4. 构建 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 本章知识结构图

下面这张图总结了三种统计方法的流程和关系,方便你对照理解。

基于统计的色温估计方法结构图 基于统计的色温估计方法 输入图像 直方图分析法 统计各通道分布特征 色温查找表(LUT)法 查表 + 插值 贝叶斯色温估计 后验概率最大化 提取均值/中位数/偏度 计算 R/G、B/G 比值 计算似然 × 先验 估计色温值 💡 工程建议 • 直方图法:适合做辅助验证,避免纯色场景 • LUT法:工程首选,注意低色温区加密采样 • 贝叶斯法:精度高但需要大量标定数据,先做场景分类再选先验

4.6 实战建议

最后,给各位一些实战中的建议:

  • 数据是王道:无论你用哪种方法,标定数据的质量和数量直接决定效果。我见过太多团队花大量时间调算法,却不愿意花一周时间好好标定。
  • 融合才是出路:单一方法都有短板。我建议用 LUT 法做主估计,直方图法做异常检测,贝叶斯法做置信度评估。三个方法投票,效果远好于任何一个。
  • 别忘了场景适配:同样的方法,在室内和室外效果可能天差地别。记得根据场景切换参数或先验。