ROS2 中对深度相机进行标定

2023-12-13 23:40:40

ROS2 中对深度相机进行标定

这篇文章主要介绍单目相机标定的方法,分享了在实际标定过程中的一些心得和注意事项,并介绍了如何使用标定结果。同时提到了奥比中光深度摄像机驱动在 ROS2 中使用的另一种方式。本文不涉及对于相机标定的原理等学术方面的探讨,如果你感兴趣可以自行搜索了解。

1. 为什么要标定

摄像机标定(Camera Calibration)是计算机视觉和机器人技术中的一个重要步骤,主要目的是为了获得摄像机与现实世界之间的关系。标定摄像机有以下几个原因:

消除畸变:摄像机镜头可能会引入径向畸变和切向畸变。这会导致图像中的直线变弯曲,且离中心越远的像素失真越明显。为减少这种影响,我们需要对摄像头参数进行校准。通过标定,我们可以获得畸变系数,进而纠正图像,使其更加真实地反映现实世界。
系统稳定性:提高摄像机的系统稳定性。随着时间的推移,摄像机内部的参数可能会发生变化,例如由于温度波动或机械应力。通过定期进行标定,可以确保摄像机始终保持最佳状态。
适应不同环境:在不同的环境条件下,例如在室内、室外或恶劣天气中,摄像机的性能可能会受到影响。标定可以帮助摄像机适应这些环境变化,从而保持高度的测量精度。

校准的方法是使用具有已知空间关系的物体(如标定板),通过分析所拍摄的图片像素,反向推导出摄像头的真实参数。

2. 标定的准备

2.1 驱动准备

在开始前的第一步,我们需要准备好摄像机的驱动,需要在 Rviz 中看到 RGB图,深度图,以及 IR 图。这里摄像机的驱动,除了前面讲到的 OpenNI SDK ROS2 外,也可以使用 Orbbec SDK for ROS2,其适用于Orbbec 3D相机的ROS2 wrapper ,可与ROS2环境无缝集成,并支持ROS2 Foxy、Galactic 和 Humble 发行版,并且更新比较活跃。

对于 Orbbec SDK for ROS2 的安装其实和前面讲的《ROS2 中 使用奥比中光 Orbbec Astra Pro 深度相机》中的过程差不多,直接按照官方教程走就可以了,对于实际启动中可能出现的深度摄像头或者其他摄像机的画面是左右反着的镜像,如此便影响到了彩色点云图的显示。

深度图异常

对于这种情况你可通过 ros2 service list 查找相关参数设置服务,进行调整,例如下方是调整深度摄像头镜像模式关闭的命令:

ros2 service call /camera/set_depth_mirror std_srvs/srv/SetBool '{data: false}'

提示:设备出厂已经完成了标定,并保存在相机中,使用原厂驱动获相关 SDK 可以直接获取到。在 ROS 中,可以通过 camera_info 话题获取到相关内容。

2.2 标定库

标定使用到的是 camera-calibration 这个库,其提供了标定所需的工具和相机内参计算的算法实现,支持使用棋盘格标定单目或双目摄像头。

在新版中该库增加了对鱼眼摄像头的支持,并使用了等距畸变模型。另外,该库还增加了双棋盘格标定的功能,使得用户可以使用多个不同尺寸的棋盘格来标定摄像头。

在标定之前,你需要安装好这个库:

sudo apt install ros-$ROS_DISTRO-camera-calibration

2.3 标定棋盘格

另外需要打印好标定板,也就是一个黑白相间的棋盘格,官方提供的是一个 8x6 的大小,可以点击这里下载。关于标定板有以下信息:

  • 标定板是黑白间隔的方块,什么规格都可以,只需要在后面执行时调整输入参数
  • 打印完成后建议用尺子测量并确认格子大小
  • 标定要尽量选择空旷,并和标定板没有相似的背景
  • 标定板最好贴在硬纸板或其他平整物体上,防止变形

3. 开始标定

3.1 相机准备

首先我们需要启动相机节点,发布图像。

ros2 launch orbbec_camera gemini.launch.xml

如果你使用远程访问的方式,则需要确认可以打开远程的 GUI 程序,或可直接使用 VNC 访问。因为后面的标定程序是有操作界面的,需要通过 UI 界面进行操作。

启动相机后,需要获取相机的话题列表,你可以使用下面的命令查阅:

ros2 topic list

话题列表

这些话题信息后面会用的到。

3.2 启动标定程序

cameracalibratorcamera_calibration 库中的一个节点,用于对单目或双目摄像头进行标定。该节点支持多种参数,以下是一些常用的参数:

  1. –size: 棋盘格尺寸,格式为NxM,其中N和M分别表示棋盘格的行数和列数。
  2. –square: 棋盘格方块的实际尺寸,单位为米。
  3. –no-service-check:禁用启动时检查 set_camera_info 服务。
  4. image: 单目摄像头的图像话题名称。
  5. camera: 单目摄像头的相机信息话题名称。

