ROS功能包:livox_camera_lidar_calibration提供了一个手动校准Livox雷达和相机之间外参的方法,已经在Mid-40,Horizon和Tele-15上进行了验证。其中包含了计算相机内参,获得标定数据,优化计算外参和雷达相机融合应用相关的代码。本方案中使用了标定板角点作为标定目标物,由于Livox雷达非重复性扫描的特点,点云的密度较大,比较易于找到雷达点云中角点的准确位置。相机雷达的标定和融合也可以得到不错的结果。
在前一篇中链接:gazebo仿真livox_camera_lidar_calibration—相机内参标定
获得了相机内参标定的数据结果:
image_width: 1024
image_height: 960
camera_name: narrow_stereo
camera_matrix:
rows: 3
cols: 3
data: [725.710429, 0.000000, 511.420214, 0.000000, 725.718815, 479.632811, 0.000000, 0.000000, 1.000000]
distortion_model: plumb_bob
distortion_coefficients:
rows: 1
cols: 5
data: [0.000047, 0.000106, 0.000019, 0.000009, 0.000000]
rectification_matrix:
rows: 3
cols: 3
data: [1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000]
projection_matrix:
rows: 3
cols: 4
data: [725.828125, 0.000000, 511.433189, 0.000000, 0.000000, 725.827393, 479.658265, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000]
这个信息在之后会用到,通过相机内参校正后的图片与雷达的数据进行同名点选取.
本篇博客主要介绍,如何在gazebo中进行标定数据的采集.最后我们会得到两个传感器的同名点.
就是激光雷达 的x y z 对应的 相机的图片的u v.
在完成了前几篇博客的内容后,下面需要做的就是相机和激光雷达标定数据的采集.
在gazebo中搭建的标定场景里,用一个矩形的标定板其中的四个角作为目标物,尺寸是2*2.5m.
标定场景搭建的链接在这里.
需要做的是 :选取至少10个左右不同的角度和距离来摆放标定板,左右位置和不同的偏向角度最好都有采集数据.每个位置保存一张图片和10s左右的rosbag即可
检查标定板是否在点云中,可以使用如下指令:
roslaunch livox_ros_driver livox_lidar_rviz.launch
需要livox 的 点云消息格式是customMsg
可以通过下面的指令检查下
rostopic info /livox/lidar
同时需要检查下标定板是否在照片中,使用如下指令:
rqt_image_view
检测下数据没问题开始采集
可以用rqt_image_view保存图片,用rosbag record /livox/lidar记录雷达数据
所以在data文件夹下新建这个两个文件夹,然后保存数据,为了数据好对应,可以直接用1\2\3命名
然后将标定板旋转一定角度再次采集数据.如何直接旋转,在上一篇博客中有操作.
重复上面的采集过程,继续操作,可以在一个位置,进行3个角度的变换姿态采集,这样一个位置是4组数据
之后移动标定板的位置到左上,再采四组数据
移动标定板的位置到右下,再采四组数据
所以我是采了12组数据,对应这12个雷达的rosbag
至此相机和激光雷达的初始标定数据就采集完成了
打开pcdTransfer.launch
<?xml version="1.0" encoding="UTF-8"?>
<launch>
<param name="input_bag_path" value="$(find camera_lidar_calibration)/data/lidar/" /> <!-- rosbag folder -->
<param name="output_pcd_path" value="$(find camera_lidar_calibration)/data/pcdFiles/" /> <!-- path to save new pcd files -->
<param name="threshold_lidar" type="int" value="80" /> <!-- the limit of messages to transfer to the pcd file, 80 means maximum 80 messages of lidar -->
<param name="data_num" type="int" value="12" /> <!-- the number of the rosbag -->
<node pkg="camera_lidar_calibration" name="pcdTransfer" type="pcdTransfer" output="screen"></node>
</launch>
然后运行指令将rosbag批量转化成PCD文件,PCD文件默认保存在data/pcdFiles文件夹中
roslaunch camera_lidar_calibration pcdTransfer.launch
终端会逐渐的打印转换的过程,把上面录的文件逐个转换完就可以了
之后在pcdFiles文件夹中检查下,文件:
然后使用pcl_viewer打开PCD文件,按住shift+左键点击即可获得对应的点坐标。
pcl_viewer -use_point_picking xx.pcd
选择标定板的角点,然后记录下它的坐标,注意这里记录顺序,之后要和照片的记录顺序保持一致.可以选择左上角开始,然后逆时针记录.
记录的时候在data文件夹下,新建一个corner_lidar.txt,安照下面的格式记录下来,格式一定要正确.
慢慢调下pcl_viewer的视角,然后shift+左键点击,在终端中会打印出该点的坐标,手动写入txt中按照格式
之后程序读取数据的时候,设置是这样的
每行数据只有超过10个字母程序才会将其读取为计算的参数,所以上面的数据中用来编号的1 2 3 4 和标题,test0 test1 是不会被读的.
程序读到空行就会停止读取参数开始计算,所以保存时不要空行。
把雷达的角点全部标完之后,就可以提取照片中的角点像素了
首先需要把最上面获得的相机内参畸变纠正参数以下图的格式保存在data/parameters/intrinsic.txt文件下
distortion下面对应5个畸变纠正参数,按顺序是k1和k2 (RadialDistortion),p1和p2 (TangentialDistortion),最后一个是k3,一般默认是0
配置cornerPhoto.launch文件中的照片路径:
<?xml version="1.0" encoding="UTF-8"?>
<launch>
<param name="intrinsic_path" value="$(find camera_lidar_calibration)/data/parameters/intrinsic.txt" /> <!-- intrinsic file -->
<param name="input_photo_path" value="$(find camera_lidar_calibration)/data/photo/1.bmp" /> <!-- photo to find the corner -->
<param name="ouput_path" value="$(find camera_lidar_calibration)/data/corner_photo.txt" /> <!-- file to save the photo corner -->
<node pkg="camera_lidar_calibration" name="cornerPhoto" type="cornerPhoto" output="screen"></node>
</launch>
运行
roslaunch camera_lidar_calibration cornerPhoto.launch
程序会在UI中打开对应的照片。在这个UI界面上只要把鼠标移到标定板的各个角上,窗口左下角就会显示对应的坐标数据。按照雷达采集的角点的顺序(左上角开始,逆时针),记录下四个角点坐标。
比如:
284 275
284 668
776 668
775 275
记录完毕后选中显示的图片按任意键,进入坐标输入流程。把记录下的四个坐标”x y”按顺序输入,x和y中间要有空格(比如: “635 487”),输入完成后输入”0 0”即可结束输入流程(如下图例所示)。程序会算出四个更精确的float类型坐标显示出来,并保存在data/corner_photo.txt中。然后按任意键结束整个流程。
更改cornerPhoto.launch文件中的照片路径,重复上述流程,直至获得所有照片的角点坐标。
此时我们需要的标定数据就采集完成了,总结下
在data文件夹下生成了两个标定数据的文件 :