机器人操作系统ROS—摄像头标定

最近使用摄像头做三维重建和激光雷达联合建图,发现摄像头所还原的三维点云与激光雷达的点云在不少位置存在明显偏差。使用两个点云构建的地图进行导航对比,还是激光雷达的更加精准,此时很有可能是摄像头的标定不精准导致的,本文就主要讲下如何对摄像头进行标定。

一、概述

摄像头这种精密仪器对光学器件的要求较高,由于摄像头内部与外部的一些原因,生成的物体图像往往会发生畸变,为了避免数据源造成的误差,需要针对摄像头的参数进行标定。

标定的参数主要分以下三部分:

  • 镜头畸变
  • 相机内参
  • 相机外参

1.畸变系数

畸变可分为两种,分别是切向畸变和径向畸变。

径向畸变的产生是由于当光线在远离透镜中心时,其弯曲程度比靠近中心时更大,径向畸变有桶形畸变和枕形畸变两种,分别如下图中的第二张和第三张:

切向畸变是由于透镜与图像不完全平行而产生,如下图:

畸变系统不受相机拍摄的分辨率和其他因素影响,时相机本身的固有属性。根据OpenCV的文档,畸变可归纳如下,k1,k2,k3,k4,k5,k6径向畸变系数,p1,p2是切向畸变系数:

(k1,k2,p1,p2[,k3[,k4,k5,k6]])

2.相机内参

相机内参与镜头本身的焦距等相关,为摄像机本身特性,可通过六个参数表示为:1/dx、1/dy、s、u0、v0、f。

dx和dy表示x方向和y方向的一个像素分别占多少长度单位,即一个像素代表的实际物理值的大小;u0,v0表示图像的中心像素坐标和图像原点像素坐标之间相差的横向和纵向像素数;f为焦距;s为坐标轴倾斜参数。

在opencv文档里内参数共四个为fx、fy、u0、v0。其中fx=f*(1/dx),fy=f*(1/dy),s假设为0,因此为4个内参

fx,fy为焦距,一般情况下,二者相等,cx、cy为主点坐标(相对于成像平面)。

焦距是光学系统中衡量光的聚集或发散的度量方式,指平行光入射时从透镜光心到光聚集之焦点的距离。亦是照相机中,从镜片中心到底片或CCD等成像平面的距离。具有短焦距的光学系统比长焦距的光学系统有更佳聚集光的能力。简单的说焦距是焦点到面镜的中心点之间的距离。

3.相机外参

相机外参矩阵描述的是相机在静态场景下相机的运动,包括旋转和平移,或者在相机固定时,运动物体的刚性运动。

相机坐标系的三个轴的旋转参数分别为(ω、δ、 θ),然后把每个轴的3*3旋转矩阵进行组合(即先矩阵之间相乘),得到旋转矩阵R,其大小为3*3;T的三个轴的平移参数(Tx、Ty、Tz)。R、T组合成成的3*4的矩阵。

 

4.总结

标定参数示例:

 

二、准备工作

1.安装摄像头标定功能包

ROS官方提供了用于双目和单目摄像头标定的功能包——camera_calibration,我们使用这个包进行测试。

sudo apt install ros-melodic-camera-calibration 

2.打印标定板

8x6x0.024棋盘格标定板

棋盘格参数:

  • size:8×6是指横/纵向格间十字角点的数量,而不是格的数量;
  • square:0.024是每格的边长,单位m;(如果用非A4纸打印,需要重新量一下边长,例如这个示例标定板打印在A3纸上边长是0.035m)

不同规格的棋盘格标定板:

将上方不同规格的棋盘格打印出来,贴到硬纸板上备用。

标定板选择:

  • 硬纸板需要平面度高,加工精度高,不反光;
  • 标定板不是越大越好,较大时精度不容易保证;
  • 尽量选择角点个数不多,面试不是很大的标定板,一般建议1米以内;
  • 如果频繁因为棋盘格某个角点被干扰导致整块板检测不到,推荐使用AprilTag二维码进行检测,角点精度高,可以减少环境干扰;

 

三、开始标定

1.标定摄像头

1.1.启动标定程序

推荐方法:

# vslam code
cd ~/catkin_ws/src
git clone git@github.com:yanjingang/robot_vslam.git
cd .. 
catkin_make 

# 启动摄像头
roslaunch robot_vslam astrapro.launch

# 启动标定程序(size/square:标定板角点数量和边长;image/camera:设置摄像头发布的图像topic/service) 
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:=/camera/rgb/image_raw camera:=/camera/rgb
*注:camera参数的查找方法: rosservice list|grep set_camera_info ,然后取/set_camera_info前的部分即可

官方方法:

# usb cam code
sudo apt install ros-melodic-image-view ros-melodic-freenect-*
cd ~/catkin_ws/src
git clone git@github.com:ros-drivers/usb_cam.git
cd .. 
catkin_make 

# 启动usb摄像头 
roslaunch usb_cam usb_cam-test.launch

# 启动标定程序(size/square:标定板角点数量和边长;image/camera:设置摄像头发布的图像topic/service) 
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:=/usb_cam/image_raw camera:=/usb_cam
1.2.开始标定

将标定板放到摄像头视野范围内,为了提高准确性,应尽量让标定版在摄像头视野内左右、上下、前后、倾斜运动,直到CALIBRATE按钮变色,表示标定程序的参数采集完成。

*注:如果用于环视相机标定,相机间的标定精度很重要,会影响环视拼接效果,因此标定板因处于两个相机的共视区域;

CALIBRATE按钮变色后,点击CALIBRATE按钮,标定程序将自动计算摄像头的标定参数,计算需要一定时间,此时终端将显示“**** Calibrating ****”标定中,出结果前别关闭窗口。

参数计算完成后会在终端显示标定结果,点击SAVE按钮保存标定文件包,解压标定文件包,使用里边的ost.yaml文件即可。

 

3.标定双目摄像头

除了RGB摄像头,双目相机一般还有一个红外深度摄像头,两个摄像头需要单独标定,标定方法同上,只是topic不同:

# 启动摄像头
roslaunch robot_vslam astrapro.launch

# 启动标定程序(size/square:标定板角点数量和边长;image/camera:设置摄像头发布的图像话题) 
# RGB摄像头
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:=/camera/rgb/image_raw camera:=/camera/rgb
# 红外深度摄像头
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:=/camera/ir/image camera:=/camera/ir

4.加载标定文件

将rgb和ir摄像头的标定文件copy到robot_vslam/config/astrapro/目录下,然后修改vslam的标定文件参数:

vim robot_vslam/launch/camera/astrapro.launch
  <arg name="rgb_camera_info_url"   default="file://$(find robot_vslam)/config/astrapro/camera_640.yaml" />
  <arg name="depth_camera_info_url" default="file://$(find robot_vslam)/config/astrapro/depth_640.yaml" />

重新启动vslam查看效果即可。

*注:如果直接使用robot_vslam astrapro.launch启动摄像头,因为里边已经配置了标定文件,所以重新标定后将会自动覆盖配置的原标定文件,不需要再手动copy。

 

四、效果对比

标定前:

标定后:

yan 22.6.27

 

参考:

AprilTag_ros包的使用

欢迎关注下方“非著名资深码农“公众号进行交流~

发表评论

邮箱地址不会被公开。