相机-激光雷达联合标定方法

本文记录了在Ubuntu18.04和ROSMelodic中,使用OpenCV解决相机驱动编译问题,进行相机内参矫正,并通过Autoware.ai的Docker安装。此外,还详细介绍了相机与激光雷达的联合标定过程,包括标定软件的安装与使用,以及解决Docker中ROS通信问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇博客是记录一下自己遇到的问题。

相机是单目相机,激光雷达是机械式激光雷达。标定板是8×6,格宽112毫米。工控机x86架构,无CUDA,Ubuntu18.04,ROS Melodic。安装过程中需要科学上网。

一、准备好相机和激光雷达的ROS驱动

已有的相机驱动在工控机上编译出现了一些问题:

问题1:报错 undefined reference to `cv::*

解决:修改CMakeLists.txt

target_link_libraries(calibration_publisher
        ${catkin_LIBRARIES}
	${OpenCV_LIBS}
        )

问题2:报错Bad argument (Invalid pointer to file storage)

解决:修改CMakeLists.txt

find_package(OpenCV 版本号 REQUIRED)  //pkg-config --modversion opencv 查看OpenCV版本

问题3:‘CV_*’ was not declared in this scope

解决:把 CV_ 前缀去掉,因为 OpenCV4以上的版本,把这个常量名称前面的 CV_ 给去掉了。

----------------------------------------------------------------------------------------------------------------------------

已有的相机驱动没有对图像去畸并发布,因此利用OpenCV的cv::undistort函数矫正图像。

参考文章:OpenCV: Camera calibration With OpenCV

相机内参数据存储在驱动ROS包的launch文件夹下

%YAML:1.0
---
CameraExtrinsicMat: !!opencv-matrix
   rows: 4
   cols: 4
   dt: d
   data: [ 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0.,
       1. ]
CameraMat: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 1007.50155,     0.     ,   632.8408 ,
             0.     ,  1002.83854,   349.68827,
             0.     ,     0.     ,     1.     ]
DistCoeff: !!opencv-matrix
   rows: 1
   cols: 5
   dt: d
   data: [-0.507477, 0.212361, 0.013718, -0.011629, 0.000000]
Projection: !!opencv-matrix
   rows: 3
   cols: 4
   dt: d
   data: [ 743.61829,    0.     ,  588.62008,    0.     ,
            0.     ,  931.75195,  355.15731,    0.     ,
            0.     ,    0.     ,    1.     ,    0.     ]
ImageHeight: 720
ImageWidth: 1280
ImageSize: [1280, 720]
Reprojection Error: 0.0
DistModel: plumb_bob
rtsp: "rtsp://admin:admin123@192.168.3.210:554/h264/ch1/main/av_stream"
device_id: 0

二、 安装Autoware.ai

参考官方Wiki,用Docker安装,最方便。

第一步: 用自动安装脚本,安装Docker。

第二步: 用官方脚本,自动拉取Autoware。

问题:could not select device driver "" with capabilities: [[gpu]],usermod: UID '0' already exists

/*-c off :运行不带CUDA的版本 
-s :跳过uid modification步骤 */
$ ./run.sh -c off -s 

参考文章: Generic x86 Docker · autowarefoundation/autoware_ai_documentation Wiki · GitHub

三、 准备好标定软件

标定软件依赖 nlopt,安装参考:GitHub - stevengj/nlopt: library for nonlinear optimization, wrapping many algorithms for global and local, constrained or unconstrained, optimization

问题: nlopt::opt::get_errmsg() const': /usr/local/include/nlopt.hpp:516: undefined reference tonlopt_get_errmsg’

解决:以前用apt安装过nlopt,需要把apt安装的卸载

sudo apt remove libnlopt-dev

问题: CMakeLists.txt没定义Melodic版本导致编译不过

解决: CMakeLists.txt里所有 (indigo|jade|kinetic) 改为 (indigo|jade|kinetic|melodic)

四、 标定相机内参

第一步: 启动相机和激光雷达的ROS驱动

第二步: 启动相机标定软件

rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.112 image:=/camera/image

 第三步: 改变棋盘格在图像中的位置、大小、角度。等界面右侧的X、Y、Size、Skew的进度条都变成绿色后,点击右侧的CALIBRATE按键,等待标定结果计算完成。结果会显示在终端上。

第四步: 点击SAVE按键,保存标定结果

标定结果如下:

image_width: 1280
image_height: 720
camera_name: narrow_stereo
camera_matrix:
  rows: 3
  cols: 3
  data: [ 1007.50155,     0.     ,   632.8408 ,
             0.     ,  1002.83854,   349.68827,
             0.     ,     0.     ,     1.     ]
distortion_model: plumb_bob
distortion_coefficients:
  rows: 1
  cols: 5
  data: [-0.507477, 0.212361, 0.013718, -0.011629, 0.000000]
rectification_matrix:
  rows: 3
  cols: 3
  data: [ 1.,  0.,  0.,
          0.,  1.,  0.,
          0.,  0.,  1.]
projection_matrix:
  rows: 3
  cols: 4
  data: [ 743.61829,    0.     ,  588.62008,    0.     ,
            0.     ,  931.75195,  355.15731,    0.     ,
            0.     ,    0.     ,    1.     ,    0.     ]

五、 相机-激光雷达联合标定

第一步: 启动相机和激光雷达ROS驱动

第二步: 录制rosbag。

标定板要同时在相机和雷达的视野内,不停调整标定板的角度,录制的时候尽量录得长一点,这样的话后续可以有足够的时间调试。

参考别人的说法,录制的时候要手拿标定板,经过六个位置:

近处左、近处中、近处右

远处左、远处中、远处右

经过每个位置的时候,应该有五个动作:

平拿、左倾、右倾、上倾、下倾

录制结束后,关闭相机和激光雷达ROS驱动,播放rosbag

rosbag play 2023-02-06-14-11-11.bag --pause

参考:无人驾驶汽车系统入门(二十二)——使用Autoware实践激光雷达与摄像机组合标定_AdamShan的博客-优快云博客_autoware标定原理

第三步: 启动标定软件 

rosrun calibration_camera_lidar calibration_toolkit

标定软件订阅的激光雷达点云的话题是 /points_raw

 

 

第四步: 播放 rosbag,当进行到合适位置角度时,暂停包, 点击MainWindow右上角”Grab”,生成下半部分的摄像机和激光雷达信息的一组数据,建议抓取20组数据。

注: 如果摁Grab后没反应,是因为软件没有识别到棋盘格。

第五步: 在右下图选择标定版所在的点云。

注:激光雷达点云窗口的操作方法

  • 移动点云:上下左右方向键、PgUp、PgDn
  • 旋转点云:a、d、w、s、q、e
  • 切换模式:数字 1 和数字 2
  • 视角缩放:减号缩小、加号放大
  • 点云大小:o 键使用小点云、p 使用大点云
  • 改变点云窗口背景颜色:b

因为点云是黑色的,所以先把背景颜色改成白色,方便观察。如果看不到点云可以摁”2“调整视角。

第六步: 点击右上角”Calibrate“,等待左侧相机外参矩阵计算完成后,点击”Project“进行验证, 左下方图像中会出现根据计算结果和激光雷达数据生成的图像对应位置,以红色散点表示。如果散点分布在标定板上,说明标定正确;如果散点不在标定板上,则对右下方激光图像重新点选。

第七步: 点击”Save“保存结果。

结果如下:

%YAML:1.0
---
CameraExtrinsicMat: !!opencv-matrix
   rows: 4
   cols: 4
   dt: d
   data: [ -6.6509416238362151e-02, 1.3199913382493766e-02,
       9.9769848142528894e-01, 6.8346409603131542e-02,
       -9.9760973802460917e-01, 1.7903454143900599e-02,
       -6.6740369553880075e-02, -4.9583755059319737e-02,
       -1.8743216108864091e-02, -9.9975258370079378e-01,
       1.1977613847695578e-02, -1.2174364878299902e-01, 0., 0., 0., 1. ]
CameraMat: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 9.9868357534321535e+02, 0., 6.1304656309192160e+02, 0.,
       9.9742355204236799e+02, 3.9721506187397307e+02, 0., 0., 1. ]
DistCoeff: !!opencv-matrix
   rows: 1
   cols: 5
   dt: d
   data: [ 7.4253599884789731e-02, -5.7266121814878035e-01,
       2.3726414468503909e-03, 2.6464864302885730e-03,
       1.1595234975696214e+00 ]
ImageSize: [ 1280, 720 ]
ReprojectionError: 1.7367420059669290e+00

六、 查看融合效果

参考:使用Autoware标定工具包进行相机和激光雷达的联合标定_范猛男的博客-优快云博客_autoware联合标定

问题: Docker中的ROS和本地ROS通信

解决: 参考解决Docker中ROS通信失败问题--Error: unable to communicate with master!_使用ros在两个docker之间通信_kinderkindme的博客-优快云博客

### 常见的相机激光雷达联合标定方法 相机激光雷达联合标定通常涉及求解两者的外参关系,即旋转矩阵 \( R \) 和平移向量 \( T \)[^1]。这一过程的核心在于找到两者之间的几何对应关系,从而使得它们能够协同工作并提供一致的数据表示。 #### 方法概述 一种常见的方法是以标定板作为中间媒介来完成标定。具体来说,利用已知尺寸的标准棋盘格或其他特征明显的图案,在同一场景下分别采集图像数据(由相机获取)和点云数据(由激光雷达获取)。通过对这些数据中的共同特征点进行匹配,最终计算得到所需的变换参数。 #### 实现流程 以下是基于MATLAB的一个典型实现框架: 1. **准备阶段** - 准备带有清晰标记物(如黑白相间的棋盘格)的目标物体用于辅助测量。 2. **数据收集** 使用摄像头拍摄包含该目标的照片;同时启动LiDAR设备扫描相同区域内的三维空间坐标集合形成点云文件。 3. **处理分析** 应用计算机视觉算法检测二维平面图片里的角点位置,并提取对应的像素坐标值; 同样地,从三维点云里识别出相应的物理世界实际地点关联起来。 4. **优化估计** 构建数学模型表达上述两种不同类型观测间的关系式子并通过最小二乘法或者其他数值技术手段解决最优解问题获得精确的结果集{R|T}。 5. **验证测试** 完成初步估算之后还需要做一系列实验检验所得结论准确性如何以及适应范围大小等问题。 下面给出一段简单的伪代码展示整个操作逻辑: ```matlab % MATLAB Pseudo Code Example for Calibration Process clc; clear all; %% Step One: Load Images and Point Clouds Data imageData = imread('calibration_image.jpg'); % Replace with your image file name. pointCloudData = pcread('lidar_pointcloud.pcd'); % Replace with your point cloud file. %% Step Two: Detect Features from Image chessboardSize = [8,6]; % Define the number of inner corners per a chess board row/column. [imagePoints, boardSize] = detectCheckerboardPoints(imageData); %% Step Three: Segment Corresponding Area in Point Cloud segmentedPointCloud = segmentLidarData(pointCloudData,chessboardSize); %% Step Four: Estimate Transformation Parameters {R | t} transformationMatrix = estimateTransform(imagePoints, segmentedPointCloud); disp(transformationMatrix); ``` 此段脚本仅作为一个概念性的例子说明可能采用的技术路线图并不意味着可以直接运行成功因为缺少很多细节部分比如函数定义等等都需要额外补充完善才行。 另外值得注意的是除了传统方式之外还有其他新兴方案例如深度学习驱动下的无监督或者弱监督训练机制也可以用来达成相似目的只不过他们往往更加复杂同时也更依赖于高质量大规模标注样本的支持[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值