这里,我们只对单目摄像机进行标定,并只介绍了用到的参数,具体使用可以前往该库的介绍页面,根据实际需要选择相应的参数。

根据前面获取的相机话题信息,可以通过下面的命令启动标定程序:

ros2 run camera_calibration cameracalibrator --size 8x6 --square 0.025 --no-service-check image:=/camera/color/image_raw camera:=/camera/color

启动标定

3.3 标定和注意事项

启动标定后,我们就可以拿着标定板,在摄像头面前进行摆各种 Pose,给你的标定板尝试各种姿势了。上下,左右,前后,和各种倾斜角度都尝试尝试。

当我们将标定板放入画面,变化不同的位姿时,系统会自动识别并保存计算信息。当标定界面按钮的上方的四个指示进度条【X】、【Y】、【Size】、【Skew】随着数据的收集变为绿色时,原本灰色的【CALIBRATE】按键就变的可以点击了。

标定过程

最好是将绿的进度条尽可能填满,实际标定过程中我们会发现 【Size】 是最难满足的,距离太远了会不识别,差不多就可以收手了。

识别时需要注意,尽量让棋盘格平整,可以在下方粘贴一个板子,同时要注意灯光,画面过曝也会影响识别效果。

画面过曝

3.4 内参计算结果

当收集了足够数据后我们就可以点击【CALIBRATE】按钮进行相机的内参计算了,需要注意的是,数据收集的越多我们需要等待计算的时间就越长,计算的结果会在控制台打印。

内参计算结果

计算完成后,点击【SAVE】按钮,即可保存本次计算结果,最后点击【COMMIT】退出就完事了。

当我们保存后,相机的标定结果会打包保存在 /tmp/calibrationdata.tar.gz,可以将其移动到用户目录:

mv /tmp/calibrationdata.tar.gz ~

这个压缩包包含了程序自动识别的图片和相机标定的结果,有 txt 和 yaml 两种格式。

标定结果

可以看到,最终的标定结果和相机出厂时的标定结果还是有一些差不的。我们使用下面的命令读取 camera_info 话题即可获得。

ros2 topic echo /camera/color/camera_info
header:
  stamp:
    sec: 0
    nanosec: 0
  frame_id: ''
height: 480
width: 640
distortion_model: plumb_bob
d:
- 0.0541798397898674
- -0.07006204128265381
- 0.0
- 0.0
- 0.0
k:
- 454.25506591796875
- 0.0
- 331.9963684082031
- 0.0
- 454.25506591796875
- 244.86154174804688
- 0.0
- 0.0
- 1.0
r:
- 1.0
- 0.0
- 0.0
- 0.0
- 1.0
- 0.0
- 0.0
- 0.0
- 1.0
p:
- 454.25506591796875
- 0.0
- 331.9963684082031
- 0.0
- 0.0
- 454.25506591796875
- 244.86154174804688
- 0.0
- 0.0
- 0.0
- 1.0
- 0.0
binning_x: 0
binning_y: 0
roi:
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: false

3.5 标定结果使用

在前面几节提到的压缩包中的标定结果 ost.yaml,在使用的时候需要将其放到 ~/.ros/camera_info 文件夹中,然后将其重命名为对应的摄像头名称,例如 left.yamlright.yaml,这样 ROS 才能自动读取到。

标定结果一般有两种使用场景:

  1. 用于图像矫正,类库传参

一般我们会在 usb_cam 的启动文件中添加 camera_info_url 参数,指定标定结果的路径,例如:

camera = Node(
    package='usb_cam', executable='usb_cam_node_exe', output='screen',
    name='camera',
    parameters=[
        {"video_device":"/dev/video0"},
        {"framerate": 30.0},
        {"io_method": "mmap"},
        {"frame_id": "default_camera"},
        {"pixel_format": "yuyv"},
        {"image_width": 1920},
        {"image_height": 1080},
        {"camera_name": "default_camera"},
        {"camera_info_url": "file:///home/ros/ros/etc/ost.yaml"}
        ]
    )
  1. 程序中直接读取使用

比如我们使用 cv2 库读取图片时,可以直接传入标定结果,进行矫正或是在进行视觉定位时,可以直接传入标定结果,进行坐标转换。

4. 最后

本文详尽地介绍了单目相机标定的实践方法,以及如何有效利用标定结果。感谢你的阅读,期待在未来的实践中,能够得到更多的收获和启发。

文章来源:https://blog.csdn.net/marin1993/article/details/134983122
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。