1. 自动对焦基础:对焦原理、评价函数、搜索策略概述
大家好,我是老张。做图像处理这些年,我调试过最多的模块就是自动对焦。说实话,很多人觉得对焦不就是「把图像变清楚」嘛,但真正深入进去,你会发现这里面的门道比想象中多得多。
这一章,我们先打好地基。把对焦原理、评价函数、搜索策略这三个核心概念讲透。嗯,都是干货,咱们一个一个来。
1.1 对焦原理:镜头到底在干什么?
自动对焦的本质,说白了就是调整镜头位置,让被摄物体在传感器上清晰成像。你想想看,镜头其实就是一个可以前后移动的透镜组。当物体正好落在焦平面上时,图像最清晰;偏离了,图像就模糊。
为什么会这样?因为光线通过透镜后,会汇聚到一个点。如果传感器刚好在这个点上,每个像素接收到的光就是「点对点」的,画面自然锐利。如果传感器偏前或偏后,一个点就会扩散成一个圆斑——我们管它叫弥散圆。弥散圆越大,图像越糊。
核心结论:对焦过程 = 寻找镜头位置,使得弥散圆直径最小。
我在项目中遇到过一种情况:镜头模组有公差,同一个对焦指令在不同设备上实际移动距离不一样。所以,光知道理论位置没用,必须靠图像反馈来闭环校准。
1.2 评价函数:怎么判断图像清不清晰?
机器不像人眼,看一眼就知道「嗯,这张清楚了」。它需要一个数学指标——对焦评价函数,来量化图像的清晰度。
常用的评价函数,我按原理分成三类:
| 类别 | 代表算法 | 核心思想 | 我的评价 |
|---|---|---|---|
| 梯度类 | Tenengrad、Laplacian、Brenner | 清晰图像边缘锐利,梯度值大 | 最常用,响应快,适合大多数场景 |
| 频域类 | FFT高频能量、DCT系数 | 清晰图像高频分量多 | 精度高,但计算量大,实时性差 |
| 统计类 | 方差、熵、自相关 | 清晰图像像素分布更分散 | 鲁棒性好,但对纹理敏感度一般 |
我个人习惯首选梯度类。为什么?因为它在计算效率和灵敏度之间取得了很好的平衡。给你看一段我常用的 Tenengrad 实现:
// 简化版 Tenengrad 评价函数
float computeTenengrad(uint8_t* img, int w, int h) {
float sum = 0.0f;
// Sobel 水平梯度
int8_t sobelX[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1};
// Sobel 垂直梯度
int8_t sobelY[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1};
for (int y = 1; y < h-1; y++) {
for (int x = 1; x < w-1; x++) {
int gx = 0, gy = 0;
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
int idx = (y+ky)*w + (x+kx);
gx += img[idx] * sobelX[(ky+1)*3 + (kx+1)];
gy += img[idx] * sobelY[(ky+1)*3 + (kx+1)];
}
}
sum += sqrtf(gx*gx + gy*gy);
}
}
return sum / (w * h);
}
经验之谈:评价函数不是越复杂越好。我曾经在一个低功耗项目里试过频域法,精度确实高,但每帧计算耗时从 2ms 飙到了 35ms,直接导致对焦卡顿。后来换回梯度类,配合下采样,效果反而更好。
1.3 搜索策略:怎么找到最佳位置?
有了评价函数,我们就能给每个镜头位置打一个「清晰度分」。接下来要做的,就是找到分数最高的那个位置。这个过程,就是搜索策略。
常见的搜索策略,我画了张图帮你理解:
每种策略都有自己的脾气。我简单说说:
- 全扫描:从最近端扫到最远端,每步都算评价函数。简单粗暴,但慢。适合开机初始化。
- 爬山法:往评价函数增大的方向走,走到山顶就停。速度快,但容易撞上「假峰」——比如在有纹理的玻璃窗前。
- 斐波那契法:用斐波那契数列确定搜索步长,收敛快。我记得在某个安防项目里,用它把对焦时间从 1.2 秒压到了 0.6 秒。
- 粗扫+精扫:先大步粗扫找到峰值区间,再小步精扫定位。这是工程中最常用的方案,兼顾速度和精度。
避坑指南:我曾经在一个户外监控项目里直接用爬山法,结果风一吹树叶晃动,评价函数剧烈抖动,镜头跟着来回乱跑,画面一直在「呼吸」。后来加了时域滤波和死区判断,才稳住。记住:搜索策略必须配合场景做鲁棒性设计。
1.4 三个要素的关系
对焦原理、评价函数、搜索策略,这三者不是孤立的。我习惯这么理解:
- 对焦原理告诉你「为什么能对焦」——物理基础
- 评价函数告诉你「怎么算清晰」——数学工具
- 搜索策略告诉你「怎么找到最清晰的位置」——算法引擎
三者缺一不可。评价函数不准,搜索再快也是白搭;搜索策略太慢,评价函数再准也卡顿;不理解对焦原理,出了问题都不知道从哪排查。
一句话总结:自动对焦 = 用评价函数做「眼睛」,用搜索策略做「腿」,在对焦原理的「地图」上找到最佳位置。
好了,这一章的基础就讲到这里。后面我们会深入每种评价函数的实现细节,以及各种搜索策略的代码实战。嗯,路要一步一步走,地基打牢了,后面才盖得起高楼。