从棋盘格到精准感知:ROS camera_calibration实战单目与双目相机标定
2026/5/15 22:27:11 网站建设 项目流程

1. 为什么相机标定是机器人视觉的"体检报告"?

想象一下你新配了一副眼镜,但镜片度数不准——看东西要么变形要么模糊。相机标定就是给机器人的"眼睛"做验光,确保它看到的图像能真实反映物理世界。我在做视觉SLAM项目时,曾因跳过标定步骤导致建图出现10cm的累积误差,不得不返工重来。

相机镜头天生存在两种误差:径向畸变(图像边缘弯曲)和切向畸变(镜头安装倾斜)。就像人眼的散光,不矫正会导致:

  • 测量距离时出现系统性偏差
  • 三维重建的点云扭曲
  • 视觉定位的漂移累积

ROS的camera_calibration功能包就像一套自动化验光设备,通过分析棋盘格图案,计算出相机的:

  • 内参矩阵(焦距、光心位置)
  • 畸变系数(k1,k2,p1,p2,k3)
  • 外参矩阵(双目相机间的相对位置)

实测表明,标定后的Realsense D435i相机,在2米距离上的测距误差从3.2%降至0.8%。下面我会手把手带你完成这个"机器人验光"流程。

2. 标定前的准备工作

2.1 制作高精度棋盘格

标定板相当于验光时的视力表,建议使用:

  • 哑光材质(避免反光干扰)
  • 边长≥0.1m的大棋盘(我常用8x6格)
  • 打印时用游标卡尺验证实际尺寸

生成棋盘格的Python代码:

import cv2 pattern_size = (8, 6) # 角点数量 square_size = 0.1 # 单位:米 pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32) pattern_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2) pattern_points *= square_size img = cv2.drawChessboardCorners(np.ones((800,600)), pattern_size, pattern_points[:,:2], True) cv2.imwrite("chessboard.png", img*255)

2.2 搭建标定环境

踩坑经验:

  • 光照要均匀(避免强侧光)
  • 相机固定在三脚架上
  • 关闭自动对焦和白平衡
  • 标定前先做10分钟预热

检查相机话题是否正常:

rostopic list | grep image_raw

3. 单目相机标定实战

3.1 启动标定节点

运行命令(以Realsense为例):

rosrun camera_calibration cameracalibrator.py \ --size 8x6 \ --square 0.1 \ image:=/camera/color/image_raw \ camera:=/camera \ --no-service-check

关键参数说明:

参数作用典型值
--size棋盘格角点数8x6
--square单个格子物理尺寸(m)0.1
image图像话题名/camera/color/image_raw

3.2 数据采集技巧

标定界面会显示四个进度条:

  • X/Y移动:让棋盘格覆盖视野四角
  • Size变化:从最近到最远距离(建议0.3m~2m)
  • Skew旋转:倾斜±60°以内

我的采集秘诀:

  1. 先做"米字形"移动覆盖视野
  2. 然后像画螺旋线一样逐渐远离
  3. 最后添加各种倾斜角度
  4. 采集100+张有效样本(进度条全绿)

3.3 保存与验证结果

点击CALIBRATE后:

  • 终端会输出重投影误差(建议<0.2像素)
  • 保存的yaml文件包含:
image_width: 640 image_height: 480 camera_matrix: !!opencv-matrix rows: 3 cols: 3 data: [615.5, 0, 327.2, 0, 615.1, 241.3, 0, 0, 1] distortion_coefficients: !!opencv-matrix rows: 1 cols: 5 data: [0.12, -0.25, 0.001, -0.002, 0.3]

验证标定效果:

import cv2 undistorted = cv2.undistort(raw_image, camera_matrix, dist_coeffs)

4. 双目相机标定进阶

4.1 同步采集设置

双目标定需要额外获取:

  • 左右相机间的旋转矩阵R
  • 平移向量T
  • 立体矫正参数

启动命令示例:

rosrun camera_calibration cameracalibrator.py \ --approximate 0.1 \ --size 8x6 \ --square 0.1 \ left:=/camera/infra1/image_rect_raw \ right:=/camera/infra2/image_rect_raw \ right_camera:=/camera/right \ left_camera:=/camera/left \ --no-service-check

4.2 关键注意事项

  1. 必须同步触发左右相机(硬件同步最佳)
  2. 标定板要同时出现在双视野中
  3. 检查视差图是否连续:
stereo = cv2.StereoBM_create() disparity = stereo.compute(left_img, right_img)

4.3 参数解析

典型输出包含:

rotation: [0.999, 0.005, -0.012, -0.005, 0.999, -0.001, 0.012, 0.001, 0.999] translation: [-0.1203, 0.0005, 0.0011] essential: !!opencv-matrix fundamental: !!opencv-matrix

5. 标定结果的实际应用

5.1 提升视觉SLAM精度

以RTAB-MAP为例,修改配置:

<Camera type="0"> <Matrix type="opencv-matrix"> <rows>3</rows> <cols>3</cols> <data>615.5 0 327.2 0 615.1 241.3 0 0 1</data> </Matrix> <Distortion type="opencv-matrix"> <rows>1</rows> <cols>5</cols> <data>0.12 -0.25 0.001 -0.002 0.3</data> </Distortion> </Camera>

5.2 优化三维测量

标定后测距代码示例:

def calculate_depth(disparity, Q): points = cv2.reprojectImageTo3D(disparity, Q) return np.linalg.norm(points[y,x])

实测对比:

距离(m)标定前误差(cm)标定后误差(cm)
1.03.20.8
2.06.71.5

记得每3个月或剧烈震动后重新标定——就像眼镜度数会变化,相机的"视力"也需要定期检查。当看到机器人稳定输出厘米级精度的定位数据时,你会觉得这些准备工作绝对值得。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询