0 前言
本文主要介绍激光雷达传感器的基本原理和优缺点,同时借助PCL对激光雷达感知算法的一些常见的数据预处理方法进行代码讲解。在本文介绍的点云数据预处理模块为感兴趣区域划分(ROI)和点云滤波,目的是降低点云数量和过滤噪声点,从而为后续的算法提供一个较为良好的输入数据。
1 激光雷达传感器(LIDAR)基本原理
目前市场上的激光雷达传感器主要可以分为机械式旋转激光雷达,混合固态激光雷达(MEMS)和固态激光雷达。其中,机械式旋转激光雷达较为常见,本文主要针对该类型激光雷达传感器的基本原理展开介绍。
1.1 LIDAR成像机制
目前市面上的激光雷达的测距原理主要是飞行时间测距法 (Time of Flight,TOF),根据激光束的飞行速度和时间,获得物体与激光雷达之间的距离信息。计算公式如下:
d
=
0.5
∗
C
∗
△
t
d=0.5*C*\triangle t
d=0.5∗C∗△t
其中,C为光速,
△
t
\triangle t
△t为发射和接收激光束的时间差。下面两个图示分别为单线激光雷达和多线激光雷达的成像原理,区别在于:1)单线激光雷达有且仅有一个激光束,多线激光雷达拥有多线激光束(16/32/64/128);2)单线激光雷达的点携带的信息通常为
(
d
,
α
,
t
i
m
e
s
t
a
m
p
,
i
n
t
e
n
s
i
t
y
)
(d,\alpha,timestamp,intensity)
(d,α,timestamp,intensity),多线激光雷达的点携带的信息通常为
(
d
,
α
,
β
,
t
i
m
e
s
t
a
m
p
,
i
n
t
e
n
s
i
t
y
)
(d,\alpha,\beta,timestamp,intensity)
(d,α,β,timestamp,intensity)。其中,
r
r
r为反射距离,
α
\alpha
α为水平扫描角度分辨率,
β
\beta
β为垂直扫描角度分辨率,
t
i
m
e
s
t
a
m
p
timestamp
timestamp为该点的时间戳,
i
n
t
e
n
s
i
t
y
intensity
intensity为反射强度信息。由多个点(Point)组成的集合通常被成为点云(PointCloud)。
对于每个返回的激光点(Point)还会根据反射物体的材质和颜色等返回不一样的强度信息,在实际应用中,可以利用点云强度信息的差异性进行车道线等特征提取(埋个坑,后续会更新基于激光点云强度信息的车道线特征提取)。
1.2 主要关注的指标:
对于激光雷达传感器而言,主要关注的指标有以下几个:线束、波长、测量精度、探测距离、点频、垂直视场角、水平视场角、旋转频率。具体可见下表格:
1.3 优缺点:
优势:可以表达三维空间信息,数据结构形式简单,测距准确,受光照影响较小;
难点:
- 密度:稀疏性,“近密远疏”;
- 不规则(无序性):难以搜索领域点;
- 缺少纹理信息;
- 无序性:交换数据的顺序,不会改变点云单对于深度学习结果会造成影响,该问题后续会介绍);
- 旋转平移不变性:会改变点云的坐标,对深度学习是一个很大的挑战;
- 价格较为昂贵。
1.4 小结
激光雷达是一种主动发射光源的传感器,其根据TOF原理进行测距,受光照影响较小,相比视觉其成像细节更稀疏,触发方式为逐点成像并且成像时间无误差,点云存在近密远疏的特性,价格较为昂贵。
2 激光雷达数据预处理
在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,以及电磁波衍射特性、北侧物体表面性质变化和数据拼接配准操作过程的影响,点云数据中将不可避免地出现一些噪声点。此外,由于受到外界干扰如视线遮挡、障碍物等因素影响,点云数据中往往存在着一些离主体点云(即被测物体点云)较远的离散点,即离群点。在点云处理流程中,滤波处理作为预处理的第一步,往往对后续处理管道影响很大。只有在数据预处理过程中将噪声点和离群点等信息过滤,才能更好地进行后续的目标检测。在本系列中,数据预处理主要有三个方面:
1)激光雷达标定 – 将点云数据转换至车辆坐标系上。具体方法可参考 激光感知算法–多激光雷达联合静态标定;
2)感兴趣区域划分;
3)点云滤波去噪;
本文主要介绍几种简单的点云滤波算法进行感兴趣区域划分和过滤噪声点。
2.1 感兴趣区域划分(ROI)
感兴趣区域划分,顾名思义就是划分出我们进行目标检测时需要重点关注的区域。准确的区域数据提取可以过滤掉远处障碍物所产生的点云数据,极大的降低数据量,聚焦于需要检测的目标上。对于自动驾驶感知任务而言,感兴趣区域主要为车辆行驶的道路,主要关注在道路上行驶的车辆、行走或者等待的行人以及其他可能会出现的障碍物。对于激光感知传统感知方法而言,感兴趣区域划分的方法有:可行驶区域(freespace),人为设定条件和通过道路边界划分(车道线/路沿)等。本篇文章主要介绍基于条件划分感兴趣区域,采用PCL中的直通滤波器实现。直通滤波器通过设定某个维度的条件,即可去掉或保留用户指定范围的点。代码如下:
pcl::PassThrough<pcl::PointXYZI> pass; //设置滤波器对象
pass.setInputCloud(cloud); //设置输入点云
pass.setFilterFieldname("x"); //设置过滤是所需要点云类型的字段为"x"
pass.setFilterLimits(-50,100); //设置再过滤字段上的范围
pass.setFilterLimitsNegative(true); //设置保留(true)还是过滤掉(false)范围内的点
pass.filter(*cloud_filtered); //执行滤波,保留过滤结果再cloud_filtered中
通过上述代码即可划分出x方向上的区域,上述代码的结果为保留在x方向上(-50m,100m)内的点云。同理,我们也可以通过同样的方法划分出y方向和z方向上的点云数据,以达到我们感兴趣区域划分的目的。
2.2 点云滤波
2.2.1 体素滤波降采样
本小节介绍如何使用体素化网格方法实现下采样,即减少点的数量,降低点云的数量,并同时保持点云的形状特征,PCL中通过使用VoxelGrid滤波器实现该功能。该算法原理为通过对输入的点云数据创建三维体素栅格,每个体素可以想象成一个三维立方体,计算体素内所有点的重心(可以想象成一个新的点)并用该重心代表体素内所有的点。重心的计算公式如下:
因为该方法时使用一个点代替体素内的所有点,所以降采样的程度取决于体素的尺寸大小,体素设置的越大,降采样程度越高,过滤后的点云越稀疏,但丢失点云的信息也会越多。PCL中体素滤波降采用的实现代码如下:
pcl::VoxelGrid<sensor_msgs::PointCloud2> voxel_sor; //创建滤波对象
voxel_sor.setInputCloud(cloud); //给滤波器对象设置需要过滤的点云
voxel_sor.setLeafSize(0.01f,0.01f,0.01f); //设置滤波时创建的体素大小为1cm的立方体
voxel_sor.filter(*cloud_filtered); //执行滤波处理,存储输出cloud_filtered
2.2.2 统计滤波过滤离群点
激光雷达在扫描过程中通常会产生密度不均匀的点云数据,本小节介绍的统计滤波可有效对离群点进行过滤,基于PCL中的StatiscalOutlierRemoval滤波器实现。基本原理为:计算输入点云中查询点与邻近点的平均距离,假设得到的结果是一个高斯分布,其形状由均值和标准差决定,平均距离在标准范围(由全局距离平均值和方差定义)之外的点,可被定义为离群点并从输入数据中过滤掉。具体实现代码如下:
pcl::StatisticalOutlierRemoval<pcl::PointXYZI> statis_sor; //创建滤波对象
statis_sor.setInputCloud(cloud); //给滤波器对象设置需要过滤的点云
statis_sor.setMeanK(50); //设置进行统计滤波时考虑的查询点的邻近点个数
statis_sor.setStddevMulThresh(1.0); //设置离群点的距离判断阈值
statis_sor.filter(*cloud_filtered); //执行滤波并将滤波后点云存储至cloud_filtered
3 总结
本篇博客主要正对机械式旋转激光雷达的基本原理以及点云数据的优缺点和指标进行了介绍,并基于PCL介绍了直通滤波,体素滤波降采样和统计滤波这几种常见的点云数据预处理方法。本系列的下一篇将对点云地面分割方法做一个综述,并介绍地面平面拟合方法(GPF)的代码实现方法,感兴趣的同学欢迎持续关注~