> 技术文档 > 相机-IMU标定(以英特尔D435i为例)_d435i标定

相机-IMU标定(以英特尔D435i为例)_d435i标定


文章目录

  • 1、简介
  • 2、标定工具
    • i、 配置camera_calibration(ROS官方提供)
    • ii、配置Kalibr(ETH Zurich开源工具)
  • 3、软硬件信息
  • 4、相机标定
    • i、 使用camera_calibration
    • ii、使用Kalibr
  • 5、IMU标定(可选,联合标定可跳过)
    • i、 使用imu_utils标定
  • 6、相机-IMU联合标定
  • 小结

1、简介

  • camera_calibration:如果只使用单目或者双目相机作为主要传感器,推荐使用ros官网提供的标定包camera_calibration,可以标定相机内参畸变参数和双目相机的相对外参(旋转及平移关系),同时提供友好的图形界面,可以实时查看标定板的检测情况。

  • Kalibr:如果涉及多相机或者与IMU融合的多传感器标定,推荐使用ETH Zurich开源的标定工具Kalibr,主要用于标定相机和IMU的外参以及它们的内参,广泛用于多传感器融合以及视觉惯导里程计(VIO)中。适合更复杂的多传感器系统标定。

  • 两款标定工具均是基于ros进行标定,在使用前应根据实际情况准备好ros环境。camera_calibration有对应的ros1及ros2版本,目前Kalibr还只支持ros1。ros安装推荐使用小鱼一键安装。只需要复制指令,根据提示输入并回车就能搞定。

2、标定工具

i、 配置camera_calibration(ROS官方提供)

  1. 根据自己的ros版本修改指令:

    sudo apt-get install ros-<ros_distro>-camera-calibration # ros_distro换成对应的ros版本,melodic or humble and so on. 
  2. ros1版本和ros2版本的标定包安装指令相同,只需要确定好自己的ros版本即可,基本功能也是一致的,只是运行指令稍有区别。

ii、配置Kalibr(ETH Zurich开源工具)

  1. 安装依赖

    sudo apt-get install -y \\ git wget autoconf automake nano \\ libeigen3-dev libboost-all-dev libsuitesparse-dev \\ doxygen libopencv-dev \\ libpoco-dev libtbb-dev libblas-dev liblapack-dev libv4l-dev -----------------根据系统版本选择指令安装--------------------- # Ubuntu 16.04 sudo apt-get install -y python2.7-dev python-pip python-scipy \\ python-matplotlib ipython python-wxgtk3.0 python-tk python-igraph python-pyx# Ubuntu 18.04 sudo apt-get install -y python3-dev python-pip python-scipy \\ python-matplotlib ipython python-wxgtk4.0 python-tk python-igraph python-pyx# Ubuntu 20.04 sudo apt-get install -y python3-dev python3-pip python3-scipy \\ python3-matplotlib ipython3 python3-wxgtk4.0 python3-tk python3-igraph python3-pyx
  2. 创建工作空间并克隆项目

    mkdir -p /kalibr_ws/src # 创建工作空间cd /kalibr_wsexport ROS1_DISTRO=noetic # kinetic=16.04, melodic=18.04, noetic=20.04source /opt/ros/$ROS1_DISTRO/setup.bashcatkin initcatkin config --extend /opt/ros/$ROS1_DISTROcatkin config --merge-devel # Necessary for catkin_tools >= 0.4.catkin config --cmake-args -DCMAKE_BUILD_TYPE=Release# 克隆cd /kalibr_ws/srcgit clone https://github.com/ethz-asl/kalibr.git
  3. 编译

    cd /kalibr_ws/catkin build -DCMAKE_BUILD_TYPE=Release -j4 # 根据硬件性能选择线程数:-j4/8/16

    流程参考官方教程:Building Kalibr from Source

3、软硬件信息

软硬件 信息简介 ubuntu 在 18.0422.04 两个版本上做过测试 ros 在ros的两个版本上做过不同标定包的测试 相机驱动 主要测试过 usb_camrealsense-sdk 相机及IMU 主要测试过单双目工业相机模组及D435i

