4. AF 搜索策略:全局搜索、爬山算法、二分搜索、黄金分割搜索、自适应步长搜索
自动对焦的核心,说白了就是让镜头找到那个让图像最清晰的位置。但怎么找?总不能把整个行程都扫一遍吧?那太慢了。我做了这么多年 ISP,见过太多因为搜索策略选错导致对焦又慢又抖的案子。今天咱们就把五种主流策略掰开揉碎讲清楚。
4.1 全局搜索——最笨但最可靠的方法
全局搜索,也叫全行程扫描。镜头从近端走到远端,每走一步算一次清晰度评价函数值,最后挑出最大值对应的位置。
适用场景:首次对焦、场景切换后的重新对焦、调试阶段验证镜头一致性。
我刚开始做摄像头驱动时,就喜欢先用全局搜索摸一遍镜头的特性。为什么呢?因为这时候你还没摸清镜头的脾气,全局搜索能给你最完整的清晰度曲线。
| 项目 | 说明 |
|---|---|
| 步长 | 通常取镜头行程的 1/100 ~ 1/200 |
| 计算量 | O(n),n 为步数,一般 100~200 次 |
| 精度 | 受步长限制,步长越小越准但越慢 |
| 抗噪性 | 强,因为采样点密集,可做后处理平滑 |
注意:全局搜索不适合视频连续对焦。你想想看,每次都要扫一遍,画面肯定卡顿。我曾经在一个 4K 视频项目中试过,结果用户反馈对焦时画面像幻灯片一样——后来果断换成了混合策略。
4.2 爬山算法——最常用的局部搜索
爬山算法的思路很直观:往清晰度值增大的方向走,直到找到峰值。就像爬山一样,一直往上爬,爬到顶为止。
具体流程是这样的:
- 从当前位置出发,先往一个方向走一步
- 如果清晰度值变大,继续往同方向走
- 如果清晰度值变小,掉头往反方向走
- 如果两个方向都变小,说明到了峰顶,停止
我的经验:爬山算法最怕的是局部峰值。比如镜头上有灰尘、或者场景里有纹理稀疏的区域,清晰度曲线会出现假峰。我一般会在算法里加一个"越峰检测"——如果连续下降超过 3 步,才判定为真峰顶。
爬山算法的步长怎么选?这是个学问。固定步长容易出问题:步长太大,可能跳过真正的峰值;步长太小,对焦太慢。我个人习惯用动态步长——初始大步快速接近,接近峰值时自动减小步长。
4.3 二分搜索——快但挑场景
二分搜索的前提是:清晰度曲线是单峰的。也就是说,从近到远,清晰度先增后减,只有一个最大值。
算法流程:
- 取行程中点,计算清晰度值
- 再取中点两侧各一点,比较三者大小
- 舍弃清晰度值较小的一侧,在剩下的一半继续搜索
- 重复直到区间小于阈值
二分搜索的收敛速度是 O(log n),比全局搜索快得多。但问题在于——现实中的清晰度曲线往往不是完美的单峰。镜头马达的迟滞、场景中的周期性纹理,都会破坏单峰假设。
我曾经踩过的坑:在一个条形码扫描项目中用了二分搜索,结果因为条码的周期性黑白条纹,清晰度曲线出现了多个等高的峰值,二分搜索直接懵了,对焦对到了错误的位置。后来我加了一个"峰值置信度"判断,才解决了这个问题。
4.4 黄金分割搜索——比二分更聪明
黄金分割搜索是二分搜索的升级版。它不取中点,而是取黄金分割点(约 0.618 和 0.382 的位置)。这样做的好处是:每次迭代只需要计算一个新点,另一个点可以复用上一次的结果。
你看这个对比就明白了:
| 策略 | 每次迭代计算次数 | 收敛速度 | 区间缩小比例 |
|---|---|---|---|
| 二分搜索 | 2 次(中点 + 一侧) | O(log n) | 50% |
| 黄金分割 | 1 次(复用另一侧) | O(log n) | 38.2% |
黄金分割搜索每次只算一个新点,计算量更少。虽然区间缩小比例不如二分(38.2% vs 50%),但整体效率反而更高——因为清晰度评价函数的计算本身就很耗时。
实际应用:我在做高端安防摄像机的自动对焦时,用的就是黄金分割搜索。配合一个粗搜索(大步长全局扫描)确定初始区间,然后用黄金分割精细搜索。整体对焦时间控制在 0.3 秒以内,效果很不错。
4.5 自适应步长搜索——动态调整的艺术
前面几种策略的步长都是固定的。自适应步长搜索则根据当前清晰度值的变化趋势,动态调整步长。
核心逻辑:
- 清晰度变化大 → 大步前进,快速接近
- 清晰度变化小 → 小步微调,精确定位
- 清晰度下降 → 立即掉头,减小步长
我一般用清晰度值的差分作为步长调整的依据。比如:
// 伪代码:自适应步长调整
step = base_step * (1 + k * abs(diff))
if diff > 0:
// 清晰度在上升,保持方向
direction = current_direction
else:
// 清晰度下降,掉头并减小步长
direction = -current_direction
step = step * 0.5
这里的 k 是步长增益系数,需要根据镜头特性调。k 太大,步长变化剧烈,容易震荡;k 太小,自适应效果不明显。
关键参数:自适应步长搜索有三个参数需要调:基础步长、步长增益系数、最小步长阈值。我建议在调试时先固定两个,调第三个,逐个击破。
4.6 五种策略对比与选型建议
说了这么多,到底该用哪个?我整理了一个对比表,方便你选型:
| 策略 | 速度 | 精度 | 抗噪性 | 适用场景 |
|---|---|---|---|---|
| 全局搜索 | 慢 | 中 | 强 | 调试、首次对焦 |
| 爬山算法 | 中 | 高 | 弱 | 连续对焦、已知场景 |
| 二分搜索 | 快 | 高 | 弱 | 单峰场景、快速对焦 |
| 黄金分割 | 快 | 高 | 中 | 高精度、低功耗场景 |
| 自适应步长 | 中快 | 高 | 中 | 复杂场景、多峰曲线 |
实际项目中,我很少只用一种策略。通常的做法是:先用全局搜索或大步长爬山快速定位大致区间,再用黄金分割或自适应步长做精细搜索。这种混合策略既保证了速度,又兼顾了精度。
最后提醒一句:不管用哪种搜索策略,清晰度评价函数的质量才是根本。函数选错了,再好的搜索算法也白搭。下一节咱们就专门讲清晰度评价函数的设计——嗯,这个放到后面再说。