pclpy SOR去除异常值-统计滤波
一、算法原理
1.背景
激光扫描通常会生成不同点密度的点云数据集。此外,测量误差会导致稀疏的异常值,从而进一步破坏测量结果。这使得局部点云特征的估计变得复杂,例如表面法线或曲率变化,导致计算错误,进而可能导致点云配准失败。其中一些不规则异常值可以通过对每个点的邻域进行统计分析来解决,并修剪不符合特定标准的那些。我们使用基于输入数据集中点到邻居距离分布的计算移除稀疏异常值。对于每个点,我们计算从它到所有邻居的平均距离。通过假设结果分布是具有均值和标准差的高斯分布,
下图显示了稀疏异常值分析和去除的效果:原始数据集显示在左侧,而结果数据集显示在右侧。该图显示了过滤前后点邻域中的平均 k 最近邻距离。
2.原理
去除分布稀疏的点,对于点云中的每个点,计算到最近k个点的平均距离,然后假设结果构成高斯分布,过滤平均距离大于标准差的点。
参数
sor.setMeanK(k)
:最近k个点
sor.setStddevMulThresh(阈值)
:基于标准差的阈值,越小滤除点越多
二、代码
from pclpy import pcl
if __name__ == '__main__':
# 读取点云数据
cloud = pcl.PointCloud.PointXYZ()
reader = pcl.io.PCDReader() # 设置读取对象
reader.read('res/table_scene_lms400.pcd', cloud) # 读取点云保存在cloud中
print('去除前点云数目:', cloud.size())
# 设置处理后点云的保存
cloud_filtered_inliers = pcl.PointCloud.PointXYZ() # 保存索引后的点云(内点)
cloud_filtered_outliers = pcl.PointCloud.PointXYZ() # 去除的点云噪点(外点)
# 创建sor滤波器
sor = pcl.filters.StatisticalOutlierRemoval.PointXYZ() # 创建sor处理对象
sor.setInputCloud(cloud) # 将cloud处理
sor.setMeanK(50) # 每个点要分析的邻居数
sor.setStddevMulThresh(1.0) # 距离查询点的平均距离大于1个标准差的点都将被标记为离群值并删除
sor.filter(cloud_filtered_inliers) # sor处理后的点云保存在这里(内点)
print('内点数目:', cloud_filtered_inliers.size())
sor.setNegative(True) # 获得去除的点噪点(外点)
sor.filter(cloud_filtered_outliers) # 降去除的点保存在 cloud_filtered_outliers
print('外点数目:', cloud_filtered_outliers.size())
# 可视化点云
viewer = pcl.visualization.PCLVisualizer("3D viewer") # 建立一个可视化对象,窗口名 3D viewer
single_color = pcl.visualization.PointCloudColorHandlerCustom.PointXYZ(cloud, 0.0, 255.0, 0.0) # 设置点云颜色(绿色)
viewer.addPointCloud(cloud_filtered_outliers, single_color) # 将颜色和点云数据添加到可刷对象中
while not viewer.wasStopped(): # 展示可视化对象
viewer.spinOnce(10)
三、结果
1.原点云
2.sor处理后的点云(内点)
3.sor处理后的点云(外点)
四、相关数据
测试数据链接:https://pan.baidu.com/s/1am-4qlxuX_l6uoDeIbpPrA
提取码:ffs2