4、相机标定

i、 使用camera_calibration

  1. 在标定开始前,需要先准备对应的标定板。对于相机的标定,主要采用张氏标定法,是张正友教授于1998年提出的一种基于单平面棋盘格的摄像机标定方法。张正友标定法基于针孔相机模型,利用棋盘格标定板进行标定。

  2. 这里提供两个获取标定板的途径:网站在线生成 和 wiki.ros 提供。其中,推荐使用网站在线生成,可以根据需要定制生成多种格式的标定板,包括Checkerboard(棋盘格)AprilGrid。当然,如果有条件还是建议购买更专业的标定板来代替纸张打印,但这只是对有特别高精度要求的时候使用。
    在这里插入图片描述

  3. 执行标定任务前,需要确保相机接入电脑,并且启动对应的驱动程序,使得ros能够发现对应的话题数据,关于 usb_cam 以及 realsense 系列相机的驱动程序安装和使用,可以关注我的这两篇博客。

  4. 当我们正常启动相机之后,可以执行如下的指令,启动相机标定节点,相关参数可以参考官方文档。

    # 单目相机标定rosrun camera_calibration cameracalibrator.py --size 10x7 --square 0.015 image:=/my_camera/image camera:=/my_camera# 双目相机联合标定rosrun camera_calibration cameracalibrator.py --size 10x7 --square 0.015 right:=/my_stereo/right/image_raw left:=/my_stereo/left/image_raw left_camera:=/my_stereo/left right_camera:=/my_stereo/right-------------------------------------------------------------------## 参数解释--size:表示标定板中角点数量。 # 这里注意,角点指的是内角点,如上图中红色圈和绿色圈的区别。--square:表示标定板中一个黑方块的边长(米)。camera:表示相机名,根据相机驱动发布的话题指定,也可以没有。image:表示具体的图像话题,同样根据相机驱动发布的话题指定,必须指定。--------------------------------------------------------------------##(双目的参数原理类似,不过多介绍,可以适当增加参数)--no-service-check(无服务检查) 禁用启动时对 set_camera_info 服务的检查--approximate 0.1 配对图像时允许指定的斜率(以秒为单位)来自非同步双目相机
  5. 正确启动相机标定节点后,通过弹出的图形界面观察,让标定板在可视画面中按照上下,左右,前后,旋转进行多角度多尺度的变换。
    标定开始

  6. 当四个进度条都变绿后,可以单击calibrate进行标定,标定结束后会在终端显示标定结果,随之save变绿,单击可以将标定结果保存到本地。

  7. 双目相机的 基线 可以通过左右目标定的 投影矩阵 计算得到,在投影矩阵中fx, fy, cx, cy表示校正后使用的内参,Tx, Ty则编码了基线信息(对水平排列的双目系统,Ty ≈ 0),左目相机的Tx、Ty一般是 0。基线可以通过baseline = -Tx / fx计算得到。在下面的例子中,baseline = -(-196.04553) / 1635.195 ≈ 0.12米。

    # 投影矩阵的格式P = [fx, 0, cx, Tx; 0, fy, cy, Ty; 0, 0, 1, 0]# 左目投影矩阵projection_matrix: rows: 3 cols: 4 data: [1635.195 , 0. , 632.69406, 0. , 0. , 1635.195 , 358.7298 , 0. , 1. , 0. , 1. , 0. ]# 右目投影矩阵projection_matrix: rows: 3 cols: 4 data: [1635.195 , 0. , 632.69406, -196.04553, 0. , 1635.195 , 358.7298 , 0. , 0. , 0. , 1. , 0. ]

