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()即可获得镜头驱动指令。实际系统中,步数到镜头物理位移的换算系数需根据镜头马达特性标定。