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

168 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 27RM
RoboMaster 视觉工程(MindVision 相机 + OpenCV)。
## 构建
```bash
xmake # 产出三个程序(见下)
xmake run 27RM # 跑主程序
```
### VSCode + clangd
`compile_commands.json` 含本机绝对路径,**不入库**,克隆后自己生成一次:
```bash
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`):
```cpp
#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. 采集标定图
```bash
# 用 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. 计算内参
```bash
./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`(见上方「配置」一节),它已经处理了配置路径、去畸变缓存和位姿门限。
若要手动读:
```cpp
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. 距离验证(改完参数一定要做)
```bash
~/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 插图)要提交时,用强制添加:
```bash
git add -f docs/xxx.png
```
### ⚠️ 标定图请自己留备份
照片不入库 = 只有本机一份。重装系统前记得把 `calib_images/` 拷到网盘或 U 盘,
否则将来想重新标定(换镜头、调焦后)就没有原始数据了。
标定**结果**在 `configs/camera.yaml` 里,但结果无法替代原始照片。