ii、使用Kalibr

  1. Kalibr可以只进行相机的标定,但是标定流程与camera_calibration不同且推荐使用AprilGrid标定板。当然也支持棋盘格标定板。
    aprilgrid标定板

  2. 创建与标定板相关的yaml配置文件,命名自定义,将下面的参数保存在yaml文件中:

    # 数值根据实际使用的标定板修改target_type: \'aprilgrid\' # 网格风格tagCols: 11  # 列数tagRows: 8 # 行数tagSize: 0.012 # 网格尺寸,注意单位是[m]tagSpacing: 0.0036 # 空白(space)与网格的比例codeOffset: 0 # 非必须,大部分情况默认是 0
  3. 保证相机正确被设备识别,启动相机驱动以D435i为例:

    roslaunch realsense2_camera rs_camera.launch # D435i默认分辨率是1280*720,30fps,可以通过参数指定具体的分辨率roslaunch realsense2_camera rs_camera.launch color_width:=640 color_height:=480 color_fps:=30# 如果不指定帧率,无法成功修改分辨率,所以分辨率需要一起指定# 理论上在这里同样可以修改帧率,但我遇到了报错,提示设备不支持,所以分辨率这里需要指定默认的30fps
  4. 使用Kalibr对相机标定,官方推荐的速率是每秒4帧左右(FPS=4),可以尝试在启动相机节点的时候,通过指定帧率参数修改帧率,如果报错,可以通过ros自带的topic_tools工具进行转换,打开一个新终端:

    rosrun topic_tools throttle messages /camera/color/image_raw 4.0 /cam0/color/image_raw# /camera/color/image_raw 表示原始的图像话题# 4.0 表示新话题帧率# /cam0/color/image_raw 表示映射的新话题名

    话题映射

  5. Kalibr主要是通过录制bag包进行标定,所以完成话题映射后,订阅新相机节点(多相机标定类似,增加话题名即可):

    rosbag record /cam0/color/image_raw # 录制图像话题数据 4fps
  6. 在录包过程中,需要将标定板垂直固定好,保证良好均匀的光照,让相机正对着标定板,推荐按照相机的三个轴(或者说俯仰偏航旋转),每个轴分别做 三次平移三次旋转(绕轴两侧偏转) 操作的方式进行录制,Kalibr官方中也提供了YouTube视频,可以通过科学上网查看操作过程。B站中也有相应转载视频。

  7. 录制完成后,将标定板的yaml文件以及bag包放在同一个文件夹中,并在当前目录下打开终端执行指令,(注意指定话题名)

    rosrun kalibr kalibr_calibrate_cameras --target april_6x6.yaml --bag 2024-11-11-11-11-11.bag --bag-from-to 10 100 --models pinhole-radtan --topics /cam0/color/image_raw# april_6x6.yaml 表示标定板的配置文件,命名随意# 2024-11-11-11-11-11.bag 表示录制的标定包# 10 100 表示取标定包中10-100这个区间的内容,在开始和结束的时候,相机有可能会出现剧烈的晃动,不利于标定,当然也可以不指定这个参数# pinhole-radtan 表示相机的模型以及畸变的模型# 多相机原理相同,只需要把模型以及话题依次指定即可rosrun kalibr kalibr_calibrate_cameras --target april_6x6.yaml --bag 2024-11-11-11-11-11.bag --bag-from-to 10 100 --models pinhole-radtan pinhole-radtan --topics /cam0/color/image_raw /cam1/color/image_raw
  8. 标定结束后,会弹出图形界面,关闭后会生成pdf,txt以及yaml三个标定结果文件,可以通过yaml文件查看具体的标定结果。
    弹窗结果文件参数信息

5、IMU标定(可选,联合标定可跳过)

