3. AF 常见问题1:对焦慢、拉风箱——原因分析与日志定位方法
对焦慢和拉风箱,是 AF 调试里最常碰到的两个问题。我入行那会儿,第一次看到镜头在那来回伸缩就是锁不住焦,心里真有点慌。后来做多了才发现,这类问题其实有规律可循。
说白了,对焦慢是算法在搜索最佳焦点的路上花了太多时间。拉风箱更严重——镜头在近端和远端之间反复振荡,根本找不到一个稳定的峰值。为什么会这样?我们得从根上找原因。
3.1 对焦慢的典型原因
我个人习惯把对焦慢的原因分成三类:硬件限制、算法策略、场景干扰。下面这张图能帮你快速建立整体认知。
3.2 拉风箱的根因
拉风箱比单纯的对焦慢更让人头疼。我记得有一次在户外调试,镜头对着远处的建筑,就是来回跑个不停。后来定位发现,问题出在 AF 窗口选错了——窗口覆盖了一大片天空,对比度信号几乎为零。
拉风箱的核心原因,我总结为以下几点:
- 对比度不足:场景太平坦,AF 评价函数找不到明显的峰值。说白了就是画面里没有"纹理"。
- 局部极值陷阱:算法在搜索过程中掉进了一个局部峰值,但那个峰值不是真正的焦点。镜头会在局部极值附近来回试探。
- 搜索范围过大:从无穷远到微距全量搜索,中间又没有有效的剪枝策略。镜头跑完整个行程,时间自然就长了。
- AF 窗口位置不当:窗口选在了低对比度区域,或者窗口太小导致信号不稳定。
- 帧率不稳定:ISP 送帧有抖动,AF 算法拿到的数据不连续,导致每次计算的结果都不一样。
⚠️ 注意: 拉风箱有时不是 AF 算法本身的问题,而是 sensor 或 ISP 的帧率波动引起的。先确认底层数据流是否稳定,再调 AF 参数。这个顺序搞反了,你会浪费大量时间。
3.3 日志定位方法
遇到对焦慢或拉风箱,我第一件事就是开日志。没有日志,你就是在盲调。我个人习惯在 AF 驱动层和应用层同时打日志,这样能快速定位问题出在哪一层。
3.3.1 关键日志字段
一份合格的 AF 日志,至少应该包含以下信息:
| 字段 | 说明 | 典型值 |
|---|---|---|
frame_id |
当前帧序号 | 1234 |
lens_pos |
镜头当前位置(步进数或 DAC 值) | 256 |
focus_value |
当前帧的 AF 评价函数值 | 8923 |
search_dir |
搜索方向(正向/反向) | 1 或 -1 |
step_size |
当前步长 | 8 |
peak_pos |
已记录的峰值位置 | 512 |
status |
AF 状态机当前状态 | SCANNING / FOCUSED / FAILED |
3.3.2 日志分析实战
假设你拿到了一段 AF 日志,怎么判断问题?我一般按这个流程来:
- 看搜索范围:检查
lens_pos是否覆盖了整个行程。如果每次都是从 0 跑到 1023,说明没有利用景深信息做范围限制。 - 看步长变化:步长如果一直不变,说明算法没有做粗精切换。正常流程应该是大步粗搜、小步精搜。
- 看峰值稳定性:连续几帧的
focus_value如果剧烈抖动,说明信号噪声大,或者场景在变化。 - 看状态机跳转:如果
status在 SCANNING 和 FOCUSED 之间反复切换,那就是典型的拉风箱。
💡 实战技巧: 我习惯把日志导入 Excel 或 Python,画一条 lens_pos 随时间变化的曲线。如果曲线是平滑的锯齿波,说明搜索正常;如果曲线在某个区间来回振荡,那就是拉风箱。一眼就能看出来。
3.3.3 日志配置示例
下面是我常用的 AF 日志打印模板,你可以直接参考:
// AF 驱动层日志
#define AF_LOG_TAG "[AF_DRV]"
#define af_log(fmt, ...) \
printf(AF_LOG_TAG "[frame:%u][pos:%d][fv:%d][dir:%d][step:%d][peak:%d][status:%s] " fmt "\n", \
frame_id, lens_pos, focus_value, search_dir, step_size, peak_pos, \
status_to_string(status), ##__VA_ARGS__)
// 使用示例
af_log("search start, range=[%d, %d]", search_min, search_max);
af_log("peak found at pos=%d, fv=%d", peak_pos, peak_fv);
af_log("focus timeout, fallback to pos=%d", default_pos);
3.4 常见问题排查表
我把平时遇到最多的几种情况整理成了表格,方便你对照排查:
| 现象 | 可能原因 | 日志特征 | 解决方向 |
|---|---|---|---|
| 对焦慢,但最终能对上 | 搜索步长太小,或粗精切换阈值不合理 | lens_pos 变化缓慢,step_size 始终为小值 | 增大粗搜步长,调整粗精切换的 fv 梯度阈值 |
| 拉风箱,镜头来回跑 | 对比度不足,或 AF 窗口选错 | lens_pos 在两端之间振荡,fv 值无明显峰值 | 检查 AF 窗口位置,增大窗口尺寸,或切换到中心权重模式 |
| 对焦到错误位置 | 局部极值干扰,或场景中有强光源 | peak_pos 不在预期位置,fv 曲线有多个峰值 | 增加峰值验证机制,或使用多帧确认策略 |
| 偶尔对焦失败 | 帧率抖动,或 sensor 输出不稳定 | frame_id 不连续,或 fv 值跳变 | 检查 ISP pipeline 帧率,增加数据有效性校验 |
📌 我的经验: 拉风箱问题里,有将近一半是 AF 窗口位置不对导致的。调试初期,先把窗口设大一点,甚至用全图统计,等 AF 基本稳定了再优化窗口位置。别一上来就追求极致的小窗口。
3.5 避坑指南
最后分享几个我踩过的坑:
- 别忽略马达特性:不同马达的步进响应时间不一样。VCM 马达和步进马达的延迟差异很大,日志里要加上马达型号信息。
- 注意日志缓冲区溢出:AF 日志如果打得太频繁,可能会撑爆 log buffer,导致丢帧。我一般只在调试阶段开全量日志,发布版本只保留关键状态跳转日志。
- 场景复现要可控:我曾经在户外调试拉风箱,结果风一吹树叶动,场景一直在变,日志根本没法分析。后来我改用静态测试图卡,问题一下子就定位了。
- 不要只看 fv 值:fv 值受光照影响很大。同一个场景,白天和晚上的 fv 能差好几倍。我习惯看 fv 的相对变化趋势,而不是值。
嗯,对焦慢和拉风箱的问题,说到底就是"信号"和"策略"的匹配问题。信号质量不好,策略再优化也有限;策略不合理,信号再好也白搭。日志就是你连接这两者的桥梁,用好它,问题就解决了一半。