滤波学习记录
点云需要处理的主要情况包括:
下采样,数据量过大,不易于处理
离群点,通常由遮挡引起
点云数据的密度不均匀
噪声数据
本文基于kitti数据集(只使用了XYZ数据),尝试了pcl常用的一些滤波方法,记录了一下关键代码和演示效果
直通滤波器(passthrough)
直通滤波器非常直观,就是从坐标范围上筛选点云
直通滤波器对象的创建
// 设置滤波器对象
pcl::PassThrough<pcl::PointXYZ> pass;
// 设置输入点云
pass.setInputCloud(cloud);
// 设置过滤的字段,x方向
pass.setFilterFieldName("x");
// 设置滤波范围
pass.setFilterLimits(0.0, 9.0);
// 设置保留过滤/滤出数据
pass.setFilterLimitsNegative(true);
// 执行滤波,写入输出
pass.filter(*cloud_filtered);
效果还是很明显滴
使用VoxelGrid滤波器对点云进行下采样
Voxelgrid就是体素滤波器,非常常用,因为采样速度较快,精度较高
PCL实现的Voxelgrid类通过输入的点云数据创建一个三维体素栅格(可把体素栅格想象为微小的空间三维立方体的集合),然后在每个体素(即三维立方体)内用体素中所有点的重心来近似显示体素中的其他点,这样该体素内所有点就用一个重心点来表示,得到过滤后的点云。
咳咳,简而言之,就是把点云划分成n多个三维立体小方格(可自定义尺寸),每个小方格里的点取一个重心保留(重心就是方格内所有坐标求均值),这样就进行了下采样操作
话不多说,来看代码
// 创建滤波器对象
pcl::VoxelGrid<pcl::PointXYZ> sor;
// 输入点云
sor.setInputCloud(cloud);
// 设置三维栅格的大小
sor.setLeafSize(0.3, 0.3, 0.3);
// 滤波,写入
sor.filter(*cloud_filtered);
非常的通俗易懂,感谢pcl库哈
来看下效果
统计滤波器移除离群点(StatisticalOutlierRemoval)
这个名字真是非常的长了
由于激光扫描的原因,点云数据里密度不太均匀,并且,由于测量的误差,会产生稀疏的离群点,使效果更糟。
统计滤波器的方法大致如下:对每个点的邻域进行一个统计分析,可以得到该点到它所有临近点的平均距离。假设得到最后所有点的数据是高斯分布,其形状由均值和标准差决定,平均距离在标准范围(以均值和标准差定义)之外的,视为离群点
代码如下
// 创建滤波器
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;