第三章 AE核心算法:统计信息提取与曝光决策

AE(自动曝光)说难不难,说简单也不简单。很多工程师把AE理解成「调亮度」,其实远不止这些。我个人习惯把AE拆成三个环节:看数据 → 定策略 → 算参数。这一章我们先聊「看数据」和「定策略」这两块。

3.1 统计信息提取:AE的眼睛

AE算法要干活,首先得知道当前画面长什么样。统计信息就是AE的「眼睛」。没有准确的统计,后面再牛的算法也是瞎蒙。

3.1.1 亮度直方图

亮度直方图是最基础的统计工具。它统计了画面中每个亮度级别的像素数量。横轴是亮度(0~255,8bit),纵轴是像素个数。

核心价值:直方图能告诉你画面是偏暗、偏亮,还是对比度不足。比单纯的平均亮度靠谱得多。

举个例子。一个平均亮度为128的画面,可能是均匀的中灰,也可能是半黑半白。平均亮度一样,但直方图形状完全不同。AE需要根据形状做不同的处理。

我在项目中遇到过一个问题:用平均亮度做AE,逆光场景下人脸总是过暗。后来换成直方图统计,把低亮度的「权重」提上来,问题就解决了。

3.1.2 分区统计

整帧直方图还不够。为什么?因为画面不同区域的重要性不一样。人脸区域、画面中心区域,显然比角落的天空更重要。

分区统计就是把画面切成M×N个格子,每个格子独立统计亮度信息。常见的分区分法有:

分区方案 格子数 适用场景
3×3 9 简单场景,计算量小
5×5 25 通用场景,平衡精度与算力
7×7 49 复杂场景,人脸检测辅助
15×15 225 高精度场景,需要硬件加速

我个人建议:移动端用5×5就够了。再细的格子,收益不大,反而增加带宽压力。

3.2 曝光权重图设计

有了分区统计,接下来要回答一个问题:哪个区域更重要?

曝光权重图就是干这个的。它给每个分区分配一个权重系数,权重高的区域对最终曝光决策影响更大。

3.2.1 权重图的设计原则

  • 中心优先:画面中心区域权重高,因为主体通常在那里。
  • 人脸优先:检测到人脸的区域,权重应该显著提高。
  • 过曝/欠曝惩罚:已经过曝或欠曝的区域,权重可以降低,避免「死区」干扰决策。
  • 运动区域降权:运动物体可能导致统计不稳定,适当降低权重。

我的经验:权重图不要设计得太「陡」。我曾经把中心区域权重设成边缘的10倍,结果画面稍微偏移一点,曝光就剧烈抖动。后来改成平滑过渡,稳定性好很多。

3.2.2 权重图生成流程

权重图通常是动态生成的。每次帧处理时,根据当前场景信息重新计算。流程如下:

  1. 基础权重:以中心为原点,生成高斯分布权重。
  2. 人脸叠加:检测到人脸,在人脸区域叠加高权重。
  3. 亮度修正:过曝/欠曝区域权重乘以衰减系数(比如0.3)。
  4. 归一化:所有权重加起来等于1,保证总权重不变。

3.3 曝光时间与增益分配策略

统计信息有了,权重图也有了。接下来就是算具体的曝光参数:曝光时间(T)和增益(Gain)。

这里有个关键问题:同样的亮度,可以用长曝光+低增益,也可以用短曝光+高增益。怎么选?

3.3.1 曝光三角关系

曝光量 = 场景亮度 × 曝光时间 × 增益。但增益会引入噪声。所以分配策略的核心是:在满足帧率要求的前提下,尽量用曝光时间,少用增益。

策略 曝光时间 增益 效果
低光照优先 尽量长 尽量低 噪声最小,但可能卡顿
帧率优先 固定短 动态调整 流畅,但噪声大
平衡模式 动态调整 动态调整 折中方案

3.3.2 增益分配的具体算法

假设目标亮度为L_target,当前统计亮度为L_curr。需要调整的倍率R = L_target / L_curr。

分配逻辑:

// 伪代码:曝光时间与增益分配
float R = targetLuminance / currentLuminance;

// 先尝试调整曝光时间
float newExposureTime = currentExposureTime * R;

if (newExposureTime <= maxExposureTime) {
    // 曝光时间够用,增益不变
    exposureTime = newExposureTime;
    gain = currentGain;
} else {
    // 曝光时间到上限了,剩下的用增益补
    exposureTime = maxExposureTime;
    float remainingR = R / (maxExposureTime / currentExposureTime);
    gain = currentGain * remainingR;
    
    // 增益不能超过上限
    if (gain > maxGain) {
        gain = maxGain;
        // 此时亮度可能达不到目标,接受吧
    }
}

注意:增益上限一定要设。我曾经在一个项目里忘了限幅,结果暗光场景下增益飙到64倍,画面全是噪点,根本没法看。

3.4 核心流程总览

把上面这些串起来,AE的核心流程就是:

AE核心算法流程 输入RAW数据 统计信息提取 亮度直方图 + 分区统计 曝光权重图设计 中心优先 + 人脸叠加 目标亮度计算 加权平均目标亮度 曝光时间与增益分配 先调时间,再调增益,上限保护 关键约束 帧率上限 / 噪声容忍度 增益上限 / 闪烁避免

3.5 避坑指南

做AE落地,有几个坑我踩过,分享给你:

  • 统计滞后:统计信息来自上一帧,但曝光参数影响的是下一帧。场景变化快的时候,会有滞后。我建议加一个预测滤波器,根据历史趋势预估当前亮度。
  • 闪烁问题:在50Hz/60Hz灯光下,曝光时间设置不当会导致画面闪烁。解决办法是曝光时间锁定为光源周期的整数倍(比如10ms或8.33ms)。
  • 增益突变:增益不要跳变太大。我曾经一次调了2倍增益,画面亮度突然变化,用户反馈「闪了一下」。后来加了平滑过渡,每次增益变化不超过20%。
  • 过曝保护:高光区域一旦过曝,信息就永久丢失了。AE应该预留一点余量,不要追求「刚好最亮」。我一般把目标亮度设在最大亮度的85%~90%。

一句话总结:AE的核心不是算得准,而是算得稳。用户对「亮度慢慢变准」的容忍度,远高于「亮度突然跳变」。