i、 使用imu_utils标定

  1. imu_utils是一个轻量级的 IMU 标定工具,主要用于校准 IMU 的偏差和尺度因子,配置和使用相对简单,适合快速标定需求。但不支持多传感器融合标定,只能单独标定 IMU,由于功能较为简单,标定结果的精度可能不如更专业的工具,通常与ros一起使用。主要在ubuntu18.04进行测试。

  2. imu_utils依赖于ceres,需要全局安装,首先安装依赖:

    sudo apt-get install liblapack-dev libsuitesparse-dev libcxsparse3 libgflags-dev libgoogle-glog-dev libgtest-dev libdw-dev
  3. 访问ceres-solver地址,选择tag为1.14.0下载tar或tar.gz压缩包,也可以使用指令下载:

    wget https://github.com/ceres-solver/ceres-solver/archive/refs/tags/1.14.0.tar.gz
  4. 解压并编译:

    # 可以选择在/opt目录下安装tar -zxvf 1.14.0.tar.gz cd ceres-solver-1.14.0/mkdir buildcd build/------------------------------------cmake ..make -j4sudo make install
  5. imu_utils同样依赖code_utils,需要先编译:

    mkdir -p imu_calib_ws/src # 创建工作空间cd ./imu_calib_ws/srcgit clone https://github.com/gaowenliang/code_utils.gitcd code_utils/srcvim sumpixel_test.cpp # 将 #include \"backward.hpp\" 改为 #include \"code_utils/backward.hpp\" 避免报错cd imu_calib_wscatkin_make
  6. 下载并编译imu_utils:这里使用的是mintar大佬修改后的文件,gaowenliang的imu_utils貌似有单位的问题。

    cd ./imu_calib_ws/srcgit clone https://github.com/mintar/imu_utils.gitcd imu_calib_wscatkin_make
  7. 这里以D435i为例,并在18.04上测试,也没有涉及到imu驱动以及相关串口的配置,后续如果有涉及会更新。一些其他问题可以参考博客。

  8. imu_utils使用bag包对imu进行标定,在静止状态下启动相机并录制imu数据:

    # 启动驱动,修改频率(可选)roslaunch realsense2_camera rs_camera.launch gyro_fps:=200 accel_fps:=200# 录制imu数据,根据实际imu的话题名修改rosbag record /camera/imu --duration=2.5h # 这里一定要录制2个小时以上,不然会有问题,录制过程处于静止状态。
  9. 配置标定所需的信息:

    cd imu_utils/data && mkdir d435i # 用于存放标定后的imu数据# 创建launch文件cd imu_utils/launch && mkdir d435i.launch vim d435i.launch # 打开创建的文件,粘贴以下内容,然后根据实际情况修改launch中的信息<launch> <node pkg=\"imu_utils\" type=\"imu_an\" name=\"imu_an\" output=\"screen\"> <param name=\"imu_topic\" type=\"string\" value= \"/camera/imu\"/> // 这里的value是imu的topic <param name=\"imu_name\" type=\"string\" value= \"d435i\"/> // 这里的value是imu名字自定义 <param name=\"data_save_path\" type=\"string\" value= \"$(find imu_utils)/data/d435i/\"/> // 这里的value是标定后输出的目录 <param name=\"max_time_min\" type=\"int\" value= \"120\"/>  // 这个value值一定要小于你录制的imu数据包 <param name=\"max_cluster\" type=\"int\" value= \"100\"/> </node></launch># max_time_min 表示使用bag数据的最大时长,单位是分钟,默认是120分钟,程序会在最大时间截断读取数据# max_time_min 设置的值如果大于实际包的长度,程序不会有效执行
  10. 标定imu:

    # 运行imu_utils标定程序roslaunch imu_utils d435i.launch # 播放录制好的数据包 以200倍速度播放rosbag play -r 200 imu.bag# 当bag包加速回放完毕后,执行launch的窗口仍然会显示wait for imu data.,等待一段时间计算,计算完毕后会显示计算结果
  11. 标定结束后,标定结果会保存在我们创建的/data/d435i目录中,标定信息参考如下:

    # 产生结果文件的路径在launch文件中设定 $(find imu_utils)/data/d435i/%YAML:1.0---# d435i_imu_param.yamltype: IMUname: d435iGyr: unit: \" rad/s\" avg-axis: gyr_n: 2.1493476850332214e-03 # 陀螺仪误差模型的高斯白噪声 gyr_w: 3.3882665860180001e-05 # 陀螺仪bias x-axis: gyr_n: 1.8179993598631510e-03 gyr_w: 3.0456325859567277e-05 y-axis: gyr_n: 2.7452213936406638e-03 gyr_w: 5.2691779068029382e-05 z-axis: gyr_n: 1.8848223015958496e-03 gyr_w: 1.8499892652943347e-05Acc: unit: \" m/s^2\" avg-axis: acc_n: 1.2846186833932205e-02 # 加速度计误差模型的高斯白噪声 acc_w: 4.8772314394013864e-04 # 加速度计bias x-axis: acc_n: 1.3392081595681551e-02 acc_w: 5.9555783348821305e-04 y-axis: acc_n: 1.1844637614810858e-02 acc_w: 4.3337690258674066e-04 z-axis: acc_n: 1.3301841291304206e-02 acc_w: 4.3423469574546220e-04

