4. 自动曝光控制:测光模式、曝光时间与增益控制、AE收敛策略、闪烁抑制
自动曝光(AE)是ISP管线的第一道关卡。说白了,它决定了你拍到的画面是亮是暗。低光照场景下,AE要是没调好,后面所有增强算法都白搭——噪点满天飞、运动模糊、或者干脆一片死黑。
我这些年调过的AE策略少说也有几十套。从功能机到旗舰机,从普通CMOS到带HDR的传感器,核心逻辑没变过,但细节上全是坑。今天咱们就把AE的四个核心模块拆开聊。
4.1 测光模式:你让相机看哪里?
测光模式决定了AE的“注意力”放在画面的哪个区域。低光照下,选错模式,画面直接废掉。
| 测光模式 | 原理 | 低光适用场景 | 我踩过的坑 |
|---|---|---|---|
| 全局平均测光 | 全画面像素亮度取平均 | 光照均匀的场景 | 暗部有大面积黑墙时,主体过曝 |
| 中央重点测光 | 中心区域权重高,边缘低 | 人物居中、背景暗 | 主体偏移中心时,测光失效 |
| 点测光 | 只取画面中心小区域 | 极暗场景、单光源 | 测光点落在高光上,暗部全黑 |
| 分区测光 | 画面分多区,加权融合 | 复杂光照、逆光 | 权重表调不好,过渡不自然 |
我个人习惯在低光照场景下优先用分区测光。为什么?因为暗部细节和亮部高光往往同时存在,全局平均会把暗部拉亮导致噪点爆炸,点测光又容易顾此失彼。分区测光配合合理的权重表,能保住主体亮度,同时不让背景死黑。
4.2 曝光时间与增益控制:低光的核心博弈
曝光时间和增益是AE的两把刀。曝光时间长了,画面亮但容易糊;增益高了,画面亮但噪点多。低光照下,这个博弈尤其激烈。
先看公式:
目标亮度 = 当前亮度 × (曝光时间_新 / 曝光时间_旧) × (增益_新 / 增益_旧)
嗯,很简单对吧?但实际调起来,你得考虑传感器的物理限制。
4.2.1 曝光时间的约束
- 最大曝光时间: 手持拍摄一般不超过33ms(30fps),再长就糊了。有OIS可以放宽到50ms左右。
- 最小曝光时间: 不能低于传感器的最小行时间,否则画面闪烁。
- 步长: 曝光时间调整步长建议用1/3档或1/2档,太粗会跳变,太细收敛慢。
4.2.2 增益的约束
- 模拟增益 vs 数字增益: 模拟增益优先,数字增益最后用。模拟增益引入的噪声远小于数字增益。
- 增益上限: 我一般把模拟增益上限设在8x(18dB),数字增益上限设在4x(12dB)。超过这个值,画面噪点就不可控了。
- 增益步长: 0.1x或0.2x,太大会导致亮度跳变。
我曾经在一个项目中,为了追求极低光照下的亮度,把数字增益拉到了8x。结果画面亮是亮了,但噪点像雪花一样。后来我强制把数字增益上限卡在4x,同时把曝光时间从33ms放宽到50ms(配合OIS),画质反而好了很多。
4.3 AE收敛策略:从暗到亮的平滑过渡
AE收敛,就是相机从当前亮度调整到目标亮度的过程。低光照下,收敛策略直接影响用户体验——你想想看,从暗处走到亮处,画面如果忽明忽暗,用户会怎么想?
收敛策略的核心参数有三个:
| 参数 | 作用 | 低光推荐值 | 说明 |
|---|---|---|---|
| 目标亮度 | AE要到达的最终亮度 | 18%灰的80%~120% | 低光下可以适当降低目标,避免噪点 |
| 收敛速度 | 每帧调整的幅度 | 0.1~0.3(归一化) | 太快会振荡,太慢用户觉得卡 |
| 死区 | 允许的亮度误差范围 | ±5% | 避免在目标附近来回跳 |
我常用的收敛策略是指数平滑:
// 指数平滑收敛
float smooth_factor = 0.2f; // 收敛速度
float current_brightness = get_current_brightness();
float target_brightness = get_target_brightness();
float error = target_brightness - current_brightness;
if (abs(error) < dead_zone) {
// 在死区内,不调整
return;
}
float adjustment = error * smooth_factor;
// 将adjustment映射到曝光时间和增益
adjust_exposure(adjustment);
这个策略的好处是平滑、无振荡。但要注意——收敛速度不能是固定的。我在项目中遇到过一个问题:从室内走到室外,亮度变化很大,固定速度导致收敛太慢,画面长时间过曝。后来我改成自适应收敛速度:误差大时速度快,误差小时速度慢。
4.4 闪烁抑制:50Hz/60Hz的噩梦
闪烁(Flicker)是AE里最烦人的问题之一。室内灯光下,50Hz(中国、欧洲)或60Hz(美国、日本)的交流电会导致画面亮度周期性变化。你想想看,拍视频时画面一闪一闪的,用户不骂才怪。
闪烁的根本原因是曝光时间不是灯光周期的整数倍。以50Hz为例,灯光周期是10ms。如果曝光时间是15ms,那么每个帧捕捉到的光周期数不同,亮度就会波动。
解决方案很简单:曝光时间锁定为灯光周期的整数倍。
| 电网频率 | 灯光周期 | 推荐曝光时间(整数倍) |
|---|---|---|
| 50Hz | 10ms | 10ms, 20ms, 30ms, 40ms... |
| 60Hz | 8.33ms | 8.33ms, 16.67ms, 25ms, 33.33ms... |
但这里有个坑——自动检测频率。你不能写死50Hz或60Hz,因为用户可能在不同国家使用。我常用的方法是:
- 在AE启动时,快速扫描一组曝光时间(比如从1ms到40ms,步长1ms)。
- 记录每个曝光时间下的亮度波动幅度。
- 波动幅度最小的曝光时间,就是整数倍周期。
- 根据整数倍周期反推电网频率。
还有一个细节:LED灯。LED灯的闪烁频率可能不是50Hz/60Hz的整数倍,而是PWM调光频率(比如200Hz)。这种情况下,整数倍策略可能失效。我的做法是:如果检测到闪烁但无法匹配50Hz/60Hz,就启用防闪烁滤波器——对亮度值做低通滤波,消除高频波动。
4.5 本章知识体系
下面这张图把AE的四个模块串起来了。你可以看到,测光模式是输入,曝光时间和增益是执行器,收敛策略是控制器,闪烁抑制是保护机制。
嗯,这张图基本把AE的四个模块和它们的关系说清楚了。实际调优时,这四个模块是联动的——你改了测光模式,目标亮度就变了,收敛策略要跟着调;你锁定了曝光时间,增益的调整范围就受限了。没有一套参数能通吃所有场景,关键是根据你的传感器特性和目标场景做取舍。