4. AE 控制策略:目标亮度设定、PID控制与步进调整、防闪烁处理
曝光控制,说白了就是让画面亮度刚刚好。太暗了细节全丢,太亮了高光一片死白。我做了这么多年 ISP,见过太多「算法调参一时爽,实景测试火葬场」的案例。这一章,咱们就把 AE 控制的三个核心模块拆开揉碎讲清楚。
4.1 目标亮度设定:你到底想要多亮?
AE 的第一步,不是算曝光,而是定目标。目标亮度(Target Luminance)设错了,后面 PID 调得再好也没用。
我个人习惯把目标亮度分成三个层级:
- 全局平均亮度:整帧 Y 通道的平均值。适合风景、文档等均匀场景。
- 人脸区域亮度:检测到人脸后,优先保证人脸曝光准确。背景过曝或欠曝可以忍。
- ROI 加权亮度:用户点击对焦框,或者算法检测到主体,给这个区域更高权重。
举个例子。我在做手机摄像头项目时,遇到过一个问题:逆光下人脸全黑,背景天空却正常。后来我们把人脸区域的权重从 0.3 提到 0.7,全局亮度目标从 120 降到 100(8bit 数据),效果立竿见影。
目标亮度设定经验值(8bit Y 通道)
| 场景类型 | 目标亮度范围 | 说明 |
|---|---|---|
| 室内人像 | 100 - 120 | 肤色自然,背景不过曝 |
| 室外风景 | 110 - 130 | 保留天空细节和地面纹理 |
| 夜景/暗光 | 60 - 90 | 避免噪点爆炸,保留暗部层次 |
| 文档/扫码 | 140 - 160 | 文字清晰,背景干净 |
你可能会问:目标亮度是固定值吗?当然不是。我建议根据环境照度做动态调整。比如从室内走到室外,目标亮度可以平滑过渡,而不是突变。否则画面会「闪一下」,用户体验极差。
4.2 PID 控制:让曝光收敛又快又稳
目标定好了,接下来就是怎么调曝光参数。PID(比例-积分-微分)控制是 AE 最经典的算法,没有之一。
先看公式:
Error = TargetLuminance - CurrentLuminance
Gain = Kp * Error + Ki * ∫Error dt + Kd * d(Error)/dt
嗯,看着有点抽象。我拆开讲:
- P(比例):当前误差越大,调整幅度越大。反应快,但容易超调。
- I(积分):累计过去的误差,消除稳态偏差。比如画面一直偏暗,I 项会慢慢把曝光拉上去。
- D(微分):预测误差变化趋势,抑制震荡。场景突变时,D 项能提前刹车。
我在项目中踩过一个坑:P 项调太大,画面在目标亮度附近来回震荡,像呼吸一样。后来把 Kp 从 0.8 降到 0.3,同时加了一点 Kd,收敛就平滑了。
调参口诀:P 大响应快,I 小稳误差,D 中防震荡。实际调试时,先调 P 让系统能收敛,再加 I 消除静差,最后用 D 抑制过冲。
4.3 步进调整:曝光变化要「温柔」
PID 算出来的 Gain 是连续值,但硬件参数(曝光时间、模拟增益、数字增益)是离散的。怎么把连续值映射到离散档位?步进调整就是干这个的。
我习惯把步进调整分成两步:
- 粗调:先调曝光时间,再调模拟增益,最后调数字增益。为什么这个顺序?因为曝光时间对画质影响最小,数字增益会放大噪声。
- 微调:在相邻档位之间做插值,或者用数字增益做精细补偿。
举个例子。当前帧算出来需要增加 1.7 倍亮度。我会先看曝光时间能不能加一档(比如从 10ms 到 15ms,增益 1.5 倍),剩下的 0.2 倍用模拟增益补。如果模拟增益也到上限了,再动数字增益。
注意:步进调整的步长不能太大。我曾经试过一步跨三档,结果画面亮度跳变明显,用户反馈「闪瞎眼」。建议每帧最多调整一档曝光时间或一档增益。
4.4 防闪烁处理:跟 50/60Hz 灯光死磕
荧光灯和 LED 灯会以 100Hz 或 120Hz 的频率闪烁(50Hz 电网对应 100Hz,60Hz 电网对应 120Hz)。如果曝光时间不是闪烁周期的整数倍,画面就会出现明暗条纹——这就是闪烁(Flicker)。
防闪烁的核心思路就一句话:让曝光时间等于闪烁周期的整数倍。
具体做法:
- 检测电网频率:通过统计画面亮度波动,判断是 50Hz 还是 60Hz 环境。
- 锁定曝光时间:50Hz 下,曝光时间必须是 10ms 的整数倍(100Hz 闪烁周期 10ms)。60Hz 下,必须是 8.33ms 的整数倍(120Hz 闪烁周期 8.33ms)。
- 限制调整范围:防闪烁模式下,曝光时间只能在这些离散值之间切换。
我记得有一次在印度做项目,当地电网既有 50Hz 也有 60Hz 区域。我们加了一个自动检测逻辑:前 10 帧统计亮度波动频率,自动切换防闪烁模式。效果还不错,但偶尔会误判。后来加了置信度阈值,连续 5 帧检测到同一频率才切换,误判率就降下来了。
防闪烁曝光时间表
| 电网频率 | 闪烁频率 | 允许曝光时间(ms) |
|---|---|---|
| 50 Hz | 100 Hz | 10, 20, 30, 40, 50 ... |
| 60 Hz | 120 Hz | 8.33, 16.67, 25, 33.33 ... |
你可能会问:如果防闪烁和曝光需求冲突怎么办?比如暗光下需要 25ms 曝光,但 50Hz 下只能选 20ms 或 30ms。我的建议是:优先保证防闪烁,然后用增益补偿亮度。因为闪烁条纹一旦出现,后期很难消除,而增益带来的噪声至少还能降噪处理。
4.5 本章知识结构图
下面这张图把 AE 控制策略的四个模块串起来了。你可以看到目标亮度是输入,PID 是核心计算,步进调整是执行层,防闪烁是约束条件。
4.6 避坑指南
最后分享几个我踩过的坑,希望能帮你少走弯路。
- PID 积分饱和:如果场景长时间过暗,I 项会累积到很大。等场景突然变亮,I 项需要很久才能退回来,导致过曝。解决办法是加积分限幅,或者条件积分(误差大时停止积分)。
- 防闪烁误判:有些 LED 灯调光频率不是 100/120Hz,比如 PWM 调光在 200Hz 以上。这时候防闪烁算法反而会限制曝光时间,导致画面闪烁。我建议加一个「闪烁检测置信度」开关,低置信度时退回到普通模式。
- 步进调整与 PID 打架:PID 算出来要调 0.3 档,但步进调整只能调整档。结果就是 PID 反复震荡。我的做法是:步进调整后,把 PID 的积分项重置,避免累积误差。
调试小技巧:在 ISP 调试工具里同时显示目标亮度、当前亮度、PID 输出和步进档位。四根曲线放在一起看,问题一目了然。我曾经靠这个方法半小时就定位了一个收敛慢的问题。