1. 相位检测自动对焦模块搭建

相位检测自动对焦模块搭建 学习卡片

任务目标

构建一个基于相位检测的自动对焦模块,模拟相机对焦系统通过相位差计算镜头移动方向与步数,实现快速对焦。模块输入为左右像素点的相位偏移量,输出为镜头控制信号(方向与步长)。

核心实现

// phase_af_module.h
#ifndef PHASE_AF_MODULE_H
#define PHASE_AF_MODULE_H

#include <stdint.h>

#define AF_SENSOR_PAIRS 8      // 相位检测像素对数量
#define AF_MAX_STEP      200   // 最大对焦步数
#define AF_DEAD_ZONE     2     // 合焦判定死区(像素)

typedef struct {
    int16_t phase_offset[AF_SENSOR_PAIRS]; // 各像素对相位差
    uint8_t  valid_count;                   // 有效像素对数量
} PhaseData;

typedef struct {
    int8_t  direction;  // +1 前移,-1 后移,0 合焦
    uint16_t steps;     // 移动步数
    uint8_t  in_focus;  // 1=已合焦
} LensCommand;

// 计算平均相位差(剔除最大/最小后取均值)
int16_t phase_af_calc_mean(const PhaseData *data);

// 生成镜头控制指令
LensCommand phase_af_generate_command(const PhaseData *data);

#endif // PHASE_AF_MODULE_H
// phase_af_module.c
#include "phase_af_module.h"

int16_t phase_af_calc_mean(const PhaseData *data) {
    if (data->valid_count == 0) return 0;
    
    int32_t sum = 0;
    int16_t min_val = data->phase_offset[0];
    int16_t max_val = data->phase_offset[0];
    
    for (uint8_t i = 0; i < data->valid_count; i++) {
        int16_t v = data->phase_offset[i];
        sum += v;
        if (v < min_val) min_val = v;
        if (v > max_val) max_val = v;
    }
    
    if (data->valid_count > 2) {
        sum -= min_val + max_val;
        return (int16_t)(sum / (data->valid_count - 2));
    }
    return (int16_t)(sum / data->valid_count);
}

LensCommand phase_af_generate_command(const PhaseData *data) {
    LensCommand cmd = {0, 0, 0};
    if (data->valid_count == 0) return cmd;
    
    int16_t mean_offset = phase_af_calc_mean(data);
    
    // 死区内判定为合焦
    if (mean_offset > -AF_DEAD_ZONE && mean_offset < AF_DEAD_ZONE) {
        cmd.in_focus = 1;
        return cmd;
    }
    
    // 相位差正负决定方向
    cmd.direction = (mean_offset > 0) ? 1 : -1;
    
    // 步数与相位差值成比例(带限幅)
    int32_t raw_steps = (int32_t)mean_offset * 10;
    if (raw_steps < 0) raw_steps = -raw_steps;
    cmd.steps = (raw_steps > AF_MAX_STEP) ? AF_MAX_STEP : (uint16_t)raw_steps;
    
    return cmd;
}
// main.c 最小验证入口
#include <stdio.h>
#include "phase_af_module.h"

int main(void) {
    // 模拟失焦状态:相位差均值约 +25 像素
    PhaseData test_data = {
        .phase_offset = {22, 26, 24, 28, 23, 27, 25, 21},
        .valid_count = 8
    };
    
    LensCommand cmd = phase_af_generate_command(&test_data);
    printf("方向: %+d, 步数: %u, 合焦: %s\n",
           cmd.direction, cmd.steps, cmd.in_focus ? "是" : "否");
    
    // 模拟合焦状态
    PhaseData focus_data = {
        .phase_offset = {1, -1, 0, 2, -2, 1, 0, -1},
        .valid_count = 8
    };
    cmd = phase_af_generate_command(&focus_data);
    printf("方向: %+d, 步数: %u, 合焦: %s\n",
           cmd.direction, cmd.steps, cmd.in_focus ? "是" : "否");
    
    return 0;
}

编译与运行

gcc -Wall -o phase_af_test main.c phase_af_module.c
./phase_af_test

验证方法

程序输出应满足以下条件即判定通过:

  • 第一组数据(均值约+25)输出 方向: +1, 步数: 200, 合焦: 否(步数被限幅到最大值)
  • 第二组数据(均值约0)输出 方向: 0, 步数: 0, 合焦: 是

该模块可直接嵌入相机对焦控制链路:将相位检测传感器输出的像素偏移量填入PhaseData结构体,调用phase_af_generate_command()即可获得镜头驱动指令。实际系统中,步数到镜头物理位移的换算系数需根据镜头马达特性标定。

左像素 右像素 镜头 相位差Δ |Δ| ≤ 2px → 合焦