5752e76576
- Update laser direction and origin from recalibration - Set DETECT_INTERVAL=1 for per-frame detection in both calibrate scripts
相机标定与激光点解算
文件说明
| 文件 | 用途 |
|---|---|
calibrate.py |
相机内参标定,交互式拍照,输出 calibration_result.json |
laser_calibrate.py |
激光器-相机联合标定,拟合相机坐标系下的激光直线,输出 laser_result.json |
pnp_solve.py |
矩形检测 + PnP 位姿解算,实时显示相机位姿 |
laser_pnp.py |
矩形检测 + PnP 位姿解算 + 激光点世界坐标计算 |
棋盘格规格
- 方格边长:15 mm
- 内角点数:11 列 x 8 行(12x9 个方格)
工作流程
第一步:相机内参标定
python calibrate.py
- 输入是否为无畸变镜头(y/n),然后输入拍摄数量(建议 15~20 张)
- 将棋盘格以不同角度/位置放在相机视野中
- 画面显示绿色 CHESSBOARD DETECTED 后,输入
y并回车拍照 - 图像自动保存到
calibration_images/目录 - 拍完后自动标定,输出内参矩阵 K 和畸变系数
- 结果保存为
calibration_result.json,同时终端打印完整 JSON
第二步(可选):激光器-相机联合标定
需要开启激光,激光点投射在标定板上
python laser_calibrate.py
- 自动加载
calibration_result.json - 输入拍摄数量(建议 >= 10 张),标定板以不同姿态摆放
- 画面显示绿色棋盘格角点 + 红色激光点圆圈后,输入
y拍照 - 每张图像:PnP 解算标定板位姿 -> 提取激光点像素 -> 反投影求交 -> 得到相机坐标系 3D 点
- 图像自动保存到
laser_calib_images/目录 - 采集完成后 PCA 拟合激光直线,输出:
d_cam:激光方向向量(相机坐标系)O_cam:基准起点(直线与相机 Z=0 平面的交点)
- 结果保存为
laser_result.json,同时终端打印完整 JSON
第三步:在线运行
仅 PnP 位姿解算:
python pnp_solve.py
将 calibrate.py 输出的 JSON 粘贴到文件顶部的 CALIB_JSON 变量中,修改 RECT_L/RECT_W 为实际矩形尺寸。
PnP 位姿 + 激光点世界坐标:
python laser_pnp.py
将 calibrate.py 输出的 JSON 粘贴到 CALIB_JSON,将 laser_calibrate.py 输出的 JSON 粘贴到 LASER_JSON,修改 RECT_L/RECT_W。
画面实时显示:
- 矩形四个角点标注(TL/BL/BR/TR)
- 右手坐标系坐标轴(X 红 / Y 绿 / Z 蓝)
- 相机平移向量 T 和旋转欧拉角 R
- 激光点世界坐标 (x, y)(仅在
laser_pnp.py中)
内参矩阵缩放
内参矩阵 K 的单位是像素,与图像分辨率绑定。畸变系数(dist)是无量纲的,不随分辨率变化。
等比例缩放因子 $s = W_{\text{new}} / W_{\text{orig}}$:
K_scaled = K.copy()
K_scaled[0, 0] *= s # fx
K_scaled[1, 1] *= s # fy
K_scaled[0, 2] *= s # cx
K_scaled[1, 2] *= s # cy
对应的 pnp_solve.py 和 laser_pnp.py 通过 IMAGE_SCALE 常量自动处理缩放。
坐标系约定
世界坐标系(矩形平面,Z=0):
TL=(0,0) ──── TR=(l,0)
│ │
BL=(0,w) ──── BR=(l,w)
- X 轴沿矩形长边,向右
- Y 轴沿矩形宽边,向下
- Z 轴由右手定则确定:X x Y = Z,指向观察者
相机坐标系:OpenCV 标准右手系,X 右、Y 下、Z 前(指向场景)。