Files
VSAG_AUTO_AIM_PRACTICE_27RM/README.md
T
mzxwww c50be9a48d Document IDE setup and repository commit rules
- note that compile_commands.json must be regenerated locally
- add a commit-rule table and a warning to back up calibration photos
- fix the intrinsics example to read configs/camera.yaml
2026-09-15 23:33:23 +08:00

5.9 KiB
Raw Blame History

27RM

RoboMaster 视觉工程(MindVision 相机 + OpenCV)。

构建

xmake                 # 产出三个程序(见下)
xmake run 27RM        # 跑主程序

VSCode + clangd

compile_commands.json 含本机绝对路径,不入库,克隆后自己生成一次:

xmake project -k compile_commands .vscode

(.vscode/settings.json 里已配置 clangd.arguments: ["--compile-commands-dir=.vscode"])

程序清单

程序 用途
27RM 自瞄主程序
capture_calib 相机标定图采集工具
calibrate 标定计算工具(照片 → 内参/畸变 → configs/camera.yaml)

配置

configs/
└── camera.yaml     # 相机内参 + 畸变 + 标定元信息(由 calibrate 生成,需入库)

代码里这样用(inc/camera_calib.hpp):

#include "camera_calib.hpp"

CameraCalib calib;
if (!calib.load("configs/camera.yaml")) return -1;      // 启动时加载一次

cv::Mat undist;
calib.undistort(frame, undist);                          // 每帧去畸变

// 装甲板四角点(左下、左上、右上、右下)→ 位姿
std::array<cv::Point2f, 4> corners{lb, lt, rt, rb};
if (auto pose = calib.solvePose(corners, ArmorSize::small())) {
    double yaw, pitch;
    CameraCalib::poseToYawPitch(pose->tvec, yaw, pitch);
    // pose->distance_mm / pose->reproj_error_px 可用于过滤坏帧
}

程序必须在工程根目录运行(configs/ 是相对路径),或自行传绝对路径。

相机标定流程

本工程标定板规格:10 × 7 内角点、方格 20.0 mm(卡尺实测值,不是打印标称值) 相机:MV-SUA131GC(1/3" CMOS,3.75μm 像元)+ MV-LD-M12-2.8MM-C 镜头,输出 1280×1024 ⚠️ M12 镜头调焦会改变有效焦距,标定和使用时必须保持对焦环位置一致

1. 采集标定图

# 用 MindVision 相机(机器人上那台)
./build/linux/x86_64/debug/capture_calib --square 20.0

# 或改用 USB 摄像头
./build/linux/x86_64/debug/capture_calib --usb 0 --square 20.0

按键:

键 功能
空格 保存当前帧(默认要求检测到棋盘格)
f 强制保存(未检测到也存)
d 删除上一张
c 开关实时角点检测显示
g 灰度预览(排查过曝/反光)
q / ESC 退出

拍摄要求:

  • 标定板出现在画面中心、四角、边缘(2.8mm 广角镜头边缘畸变最大)
  • 姿态多样:正对、倾斜、旋转、俯仰
  • 清晰不糊、光照均匀、无反光、板子贴平硬板
  • 20~30 张,保存于 calib_images/(已加入 .gitignore,不会入库)

2. 计算内参

./build/linux/x86_64/debug/calibrate --dir calib_images --square 20.0   # 只算顶层
./build/linux/x86_64/debug/calibrate --dir calib_all --square 20.0      # 全部 31 张(推荐)
./build/linux/x86_64/debug/calibrate --square 20.0 --show               # 逐张查看角点与重投影

工具会输出重投影误差 RMS、内参 K、畸变系数、每张图误差排行,并写入 camera_calib.yml。

重投影误差 评价
< 0.3 px 很好
0.3 ~ 0.5 px 可接受
> 0.5 px 建议重拍

当前标定结果(calib_all/ 31 张,20mm 方格): fx=657.47, fy=658.25, cx=625.64, cy=509.00,RMS 0.483 px 距离验证:卷尺 700mm vs 程序 687~697mm,误差 < 2% ✓

⚠️ 标定图必须同时具备「三种多样性」

维度 作用 不满足的后果
画面位置(九宫格覆盖) 约束畸变系数 边缘畸变解不出来,RMS 偏高
倾角(正对/上下倾/左右倾/大角度) 约束焦距与主点 参数耦合,精度下降
距离(近/中/远,板子占画面 40%/20%/8%) 约束尺度 ⭐ fx 无法确定:所有图同距离时,"焦距×距离"可整体缩放而图像不变,优化器会落到错误值,且 RMS 依然很低(最阴险的坑)

实测教训:一套 19 张、覆盖 9/9 但距离相近的图,标出的 fx=883(实际 659,偏差 34%),距离误差直接 +32%; 与旧的 12 张(距离 24~65cm)合并后 fx 回到 657,误差 <2%。距离多样性是 fx 的锚点,不可省。

3. 使用内参

推荐直接用封装好的 CameraCalib(见上方「配置」一节),它已经处理了配置路径、去畸变缓存和位姿门限。 若要手动读:

cv::Mat K, D;
cv::FileStorage fs("configs/camera.yaml", cv::FileStorage::READ);
fs["camera_matrix"] >> K;
fs["dist_coeffs"] >> D;

之后用 cv::undistort / cv::solvePnP 做去畸变与位姿解算。

4. 距离验证(改完参数一定要做)

~/yolo-env/bin/python ~/rm_vision/verify_distance.py 图片.jpg --square 20.0 --distance 647

用卷尺量出真实距离,与程序算出的距离对比:误差 < 2% 说明标定可用。

提交规则(.gitignore)

内容 是否入库 原因
src/ inc/ xmake.lua README.md ✅ 入库 源码与构建脚本
configs/camera.yaml ✅ 必须入库 相机内参,全队共用
calib_images/ calib_all/ ❌ 不入库 标定照片,20MB+ 且随时重拍
*.jpg *.png *.bmp *.avi *.mp4 ❌ 不入库 图片视频一律不入库
build/ .xmake/ Camera/ *.log ❌ 不入库 编译产物、SDK 运行时日志
.vscode/compile_commands.json ❌ 不入库 xmake 生成,含本机绝对路径

确有少量配图(例如 README 插图)要提交时,用强制添加:

git add -f docs/xxx.png

⚠️ 标定图请自己留备份

照片不入库 = 只有本机一份。重装系统前记得把 calib_images/ 拷到网盘或 U 盘, 否则将来想重新标定(换镜头、调焦后)就没有原始数据了。 标定结果在 configs/camera.yaml 里,但结果无法替代原始照片。