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步内,防止在低纹理场景下漂移过远。

验证方法

  1. 在模拟环境中,构造一个已知最佳合焦位置(如best_pos = 500),并让pdaf_detect_offset()返回一个接近真实偏移的值(如best_pos - current_pos + 5的误差),sensor_get_contrast()返回随位置变化的单峰函数(如高斯型)。
  2. 调用hybrid_af_run()后,断言最终lens_position与best_pos的偏差小于CDAF_STEP(即8步以内)。
  3. 将pdaf_get_confidence()设为低值(如20),验证系统仍能通过CDAF独立完成合焦,且不会因PDAF错误偏移而失焦。
  4. 通过条件:上述两种场景下,最终位置均落在最佳位置±8步范围内,且is_focused返回true。

常见问题

  • 对比度搜索陷入局部极值:在低纹理或重复纹理场景中,可增大CDAF_RANGE或改用全局扫描策略,但会增加耗时。
  • PDAF与CDAF结果冲突:当两者偏差超过CDAF_RANGE时,应以CDAF结果为准,并降低PDAF置信度权重。
  • 实时性要求:若系统需要视频追焦,可将cdaf_fine_search改为每帧只搜索一步的迭代式逼近,避免阻塞。