1 简介
近期在基于在基于GVINS进行开发,采集了GNSS、IMU、相机的数据,需要对相机和IMU的数据进行标定,包括相机内参标定以及相机和IMU之间的外参标定,这里使用了经典的Kalibr标定软件进行操作,在此记录一下使用过程。
2 Kalibr安装过程
Kalibr软件是一个经典的标定软件,可以解决以下标定问题:
- 多相机标定;
- 相机-IMU标定;
- 多IMU标定;
- 卷帘快门相机标定。
具体可以参考Kalibr 页面介绍。
由于Kalibr软件开发得比较早,安装环境是基于较旧的Ubuntu环境,所以本人在Ubuntu22.04上基于源码编译安装出现了很多问题,最终还是采用了基于Docker的安装方式,这里就不对源码编译安装的惨痛过程进行赘述了,直接开始介绍Docker安装过程。
Kalibr的安装过程可以参考install wiki页面,本人所用的安装命令为:
1 | git clone https://github.com/ethz-asl/kalibr.git |
尽管本人电脑的操作系统为Ubuntu22.04,但是安装的ROS版本还是ROS-noetic,所以这里还是选用的Dockerfile_ros1_20_04。执行上述命令后不出意外报错了:
1 | [+] Building 30.1s (2/2) FINISHED docker:default |
根据以上报错原因,是Docker从官方仓库获取镜像osrf/ros:noetic-desktop-full时超时了,这我就不理解了,本机一直开着代理,curl google也没有问题,这里为什么就会超时。咨询了Gemini后是这么回答我的:
终端的环境变量代理(HTTP_PROXY)与 Docker 守护进程(Docker Daemon)的代理是完全独立的。
即使你在终端里执行
export http_proxy=...并且curl成功了,这只影响当前这个 Shell 窗口发出的请求。而docker build命令实际上是将指令发送给后台运行的 Docker Engine (dockerd),它并不读取你终端里的环境变量。要解决
docker build时的超时,你需要针对性地配置 Docker 守护进程或构建参数。
嗯,看来Docker还是有很多东西要学习的。Gemini也给出了解决办法,快速点就是直接换源,在Dockerfile_ros1_20_04中修改源地址:
1 | FROM osrf/ros:noetic-desktop-full # 注释掉原有的官方地址 |
然后就是漫长的等待时间,等待安装完成即可。
3 标定过程
安装完成之后,使用以下命令进入docker环境:
1 | docker run -it \ |
要进行相机-IMU标定前需要先对相机进行内参标定,然后才可以进行外参标定,接下来分别进行介绍。
3.1 相机内参标定
进行相机内参标定时需要用到标定板,然后编写对应的配置文件,我这里用的是棋盘格(Checkerboard),将对应的配置文件写下作为参考:
1 | target_type: 'checkerboard' |
当然,更推荐使用Aprilgrid,在抗遮挡方面效果更佳,其对应的配置文件为:
1 | target_type: 'aprilgrid' |
完成标定板的配置文件之后,就可以利用提前录制的标定rosbag来进行标定了:
1 | rosrun kalibr kalibr_calibrate_cameras \ |
然后程序就可以自主运行,解算出相机的内参与标定结果文件了。
3.2 相机-IMU外参标定
3.2.1 IMU配置文件
在得到相机的内参之后,就可以进行相机-IMU的外参标定了,这里还需要准备以下IMU的相关噪声参数,这些参数都可以从datasheet中获取,这里写下IMU的噪声参数配置文件:
1 | rostopic: /imu0 |
这里需要注意单位换算,以ADIS16470手册中给的数值为例:

文件中给定的陀螺仪、加速度计的随机游走单位分别为$^\circ/\sqrt{\text{hr}}$、$ \text{m}/\text{s}/\sqrt{\text{hr}}$,而配置文件中要求的单位分别是:$ \text{rad}/\text{s}^2/\sqrt{\text{Hz}}$、$\text{m}/\text{s}^3/\sqrt{\text{Hz}}$,这里给出对应的转换关系:
而噪声密度参数的单位转换比较简单,从$^\circ$转换为rad、从$\mu g$转换为$\text{m}/\text{s}^2$,这里就不多赘述了。
3.2.2 标定与结果
编写完IMU的配置文件之后即可进行相机-IMU外参标定了,命令如下所示:
1 | rosrun kalibr kalibr_calibrate_imu_camera \ |
与相机标定命令类似,需要对上述各路径根据实际情况进行修改。然后程序就可以自主运行,得到相机和IMU之间的外参了。这里以我的标定结果为例进行说明:
1 | cam0: |
值得注意的是,这里得到的是从IMU坐标系到相机坐标系的转换矩阵,即:
若想获取从相机坐标系到IMU坐标系的转换矩阵,可以通过下式得到: