3. 全局搜索:遍历搜索、斐波那契搜索、黄金分割搜索

全局搜索,说白了就是「地毯式排查」。当镜头离焦点很远,或者场景太复杂时,局部搜索很容易掉进坑里。这时候,你得先做一轮全局扫描,找到大致位置,再交给精细算法。

我刚开始做对焦算法时,总觉得全局搜索太笨——费时间、费算力。后来在户外强光下拍树叶,局部搜索直接卡在局部极值上,画面糊成一团。嗯,从那以后,我再也不敢小看全局搜索了。

3.1 遍历搜索:最笨但最可靠

遍历搜索的思路很简单:把整个对焦范围分成 N 步,每一步拍一张图,算清晰度,然后挑最大值。就像你在停车场找车,一辆一辆看过去,总能找到。

核心公式:
步长 = (对焦范围上限 - 下限) / 步数
清晰度值 = 拉普拉斯方差 / 索贝尔梯度 / Brenner 梯度...

我在项目中遇到过一个问题:步长设太大,容易漏掉焦点;步长设太小,时间又受不了。后来我总结了一个经验——

场景类型 推荐步数 单步耗时(ms) 总耗时(ms)
低倍镜(10x) 20~30 30~50 600~1500
中倍镜(40x) 40~60 50~80 2000~4800
高倍镜(100x) 80~120 80~120 6400~14400
我曾经踩过的坑: 遍历搜索时,如果场景中有运动物体(比如流水、飘动的树叶),清晰度曲线会剧烈抖动。我建议在每一步做 3 次采样取中值,能有效抑制噪声。

3.2 斐波那契搜索:数学家的优雅解法

斐波那契搜索,本质上是一种「不对称二分法」。它利用斐波那契数列来划分搜索区间,每次只比较两个点,就能缩小范围。你想想看,这比遍历搜索聪明多了——不用拍那么多张图。

为什么用斐波那契数列?因为它的比值趋近黄金分割(0.618),但每一步都是整数步长,适合离散的电机控制。我个人习惯在步数较少(< 50)时用斐波那契,效果比黄金分割更稳定。

// 斐波那契搜索伪代码
function fibonacciSearch(low, high, n):
    fib = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    k = findK(fib, n)  // 找到大于等于 n 的斐波那契数索引
    
    x1 = low + fib[k-2] * (high - low) / fib[k]
    x2 = low + fib[k-1] * (high - low) / fib[k]
    
    while k > 1:
        if clarity(x1) > clarity(x2):
            high = x2
            x2 = x1
            x1 = low + fib[k-2] * (high - low) / fib[k]
            k = k - 1
        else:
            low = x1
            x1 = x2
            x2 = low + fib[k-1] * (high - low) / fib[k]
            k = k - 1
    
    return (low + high) / 2
小技巧: 斐波那契搜索要求清晰度曲线是单峰的。如果场景有多个峰值(比如多层玻璃反射),建议先做粗遍历找到主峰区域,再用斐波那契精搜。

3.3 黄金分割搜索:连续域的王者

黄金分割搜索和斐波那契很像,区别在于它用固定的 0.618 比例。说白了,就是每次在区间内取两个点,位置在 0.382 和 0.618 处,然后比较、缩小区间。

我记得有一次做显微镜自动对焦,电机步进精度是 0.1μm,斐波那契的整数步长反而限制了精度。换成黄金分割后,收敛速度更快,而且能直接输出浮点位置。

特性 遍历搜索 斐波那契搜索 黄金分割搜索
搜索方式 等步长扫描 不对称二分 固定比例二分
收敛速度 O(N) O(log N) O(log N)
适用场景 初始搜索、多峰 离散步进电机 连续运动、高精度
抗噪能力 强(可多次采样) 中 中
实现复杂度 低 中 低
我的实战建议:
- 第一次对焦:用遍历搜索(20~30步),找到大致位置
- 第二次精搜:用黄金分割搜索(10~15次迭代),收敛到亚微米级
- 如果电机是步进式:换成斐波那契搜索,避免浮点舍入误差

3.4 三种搜索策略的对比与选择

你可能会问:到底该用哪个?其实没有银弹。我一般这样选——

  • 场景一: 第一次对焦,或者场景变化剧烈 → 遍历搜索(稳)
  • 场景二: 已知大致位置,电机步进精度有限 → 斐波那契搜索(准)
  • 场景三: 连续运动控制,需要高精度浮点输出 → 黄金分割搜索(快)

为什么会这样?因为遍历搜索不怕多峰,斐波那契适合离散控制,黄金分割在连续域里效率最高。你想想看,如果场景里既有玻璃反光又有运动物体,直接上黄金分割,大概率会卡在局部极值上。

我曾经犯过的错: 在低对比度场景(比如白墙、均匀表面)用黄金分割搜索,清晰度曲线太平坦,算法直接随机跳动。后来我加了一个「最小梯度阈值」判断——如果相邻点的清晰度差小于 5%,就认为当前区域是平坦区,直接跳到下一个候选区。
全局搜索策略选择流程图 开始全局搜索 是否首次对焦或场景剧烈变化? 是 遍历搜索(20~30步) 否 判断电机类型 确定大致焦点区域 步进电机 → 斐波那契 | 连续电机 → 黄金分割 说明:遍历搜索用于粗定位,斐波那契/黄金分割用于精搜,两者配合使用效果最佳

最后说一句:全局搜索不是终点,而是起点。找到大致位置后,我会立刻切换到爬山算法或曲线拟合,把精度推到极限。这三种搜索策略,说白了就是给你一个「靠谱的初始值」——没有它,后面的精细算法全是空中楼阁。