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 日志,怎么判断问题?我一般按这个流程来:

  1. 看搜索范围:检查 lens_pos 是否覆盖了整个行程。如果每次都是从 0 跑到 1023,说明没有利用景深信息做范围限制。
  2. 看步长变化:步长如果一直不变,说明算法没有做粗精切换。正常流程应该是大步粗搜、小步精搜。
  3. 看峰值稳定性:连续几帧的 focus_value 如果剧烈抖动,说明信号噪声大,或者场景在变化。
  4. 看状态机跳转:如果 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 的相对变化趋势,而不是值。

嗯,对焦慢和拉风箱的问题,说到底就是"信号"和"策略"的匹配问题。信号质量不好,策略再优化也有限;策略不合理,信号再好也白搭。日志就是你连接这两者的桥梁,用好它,问题就解决了一半。