3. 混合自动对焦系统集成
任务目标
在现有单反/微单相机自动对焦框架中,将相位检测自动对焦(PDAF)与对比度检测自动对焦(CDAF)两种策略集成,形成混合自动对焦系统。系统优先使用PDAF快速逼近焦点,再切换至CDAF进行精细校准,最终输出合焦位置及状态。
核心实现
#include <stdint.h>
#include <stdbool.h>
// ---------- 数据结构 ----------
typedef struct {
int32_t lens_position; // 当前镜头位置(步进马达步数)
int32_t focus_peak; // PDAF检测到的峰值位置
int32_t contrast_best; // CDAF最佳对比度位置
uint8_t phase_conf; // PDAF置信度 0-100
uint16_t contrast_value; // 当前对比度评价值
bool is_focused;
} AFState;
// ---------- 硬件抽象接口(需由平台层实现) ----------
int32_t lens_get_position(void);
void lens_move_to(int32_t pos);
uint16_t sensor_get_contrast(int32_t pos); // 移动后读取对比度
int32_t pdaf_detect_offset(void); // 返回相位差换算的偏移量
uint8_t pdaf_get_confidence(void);
// ---------- 混合对焦核心算法 ----------
#define CDAF_STEP 8 // 精细搜索步长
#define CDAF_RANGE 40 // 精细搜索范围 ±40步
#define PHASE_CONF_THRESHOLD 60
static int32_t clamp(int32_t v, int32_t lo, int32_t hi) {
return (v < lo) ? lo : (v > hi) ? hi : v;
}
// 对比度精细搜索(爬山法)
static int32_t cdaf_fine_search(int32_t center) {
int32_t best_pos = center;
uint16_t best_val = sensor_get_contrast(center);
int32_t step = CDAF_STEP;
// 正向搜索
int32_t pos = center;
while (pos < center + CDAF_RANGE) {
pos += step;
uint16_t val = sensor_get_contrast(pos);
if (val > best_val) {
best_val = val;
best_pos = pos;
} else {
break; // 对比度下降,停止
}
}
// 负向搜索
pos = center;
while (pos > center - CDAF_RANGE) {
pos -= step;
uint16_t val = sensor_get_contrast(pos);
if (val > best_val) {
best_val = val;
best_pos = pos;
} else {
break;
}
}
return best_pos;
}
// 混合自动对焦主流程
bool hybrid_af_run(AFState *state) {
// 1. 相位检测粗定位
int32_t cur = lens_get_position();
int32_t offset = pdaf_detect_offset();
state->phase_conf = pdaf_get_confidence();
if (state->phase_conf >= PHASE_CONF_THRESHOLD) {
// PDAF可信,直接移动到检测位置
int32_t target = cur + offset;
target = clamp(target, 0, 10000); // 行程限位
lens_move_to(target);
state->focus_peak = target;
} else {
// PDAF不可信,以当前位置为中心做小范围搜索
state->focus_peak = cur;
}
// 2. 对比度精细校准
state->contrast_best = cdaf_fine_search(state->focus_peak);
lens_move_to(state->contrast_best);
// 3. 最终确认
state->lens_position = lens_get_position();
state->contrast_value = sensor_get_contrast(state->lens_position);
state->is_focused = (state->contrast_value > 200); // 阈值由标定决定
return state->is_focused;
}
// ---------- 调用示例 ----------
// AFState af = {0};
// bool ok = hybrid_af_run(&af);
// if (ok) { /* 合焦,af.lens_position 为最终位置 */ }
集成要点
- 依赖接口:
lens_get_position/lens_move_to由镜头驱动层提供;sensor_get_contrast由图像信号处理器(ISP)提供;pdaf_detect_offset与pdaf_get_confidence由相位检测传感器层提供。本代码聚焦混合调度逻辑,不展开各硬件驱动实现。 - 切换策略:PDAF置信度低于阈值(60)时跳过粗定位,直接以当前位置进入CDAF搜索,避免错误偏移导致失焦。
- 搜索边界:CDAF搜索范围限制在±40步内,防止在低纹理场景下漂移过远。
验证方法
- 在模拟环境中,构造一个已知最佳合焦位置(如
best_pos = 500),并让pdaf_detect_offset()返回一个接近真实偏移的值(如best_pos - current_pos + 5的误差),sensor_get_contrast()返回随位置变化的单峰函数(如高斯型)。 - 调用
hybrid_af_run()后,断言最终lens_position与best_pos的偏差小于CDAF_STEP(即8步以内)。 - 将
pdaf_get_confidence()设为低值(如20),验证系统仍能通过CDAF独立完成合焦,且不会因PDAF错误偏移而失焦。 - 通过条件:上述两种场景下,最终位置均落在最佳位置±8步范围内,且
is_focused返回true。
常见问题
- 对比度搜索陷入局部极值:在低纹理或重复纹理场景中,可增大
CDAF_RANGE或改用全局扫描策略,但会增加耗时。 - PDAF与CDAF结果冲突:当两者偏差超过
CDAF_RANGE时,应以CDAF结果为准,并降低PDAF置信度权重。 - 实时性要求:若系统需要视频追焦,可将
cdaf_fine_search改为每帧只搜索一步的迭代式逼近,避免阻塞。