6、相机-IMU联合标定

  1. 联合标定流程与单独进行相机标定的流程类似,同样需要录制rosbag包,不过在需要在录制过程中增加对IMU话题数据的订阅,同时需要准备关于IMU初始参数的yaml文件

  2. 这里以D435i为例,默认情况下D435i是关闭陀螺仪、加速度计等IMU信息的,可以通过修改rs_camera.launch文件(ros1)中的参数开启,具体的开启流程,可以参考上面提到的关于Realsense安装博客中最后介绍的内容,这里就不过多介绍了,接下来默认能够正常开启IMU并发布话题数据。

  3. 在进行联合标定的过程中,Kalibr会自动估计IMU的 噪声密度(noise density)随机游走(random walk) 等参数,这也意味着在标定开始的时候并不需要一个完全准确的IMU噪声模型,Kalibr会在标定过程中不断调整这些参数,当然如果提供一个稍微精准的初始值也能够加快标定算法的收敛,具有一定的优势,Kalibr也提供了sample,可以参考里面的参数,这里不过多的介绍。

  4. 联合标定,官方推荐使用 相机 20 fps,IMU 200 fps 这样的帧率设置。D435i初始的加速度计和陀螺仪频率并不全是200HZ,可以在启动相机驱动的时候,修改accel和gyro的发布频率,或者通过topic_tools修改相机和imu的发布频率(这里直接映射imu发布频率,因为之后使用的也是整合accel和gyro的imu话题数据)。如何映射参考相机标定流程。

  5. 录制bag包,录制过程与相机标定类似,需要订阅相机及IMU话题数据,并将相机与IMU设备正对标定板,按照同样的思路进行三次旋转和三次平移,完成数据录制。因为涉及到imu,所以必须要移动设备,不能移动标定板而设备不动。

  6. 联合标定需要准备好,(1)标定板yaml文件(2)相机yaml文件(刚才标定的)、(3)imu的yaml文件(可标可不标)、以及 (4)bag包,为了方便也可将配置信息及数据包放在同一个文件夹中。

  7. 确认相机及imu的yaml文件中所对应的话题名是否和bag包中的一致,确认无误后执行指令:

    rosrun kalibr kalibr_calibrate_imu_camera --target april_6x6.yaml --cam 2024-11-03-14-57-10-camchain.yaml --imu imu_adis16448.yaml --bag 2024-11-03-17-44-26.bag --bag-from-to 5 135 # 2024-11-03-14-57-10-camchain.yaml 表示标定后的参数文件# imu_adis16448.yaml 使用的是官方提供的样本文件,可以自己标定后替换# --show-extraction 可以增加参数可视化标定
  8. 标定结束后,关闭图像化界面,会在同目录下生成四个有关标定参数的文件。
    标定结果

小结

这里也分享几个不错的博客内容大家可以参考:使用Kalibr标定相机和IMU(ZED+px4)外参 ,imu内参标定 ,imu噪声的建模理解 。以上是关于相机及IMU设备的标定流程分享,目前遇到的问题不是很多,如果有其他情况欢迎在评论区分享你的解决办法!!