原理统计离群点移除 (Statistical Outlier Removal)是一种基于局部统计特征的点云去噪算法。该算法假设正常点与其邻居点的距离服从高斯分布而离群点噪声点则偏离这个分布。算法核心思想对于点云中的每个点计算其到K个最近邻点的平均距离。假设这些距离服从高斯分布通过计算全局距离的均值和标准差移除距离均值超过N倍标准差的点。算法详细流程邻域搜索对于点云中的每个点pip_ipi找到其K个最近邻点距离计算计算pip_ipi到每个邻居点的欧氏距离dijd_{ij}dij平均距离计算计算pip_ipi到所有邻居的平均距离μi1K∑j1Kdij\mu_i \frac{1}{K} \sum_{j1}^{K} d_{ij}μiK1∑j1Kdij全局统计计算所有点平均距离的全局均值μ\muμ和标准差σ\sigmaσ离群点判断对于每个点pip_ipi如果μiμα⋅σ\mu_i \mu \alpha \cdot \sigmaμiμα⋅σ则判定为离群点点云过滤移除所有被判定为离群点的点数学表达式点pip_ipi到邻居点pjp_jpj的距离dij∥pi−pj∥d_{ij} \|p_i - p_j\|dij∥pi−pj∥平均距离μi1K∑j1Kdij\mu_i \frac{1}{K} \sum_{j1}^{K} d_{ij}μiK1∑j1Kdij全局统计μ1N∑i1Nμi\mu \frac{1}{N} \sum_{i1}^{N} \mu_iμN1∑i1Nμiσ1N∑i1N(μi−μ)2\sigma \sqrt{\frac{1}{N} \sum_{i1}^{N} (\mu_i - \mu)^2}σN1∑i1N(μi−μ)2离群点条件μiμα⋅σ\mu_i \mu \alpha \cdot \sigmaμiμα⋅σ参数作用分析MeanK (K值)决定局部邻域的大小过小对噪声敏感可能将正常点误判为离群点过大计算量大可能忽略局部特征推荐值20-50根据点云密度调整StddevMulThresh (α值)控制离群点判定的严格程度值越小判定越严格移除更多点值越大判定越宽松保留更多点推荐值0.5-2.01.0为常用值算法特点统计鲁棒性基于统计方法对高斯噪声有很好的去除效果自适应阈值根据点云自身特征自动计算阈值局部敏感性考虑点的局部邻域特征计算复杂度需要KD树构建和邻域搜索复杂度为O(NlogN)O(N \log N)O(NlogN)算法优势自动阈值确定无需手动设置固定距离阈值保持几何特征主要移除孤立噪声点保留主体结构参数直观两个参数都有明确的物理意义适用范围广适用于各种类型的点云数据算法局限性密度敏感性对点云密度不均匀的情况效果不佳边界效应在物体边界处可能误判计算开销需要计算所有点的K近邻参数依赖性效果受K值和α值影响较大实现算法基本用法:pcl::StatisticalOutlierRemovalpcl::PointXYZsor;sor.setInputCloud(cloud);// 设置输入点云sor.setMeanK(50);// 设置邻居数量sor.setStddevMulThresh(1.0);// 设置标准差倍数阈值sor.filter(*cloud_filtered);// 执行滤波完整代码#includeiostream#includepcl/point_cloud.h#includepcl/point_types.h#includepcl/io/pcd_io.h#includepcl/filters/statistical_outlier_removal.h#includepcl/visualization/pcl_visualizer.hintmain(){// 1. 加载点云pcl::PointCloudpcl::PointXYZ::Ptrcloud(newpcl::PointCloudpcl::PointXYZ);if(pcl::io::loadPCDFilepcl::PointXYZ(02.pcd,*cloud)-1){std::cerr错误无法加载02.pcd文件std::endl;return-1;}std::cout加载点云成功点数: cloud-points.size()std::endl;// 2. 执行统计离群点移除pcl::PointCloudpcl::PointXYZ::Ptrfiltered(newpcl::PointCloudpcl::PointXYZ);pcl::StatisticalOutlierRemovalpcl::PointXYZsor;sor.setInputCloud(cloud);sor.setMeanK(50);// 考虑50个邻居点sor.setStddevMulThresh(1.0);// 标准差倍数阈值为1.0sor.filter(*filtered);std::cout统计离群点移除后点数: filtered-points.size()std::endl;std::cout移除离群点数量: cloud-size()-filtered-size()std::endl;// 3. 可视化pcl::visualization::PCLVisualizerviewer(filter);// 原始点云红色半透明viewer.addPointCloudpcl::PointXYZ(cloud,original);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,1.0,0.0,0.0,original);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,original);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,0.3,original);// 滤波后点云白色viewer.addPointCloudpcl::PointXYZ(filtered,filtered);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,1.0,1.0,1.0,filtered);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,3,filtered);while(!viewer.wasStopped()){viewer.spinOnce(100);}// 4. 保存结果pcl::io::savePCDFileASCII(filtered.pcd,*filtered);std::cout结果已保存到: filtered.pcdstd::endl;return0;}运行结果原始点数: 25799统计离群点移除后点数: 21988移除离群点数量: 3811
统计离群点滤波算法实现
原理统计离群点移除 (Statistical Outlier Removal)是一种基于局部统计特征的点云去噪算法。该算法假设正常点与其邻居点的距离服从高斯分布而离群点噪声点则偏离这个分布。算法核心思想对于点云中的每个点计算其到K个最近邻点的平均距离。假设这些距离服从高斯分布通过计算全局距离的均值和标准差移除距离均值超过N倍标准差的点。算法详细流程邻域搜索对于点云中的每个点pip_ipi找到其K个最近邻点距离计算计算pip_ipi到每个邻居点的欧氏距离dijd_{ij}dij平均距离计算计算pip_ipi到所有邻居的平均距离μi1K∑j1Kdij\mu_i \frac{1}{K} \sum_{j1}^{K} d_{ij}μiK1∑j1Kdij全局统计计算所有点平均距离的全局均值μ\muμ和标准差σ\sigmaσ离群点判断对于每个点pip_ipi如果μiμα⋅σ\mu_i \mu \alpha \cdot \sigmaμiμα⋅σ则判定为离群点点云过滤移除所有被判定为离群点的点数学表达式点pip_ipi到邻居点pjp_jpj的距离dij∥pi−pj∥d_{ij} \|p_i - p_j\|dij∥pi−pj∥平均距离μi1K∑j1Kdij\mu_i \frac{1}{K} \sum_{j1}^{K} d_{ij}μiK1∑j1Kdij全局统计μ1N∑i1Nμi\mu \frac{1}{N} \sum_{i1}^{N} \mu_iμN1∑i1Nμiσ1N∑i1N(μi−μ)2\sigma \sqrt{\frac{1}{N} \sum_{i1}^{N} (\mu_i - \mu)^2}σN1∑i1N(μi−μ)2离群点条件μiμα⋅σ\mu_i \mu \alpha \cdot \sigmaμiμα⋅σ参数作用分析MeanK (K值)决定局部邻域的大小过小对噪声敏感可能将正常点误判为离群点过大计算量大可能忽略局部特征推荐值20-50根据点云密度调整StddevMulThresh (α值)控制离群点判定的严格程度值越小判定越严格移除更多点值越大判定越宽松保留更多点推荐值0.5-2.01.0为常用值算法特点统计鲁棒性基于统计方法对高斯噪声有很好的去除效果自适应阈值根据点云自身特征自动计算阈值局部敏感性考虑点的局部邻域特征计算复杂度需要KD树构建和邻域搜索复杂度为O(NlogN)O(N \log N)O(NlogN)算法优势自动阈值确定无需手动设置固定距离阈值保持几何特征主要移除孤立噪声点保留主体结构参数直观两个参数都有明确的物理意义适用范围广适用于各种类型的点云数据算法局限性密度敏感性对点云密度不均匀的情况效果不佳边界效应在物体边界处可能误判计算开销需要计算所有点的K近邻参数依赖性效果受K值和α值影响较大实现算法基本用法:pcl::StatisticalOutlierRemovalpcl::PointXYZsor;sor.setInputCloud(cloud);// 设置输入点云sor.setMeanK(50);// 设置邻居数量sor.setStddevMulThresh(1.0);// 设置标准差倍数阈值sor.filter(*cloud_filtered);// 执行滤波完整代码#includeiostream#includepcl/point_cloud.h#includepcl/point_types.h#includepcl/io/pcd_io.h#includepcl/filters/statistical_outlier_removal.h#includepcl/visualization/pcl_visualizer.hintmain(){// 1. 加载点云pcl::PointCloudpcl::PointXYZ::Ptrcloud(newpcl::PointCloudpcl::PointXYZ);if(pcl::io::loadPCDFilepcl::PointXYZ(02.pcd,*cloud)-1){std::cerr错误无法加载02.pcd文件std::endl;return-1;}std::cout加载点云成功点数: cloud-points.size()std::endl;// 2. 执行统计离群点移除pcl::PointCloudpcl::PointXYZ::Ptrfiltered(newpcl::PointCloudpcl::PointXYZ);pcl::StatisticalOutlierRemovalpcl::PointXYZsor;sor.setInputCloud(cloud);sor.setMeanK(50);// 考虑50个邻居点sor.setStddevMulThresh(1.0);// 标准差倍数阈值为1.0sor.filter(*filtered);std::cout统计离群点移除后点数: filtered-points.size()std::endl;std::cout移除离群点数量: cloud-size()-filtered-size()std::endl;// 3. 可视化pcl::visualization::PCLVisualizerviewer(filter);// 原始点云红色半透明viewer.addPointCloudpcl::PointXYZ(cloud,original);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,1.0,0.0,0.0,original);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,original);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,0.3,original);// 滤波后点云白色viewer.addPointCloudpcl::PointXYZ(filtered,filtered);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,1.0,1.0,1.0,filtered);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,3,filtered);while(!viewer.wasStopped()){viewer.spinOnce(100);}// 4. 保存结果pcl::io::savePCDFileASCII(filtered.pcd,*filtered);std::cout结果已保存到: filtered.pcdstd::endl;return0;}运行结果原始点数: 25799统计离群点移除后点数: 21988移除离群点数量: 3811