无人驾驶汽车系统入门(三十一)——点云分割和聚类算法详解
本篇详细讲解点云处理中的基本分割和聚类的算法原理。
Lidar基本常识
lidar的分辨率要高于radar,但是radar可以直接测量目标的速度。通过融合两者,可以获得对目标较好的位置和速度估计。
激光雷达坐标系:右手法则,大拇指朝上为z,食指朝前为x,中指朝左为y, lidar的解析度很大程度上取决于线数,其解析度指标分为横向解析度和纵向解析度,横向解析度即一条激光束扫描一圈(360度)的反射点的数量,作为参考,Velodyne的16线激光雷达的横向解析度为1800个反射点,即:
360 1800 = 0.2 d e g r e e / p o i n t \frac{360}{1800} = 0.2 \ degree/point 1800360=0.2 degree/point
也就是说这一款雷达横向上每0.2度有一个反射点。纵向解析度即雷达的线束数量,线束越多解析度越高。
常用的point cloud处理工具:
- PCL: 主要用于点云滤波、分割和聚类
- OpenCV
- ROS:提供了一些点云数据表示、消息格式、坐标变化、可视化工具
- Eigen:线性运算库,可用于描述各类变换,通常用于点云的坐标变换(点云SLAM里用的比较多)
传统的点云感知算法处理流程:
- 点云滤波:降采样点云以加速后续计算
- 点云分割:分别提取出地面点和非地面点
- 点云聚类:将非地面点通过空间关系聚类成点云簇
- 目标轮廓拟合:使用设定形状(如bounding box)将点云簇拟合
本文详细讲解基础的点云分割和点云聚类算法。
点云滤波和降采样
为什么做滤波(filter)和降采样?
滤波是点云预处理的步骤,可以显著减低后续处理的计算复杂度,有些滤波方法还能够滤除点云中的噪点。PCL提供多种点云滤波方法的实现,其中应用最多的是体素滤波:Voxel grid filter. 体素滤波即将空间按照一定尺寸(比如说 1 m × 1 m × 1 m 1m \times 1m \times 1m 1m×1m×1m)的立方体格进行划分,每个立方格内仅保留一个点。下图是voxel size为0.3m的降采样结果。
PCL提供各类成熟的点云滤波方法,以体素滤波为例:
typename pcl::VoxelGrid<PointT> voxel_filter;
voxel_filter.setInputCloud(cloud);
voxel_filter.setLeafSize(filterRes, filterRes, filterRes);
typename pcl::PointCloud<PointT>::Ptr ds_cloud(new pcl::PointCloud<PointT>);
voxel_filter.filter(*ds_cloud);
点云分割:RANSAC 算法
RANSAC: RANdom SAmple Consensus, 通过随机采样和迭代的方法用一种模型(比如说直线模型、平面模型)拟合一群数据,在点云处理中通常用于点云数据的分割,以最简单的直线拟合为例:
给定平面内若干个点的集合 P n : { ( x 0 , y 0 ) , ( x 1 , y 1 ) , . . . , ( x n , y n ) } P_n: \{(x_0, y_0), (x_1, y_1), ... , (x_n, y_n)\} Pn:{ (x0,y0),(x1,y1),...,(xn,yn)},要求得一条直线 L : a x + b y + c = 0 L: ax+by+c=0 L:ax+by+c=0 使得拟合尽可能多的点,也就是 n n n 个点到直线 L L L 的距离和最短;RANSAC的做法是通过一定的迭代次数(比如1000次),在每次迭代中随机在点集 P n P_n Pn 中选取两个点