点云滤波---统计滤波器

适用对象

统计滤波器主要用于滤除点云中的离群点(离群点往往由测量噪声引入)。
激光扫描通常生成具有不同点密度的点云数据集。此外,测量误差会导致稀疏异常值,从而进一步破坏点云的表达准确性。使得局部点云特征(例如表面法线或曲率变化)的估计变得非常复杂,这往往导致错误的估计结果,进而导致点云的高层应用表现不佳。

工作原理

明显离群点的特征是在空间中分布稀疏,可以理解为:每个点都表达一定信息量,某个区域点越密集则可能信息量越大。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离,(假设得到的结果是一个高斯分布,其形状是由均值和标准差决定),那么平均距离在标准范围之外的点,可以被定义为离群点并从数据中去除。给定均值与方差,可剔除方差在3σ之外的点。

PCL核心代码实现

pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;   //创建统计滤波器对象 
sor.setInputCloud(pointCloud_raw);         			 //设置输入的点云
sor.setMeanK(50);                 					 //设置KNN的k值
sor.setStddevMulThresh(1.0);      				     //设置标准偏差乘数为1.0
sor.filter(*pointCloud_filter);          			 //执行滤波
//说明:设置标准偏差乘数为1.0,意味着1个标准差以上就是离群点
//即那些距离大于(平均距离+或者-一个标准偏差)的点将被标记为离群值并被删除。
//根据高斯分布的数学表达,均值的一个标准差之内的分布可以达到总体的95%。
//注意:这里的平均距离和标准差、方差都可以由输入的点云数据集计算出来。

完整代码:

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>

int main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);

  // Fill in the cloud data
  pcl::PCDReader reader;
  // Replace the path below with the path where you saved your file
  reader.read<pcl::PointXYZ> ("table_scene_lms400.pcd", *cloud);

  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;

  // Create the filtering object
  pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
  sor.setInputCloud (cloud);
  sor.setMeanK (50);
  sor.setStddevMulThresh (1.0);
  sor.filter (*cloud_filtered);

  std::cerr << "Cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;

  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("table_scene_lms400_inliers.pcd", *cloud_filtered, false);

  sor.setNegative (true);
  sor.filter (*cloud_filtered);
  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);

  return (0);
}

测试的时候,需要先下载table_scene_lms400.pcd

参考资料

Removing outliers using a StatisticalOutlierRemoval filter

### 点云滤波技术概述 点云滤波是一项重要的点云预处理技术,其目的是通过去除噪声、平滑表面以及优化数据结构来提高点云的质量[^2]。这项技术对于后续的点云分析和建模至关重要,因为它直接影响到最终的结果精度。 #### 点云为何需要滤波点云通常来源于激光扫描仪或其他三维传感器,在采集过程中可能会受到多种因素的影响而引入噪声或异常点。这些干扰可能来自环境反射、设备误或者目标物体本身的复杂性。因此,为了获得更精确的数据表示并减少冗余信息,有必要对原始点云进行滤波处理[^1]。 #### 主要的点云滤波方法 以下是几种常用的点云滤波方法及其特点: - **直通滤波 (Pass-through Filter)** 这种方法通过对某一维度设置阈值范围来筛选符合条件的点,适用于剔除不需要的空间区域内的点云数据。 - **体素滤波 (Voxel Grid Downsample)** 将空间划分为多个小立方体(即体素),并对每个体素中的点取平均值或者其他策略保留代表性的点,从而达到降采样的效果。 - **统计滤波 (Statistical Outlier Removal, SOR)** 利用统计学原理检测偏离正常分布的离群点,并将其移除。这种方法特别适合于清理随机分布型噪音^。 - **条件滤波 (Conditional Filtering)** 根据特定几何约束条件过滤掉不符合规则的点,例如高度过大等情况下的地面分类应用。 - **半径滤波 (Radius Outlier Removal)** 定义一个邻域搜索半径,如果某个点在其范围内找到少于指定数量邻居,则认为该点为孤立点并删除之。 除了上述经典算法外,还有基于数学形态学的操作也可用于点云滤波任务中[^3]。这类方法主要依赖开闭运算等基本概念完成去噪和平滑等功能[^4]。 --- ### 统计滤波的具体实现 以 PCL 库为例展示如何利用 C++ 或 Python 编程语言实现简单的统计滤波过程如下所示: ```cpp // 使用PCL库实现C++版本的SOR滤波器 #include <pcl/io/pcd_io.h> #include <pcl/filters/statistical_outlier_removal.h> int main() { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("input_cloud.pcd", *cloud); pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; sor.setInputCloud(cloud); sor.setMeanK(50); // 设置考虑最近邻的数量 sor.setStddevMulThresh(1.0); // 设定标准偏倍数阈值 sor.filter(*cloud); pcl::io::savePCDFileASCII("output_cloud.pcd", *cloud); } ``` 同样也可以采用Python脚本快速测试相同逻辑的功能模块: ```python import numpy as np import open3d as o3d def statistical_filter(pcd, nb_neighbors=20, std_ratio=2.0): cl, ind = pcd.remove_statistical_outlier(nb_neighbors=nb_neighbors, std_ratio=std_ratio) return cl.select_by_index(ind) if __name__ == "__main__": input_pcd = o3d.io.read_point_cloud("input_cloud.ply") filtered_pcd = statistical_filter(input_pcd) o3d.visualization.draw_geometries([filtered_pcd]) ``` 以上两段代码分别展示了两种不同编程环境下执行统计滤波的方式,其中参数`setMeanK()` 和 `remove_statistical_outlier()` 控制着近邻数目与容忍度的选择,合理调整它们能够有效改善滤波性能。 --- ### 数学形态学滤波简介 另一种值得注意的方法是基于数学形态学理论设计出来的点云滤波方案。此方法借助集合论的思想定义了一些基础算子如腐蚀(Erosion)、膨胀(Dilation),并通过组合形成更加复杂的变换形式——开启(Opening)/关闭(Closing)。下面给出一段MATLAB伪代码片段说明其实现思路: ```matlab % MATLAB实现简单形态学开操作 function output = morphological_opening(pointCloud, structElementSize) se = strel('disk', structElementSize); % 创建圆形结构元 erodedCloud = imerode(pointCloud, se); % 腐蚀阶段 dilatedCloud = imdilate(erodedCloud, se); % 膨胀恢复细节部分 output = dilatedCloud; % 返回结果 end ``` 这种技术尤其擅长应对那些具有明显边界特征的对象场景下产生的毛刺类缺陷修复工作。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值