来源丨古月居
功能包介绍
该功能包提供了一个手动校准Livox雷达和相机之间外参的方法,已经在Mid-40,Horizon和Tele-15上进行了验证。
其中包含了计算相机内参,获得标定数据,优化计算外参和雷达相机融合应用相关的代码。
本方案中使用了标定板角点作为标定目标物,由于Livox雷达非重复性扫描的特点,点云的密度较大,比较易于找到雷达点云中角点的准确位置。
相机雷达的标定和融合也可以得到不错的结果。
功能包名称:livox_camera_lidar_calibration
功能包使用环境:Ubuntu 64-bit 16.04
使用步骤
采集数据
连接雷达检查标定板角点是否在点云中
输入点云可视化的命令查看点云
roslaunch livox_ros_driver livox_lidar_rviz.launch
这样就在rviz中显示了点云
连接相机检查标定板角点是否在照片中
打开相机,检查获取照片的质量,并检查标定板角点是否在照片中。具体方法根据相机型号来了。
采集照片和点云数据
拍摄照片运行指令录制点云
roslaunch livox_ros_driver livox_lidar_msg.launchrosbag record /livox/lidar
每个位置保存一张照片和10s左右的rosbag即可
数据采集完成后,将照片放在data/photo文件夹下; 雷达rosbag放在data/lidar文件夹下
以上步骤数据就采集好了,下面进行标定工作
标定角点
设置相机内参
首先需要把得到的内参和畸变纠正参数以下图的格式保存在data/parameters/intrinsic.txt文件下 。
distortion下面对应5个畸变纠正参数,按顺序是k1和k2 (RadialDistortion),p1和p2 (TangentialDistortion),最后一个是k3,一般默认是0
获得照片中的角点坐标
配置cornerPhoto.launch文件中的照片路径,运行
roslaunch camera_lidar_calibration 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/0.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>
程序会在UI中打开对应的照片。在这个UI界面上只要把鼠标移到标定板的各个角上,窗口左下角就会显示对应的坐标数据。
确定一个顺序,一般从左上角的角点开始,逆时针旋转按顺序记录下四个角点坐标。
记录完毕后选中显示的图片按任意键,进入坐标输入流程。
把记录下的四个坐标”x y”按顺序输入,x和y中间要有空格(比如: “635 487”),输入完成后输入”0 0”即可结束输入流程(如下图例所示)。
程序会算出四个更精确的float类型坐标显示出来,并保存在data/corner_photo.txt中。然后按任意键结束整个流程。
更改cornerPhoto.launch文件中的照片路径,重复上述流程,直至获得所有照片的角点坐标。
获得雷达点云中的角点坐标
检查pcdTransfer.launch文件中的rosbag路径,设置rosbag的数量,并将rosbag以0.bag, 1.bag…命名。
运行指令将rosbag批量转化成PCD文件,PCD文件默认保存在data/pcdFiles文件夹中
roslaunch camera_lidar_calibration 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="10" /> <!-- the number of the rosbag --> <node pkg="camera_lidar_calibration" name="pcdTransfer" type="pcdTransfer" output="screen"></node></launch>
使用pcl_viewer打开PCD文件,按住shift+左键点击即可获得对应的点坐标。注意和照片采用相同的角点顺序
pcl_viewer -use_point_picking xx.pcd
将xyz角点坐标按如下格式保存在data/corner_lidar.txt中,将所有PCD文件中雷达点云的角点坐标保存下来。
上面的步骤把相机和雷达角点获得了,也就是同名点,下面就是计算外参了
参数设置
外参计算节点会读取data/corner_photo.txt和data/corner_lidar.txt中的标定数据来计算外参,数据需要保存成特定的格式才能被外参计算节点正确读取。
参考以下格式,每行数据只有超过10个字母程序才会将其读取为计算的参数,比如下图用来编号的1234,lidar0和0.bmp这些标题不会被读取为计算参数。
程序读到空行就会停止读取参数开始计算,所以保存时不要空行。
在计算前检查一下雷达和相机两个标定数据中是否每行对应的是同一个角点,并检查数据量是否相同
计算外参
外参计算getExt1节点
计算前在getExt1.launch文件中配置好外参初值
输入指令开始计算外参
roslaunch camera_lidar_calibration getExt1.launch
内容如下:
<?xml version="1.0" encoding="UTF-8"?><launch> <rosparam param="init_value"> [0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0] </rosparam> <!-- init value of roatation matrix(3*3 on the left) and the translation(3*1 vector on the right) --> <param name="intrinsic_path" value="$(find camera_lidar_calibration)/../../data/parameters/intrinsic.txt" /> <!-- intrinsic file --> <param name="extrinsic_path" value="$(find camera_lidar_calibration)/../../data/parameters/extrinsic.txt" /> <!-- extrinsic file --> <param name="input_lidar_path" value="$(find camera_lidar_calibration)/../../data/corner_lidar.txt" /> <!-- get the lidar corner data --> <param name="input_photo_path" value="$(find camera_lidar_calibration)/../../data/corner_photo.txt" /> <!-- get the photo corner data --> <param name="error_threshold" type="int" value="12" /> <!-- the threshold of the reprojection error --> <node pkg="camera_lidar_calibration" name="getExt1" type="getExt1" output="screen"></node></launch>
终端中可以看到每次迭代运算的cost,外参结果以齐次矩阵的格式保存到data/parameters/extrinsic.txt下。
可以根据优化后的残差和重投影误差评估一下得到的外参,重投影会把误差较大的数据打印在屏幕上,可以剔除异常标定数据后再重新进行优化计算。
外参计算getExt2节点
getExt1节点只优化外参,而getExt2节点在计算的时候会将一开始计算的内参作为初值和外参一起优化。
输入指令程序会得到一个新的内参和外参,并用新的参数来进行重投影验证。
roslaunch camera_lidar_calibration getExt2.launch
一般使用getExt1节点即可,如果在外参初值验证过,并且异常值已经剔除后,优化还是有较大的残差,那么可以使用getExt2试一试。
使用的前提需要保证标定数据量较大,并且要充分验证结果。
如果经过验证getExt2计算的结果确实更好,那么把新的内参更新在data/parameters/intrinsic.txt中
通过上面步骤已经得到了外参的结果,结果的优略可以通过下面的验证方法
结果验证
获得外参后我们可以用两个方式看一下融合的效果。第一个是将点云投影到照片上,第二个是点云的着色。
投影点云到照片在projectCloud.launch文件中配置点云和照片的路径后,运行指令,将rosbag中一定数量的点投影到照片上并且保存成新的照片。
roslaunch camera_lidar_calibration projectCloud.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="extrinsic_path" value="$(find camera_lidar_calibration)/../../data/parameters/extrinsic.txt" /> <!-- extrinsic file --> <param name="input_bag_path" value="$(find camera_lidar_calibration)/../../data/lidar/0.bag" /> <!-- rosbag file --> <param name="input_photo_path" value="$(find camera_lidar_calibration)/../../data/photo/0.bmp" /> <!-- photo file --> <param name="output_path" value="$(find camera_lidar_calibration)/../../data/projection/new.bmp" /> <!-- path to save new photo file --> <param name="threshold_lidar" type="int" value="30000" /> <!-- the maximum points shown on the photo --> <node pkg="camera_lidar_calibration" name="projectCloud" type="projectCloud" output="screen"></node></launch>
点云着色在colorLidar.launch文件中配置点云和照片的路径,运行指令,可以在rviz中检查着色的效果。
roslaunch camera_lidar_calibration colorLidar.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="extrinsic_path" value="$(find camera_lidar_calibration)/../../data/parameters/extrinsic.txt" /> <!-- extrinsic file --> <param name="input_bag_path" value="$(find camera_lidar_calibration)/../../data/lidar/0.bag" /> <!-- rosbag to give the lidar info --> <param name="input_photo_path" value="$(find camera_lidar_calibration)/../../data/photo/0.bmp" /> <!-- photo to get RGB info --> <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 --> <node pkg="camera_lidar_calibration" name="colorLidar" type="colorLidar" output="screen"></node> <node name="rviz" pkg="rviz" type="rviz" respawn="true" args="-d $(find camera_lidar_calibration)/launch/config.rviz"/></launch>
本文仅做学术分享,如有侵权,请联系删文。
干货下载与学习
后台回复:巴塞罗那自治大学课件,即可下载国外大学沉淀数年3D Vison精品课件
后台回复:计算机视觉书籍,即可下载3D视觉领域经典书籍pdf
后台回复:3D视觉课程,即可学习3D视觉领域精品课程
3D视觉工坊精品课程官网:3dcver.com
2.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
3.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进
4.国内首个面向工业级实战的点云处理课程
5.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解
6.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦
7.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化
8.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)
重磅!3DCVer-学术论文写作投稿 交流群已成立
扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。
同时也可申请加入我们的细分方向交流群,目前主要有3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。
一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。
▲长按加微信群或投稿,加微信:dddvision
▲长按关注公众号
3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列、三维点云系列、结构光系列、手眼标定、相机标定、激光/视觉SLAM、自动驾驶等)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近4000星球成员为创造更好的AI世界共同进步,知识星球入口:
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~