4. 安防场景实战:红外夜视模式下的AF调优、宽动态(WDR)场景下的AF策略、多目标跟踪时的连续AF
好,咱们进入实战环节。前面几章讲了AF的基础原理和核心算法,但说实话,那些东西在实验室里跑得再好,到了真正的安防场景,该翻车还是翻车。我这些年调过的设备,少说也有上百款了,踩过的坑比走过的路还多。今天就把红外夜视、宽动态、多目标跟踪这三个最头疼的场景,掰开了揉碎了讲清楚。
4.1 红外夜视模式下的AF调优
先说说红外夜视。这个场景有多难?说白了,就是相机几乎「瞎」了。可见光没了,全靠红外灯补光,画面是黑白的,对比度极低,而且红外光波长和可见光不一样,焦平面天然就有偏移。
我记得有一次,给一个园区做夜间监控升级。白天对焦好好的,一到晚上画面就糊成一片。甲方项目经理急得直跳脚,说「你们这设备还不如我手机拍得清楚」。我过去一看,AF算法还在用白天的策略,那肯定不行。
4.1.1 红外截止滤镜的切换补偿
大多数安防摄像机都有ICR(红外截止滤镜)。白天滤镜在,滤掉红外光;晚上滤镜移开,让红外光进来。问题就出在这里——滤镜移开的那一刻,光路变了,焦平面也变了。
我个人的习惯是,在ICR切换的瞬间,强制触发一次AF重新对焦。但这里有个坑:
- 不能直接用白天的对焦位置——红外偏移量通常在5~20个步长之间,具体看镜头和传感器匹配
- 不能重新全行程扫描——太慢了,用户能明显感觉到「卡一下」
那怎么办?我一般用「偏移量预补偿 + 局部微调」的策略:
// 红外偏移预补偿示例(伪代码)
int infrared_offset = calibrate_offset(lens_id, sensor_id);
int day_focus_pos = get_current_focus_position();
if (icr_switched_to_ir) {
int night_start_pos = day_focus_pos + infrared_offset;
set_focus_position(night_start_pos);
// 然后在 ±3 步长范围内做精细搜索
fine_tune_focus(night_start_pos - 3, night_start_pos + 3);
}
4.1.2 低照度下的AF评价函数选择
红外夜视下,图像信噪比极低。传统的Tenengrad梯度函数,在噪声面前基本失效——噪声的梯度比真正的边缘还大。你想想看,算法把噪点当成细节去对焦,结果就是来回乱跳。
我推荐用以下两种方案:
| 评价函数 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 修正拉普拉斯(ML) | 低照度、有纹理 | 对噪声有一定抑制 | 计算量稍大 |
| 带通滤波 + 能量统计 | 极低照度、无纹理 | 抗噪能力强 | 对焦精度略低 |
我个人更倾向于第二种。在红外模式下,先做一次带通滤波,把低频背景和高频噪声都滤掉,只保留中频的边缘信息,然后再算能量。效果比直接用梯度好得多。
4.2 宽动态(WDR)场景下的AF策略
宽动态场景,说白了就是「亮的地方太亮,暗的地方太暗」。比如监控出入口,外面阳光明媚,里面黑漆漆的。这种场景下,AF算法很容易被高亮区域「带偏」。
为什么会这样?因为大多数AF评价函数都是基于全图或固定ROI的。WDR模式下,高亮区域过曝,梯度信息丢失;暗区欠曝,同样没有梯度。算法在整张图上找不到清晰的边缘,就开始乱猜。
4.2.1 动态ROI选择策略
我建议的做法是:不要用固定ROI,而是根据WDR的融合权重图来动态选择对焦区域。
现在的WDR算法,通常会把多帧曝光融合成一张图,同时生成一张权重图——权重高的区域,说明细节保留得好。我们就用这个权重图来指导AF:
- 从WDR模块拿到融合权重图
- 筛选出权重在0.6~0.9之间的像素区域(太高可能是过曝,太低可能是欠曝)
- 在这些区域中,选择梯度能量最大的区域作为ROI
- 只在这个ROI上计算AF评价函数
4.2.2 多曝光帧的AF同步问题
WDR通常需要两帧或三帧不同曝光的图像合成。但AF算法如果只拿合成后的图像做评价,会有一个延迟问题——合成帧的生成速度比原始帧慢。
我曾经遇到过一个情况:AF的反馈周期比WDR的合成周期还长,导致对焦动作永远慢半拍。画面一会儿清楚一会儿模糊,用户投诉说「这摄像头是不是坏了」。
解决方案其实不复杂:
- 方案A: 用WDR的短曝光帧单独做AF评价。短曝光帧虽然暗,但运动模糊少,边缘信息相对可靠。
- 方案B: 把AF的更新频率降到WDR合成频率的一半,保证每次AF动作都能拿到最新的合成帧。
我个人推荐方案A。短曝光帧的帧率更高,AF响应更快。但要注意,短曝光帧的噪声也大,需要配合前面说的抗噪评价函数使用。
4.3 多目标跟踪时的连续AF
最后这个场景,是最考验算法功力的。多目标跟踪,意味着画面里同时有多个移动的人或车。AF该对谁?怎么跟?
你想想看,如果AF跟着最近的目标走,结果远处突然出现一个更重要的目标(比如有人摔倒),那怎么办?如果AF平均所有目标,结果就是所有目标都模糊。
4.3.1 目标优先级与AF调度
我设计过一个基于优先级的AF调度策略,核心思路是:
| 优先级 | 目标类型 | AF行为 |
|---|---|---|
| P0(最高) | 人形目标(尤其是摔倒、奔跑) | 锁定对焦,不切换 |
| P1 | 车辆、大型物体 | 跟踪对焦,允许切换 |
| P2 | 其他移动目标 | 背景对焦,不主动跟踪 |
这个优先级不是写死的。我习惯让算法根据目标的行为动态调整优先级。比如一个目标突然加速,或者轨迹异常,优先级自动提升。
4.3.2 连续AF的平滑过渡
多目标跟踪时,AF最怕的就是频繁切换目标。每次切换,镜头都要重新对焦,画面就会「呼吸」一下。用户看着特别难受。
我的做法是:
- 不立即切换: 当检测到更优目标时,先计算当前目标和更优目标的景深差。如果景深差小于某个阈值(比如0.5米),就不切换。
- 渐进式移动: 如果必须切换,用S曲线控制对焦马达的速度,而不是直接跳到目标位置。这样画面过渡更自然。
// 平滑过渡示例(伪代码)
float current_pos = get_focus_position();
float target_pos = calculate_target_focus(high_priority_target);
if (abs(target_pos - current_pos) < DEAD_ZONE) {
// 景深差太小,不动作
return;
}
// S曲线速度控制
float speed = calculate_s_curve_speed(current_pos, target_pos);
move_focus_motor(speed, target_pos);
4.3.3 预测性对焦
这个算是我比较得意的一个设计。多目标跟踪时,如果等到目标移动了再对焦,永远慢一步。为什么不提前预测目标的位置?
我用卡尔曼滤波预测目标在下一帧的位置,然后提前把焦点移到预测位置。等目标真的到了那个位置,焦点已经到位了。效果非常明显——画面几乎感觉不到对焦延迟。
但要注意,预测性对焦不能滥用。如果目标运动轨迹突变(比如突然转身),预测会失败。我加了一个置信度判断——预测误差超过阈值时,立即切换到实时对焦模式。
嗯,这三个场景讲完了。红外夜视、宽动态、多目标跟踪,每一个都是安防行业绕不过去的坎。但反过来想,也正是这些坎,让我们的算法有了用武之地。调优没有终点,只有不断逼近极限。