多线激光 Velodyne 与相机的配准及投影

0x00 Velodyne 简介

1. 数据结构及坐标系

Velodyne 通过网线发送的原始数据包为球坐标(spherical coordinates, r, ω, α)。它的 ros driver 提供了两种更方便的格式:/velodyne_points/velodyne_scan

其中,/velodyne_points是转换为XYZ后的坐标,转换的方式如下图;/velodyne_scan为第8根线的scan值(可直接用来模拟单线雷达)。

/velodyne_points的数据结构为:

  • point: 坐标(x,y)
  • intensity: 强度(0~255) 具体解释见下节(反射率)
  • ring: 第几根线(0~15)

2. 反射率

Velodyne 测量 1m - 100m 物体的反射率(距离小于一米的点应该被忽略),其反射率的标定文件存储在VLP-16内置的FPGA中。当反射为漫反射(Diffuse Reflector)时,反射率的数值为0~100;当反射为逆反射(Retro-Reflector)时,数值为101~255.

3. 反射模型

Velodyne 单次激光可能撞击多个物体,产生多次返回值,VLP-16 可以记录最强反射和最后一次反射。如下图大部分光束撞击近壁,而光束的其余部分撞击远墙。只有当两个物体之间的距离大于1米时,VLP-16才会记录两个返回值,如果最强反射是最后一次反射,则报告次强反射值。

8.png

双返回功能通常用于林业应用,用户需要确定树木的高度。下图说明了当激光点撞击外部树叶,穿透树叶和树枝并最终撞击地面时返回的值。

7.png

在Velodyne的配置页面中可以选择反射模型: StrongestLastDual.

9.png

4. Velodyne 坐标系

VLP-16 原始的返回值为球坐标(spherical coordinates, r, ω, α)。 在rosbag中,/velodyne_points是转换为XYZ后的坐标;/velodyne_scan为第8根线的scan值(可直接用来模拟单线雷达)。 坐标系如下图所示。

5.png

5. 相机坐标系

考虑到需要对VLP-16与相机进行配准,需要了解相机的坐标系。(Z轴向前)

11.png

0x01 标定

标定可以参见这篇: 多目相机、Velodyne标定那些破事

0x02 将 Velodyne 的深度信息投影到 camera

  1. 首先,获取点云信息 topic:/velodyne_points。在下图中,绿圈为标定板。
1
2
3
> points_velo = pointcloud2_to_xyz_array(msg).T   # np.array([X,Y,Z,1])
> points_velo.shape # 一帧有22301个点,坐标为(x, y, z, 1)
(4, 22301)

1.png

  1. 将点云转换到相机坐标系,只保留相机前方的点(黄色为保留的点)
    1
    2
    points_cam = np.matmul(transf_mat, points_velo)
    points_cam_front = points_cam.T[points_cam.T[:,2]>0].T

2.png

  1. 将空间坐标转换为图像上的坐标:
1
2
3
points_img = np.matmul(projection_matrix, points_cam_front)
points_img[0:2,:] /= points_img[2,:]
points_img = np.array(points_img.T)

4.png