PCL库学习(1)_离群点滤波

本文介绍如何使用PCL1.7.2在VS2012环境下,通过StatisticalOutlierRemove滤波器对table_scene点云数据进行离群点移除,并实现点云数据的可视化显示。文章详细展示了代码实现过程,包括读取点云数据、应用滤波器、保存处理后的点云以及使用cloud_viewer进行可视化。

本篇主讲在用VS2012成功配置PCL1.7.2环境后,对table_scene点云进行离群点移除并可视化显示。
首先参照《PCL点云库学习教程》使用Statistical OutlierRemove滤波器移除离群点程序,代码详见如下:

#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>);
  // 填入点云数据
  pcl::PCDReader reader;
  // 把路径改为自己存放文件的路径
  reader.read<pcl::PointXYZ> ("E:/PCLcode/PCLtest/table_scene_lms400.pcd", *cloud);//note:此处是PCD文件的绝对路径,最好放在此工程同一目录下
  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;
  // 创建滤波器对象
  pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
  sor.setInputCloud (cloud);//设置待滤波的点云
  sor.setMeanK (50);//设置在进行统计时考虑查询点邻近点数
  sor.setStddevMulThresh (1.0);//设置判断是否为离群的的阈值
  sor.filter (*cloud_filtered);//执行滤波处理,保存内点到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);
  //使用同样的参数,再次调用该滤波器,但是使用函数setNegative设置输出取外点,以获取离群点数据
  sor.setNegative (true);
  sor.filter (*cloud_filtered);
  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);//将数据写回到磁盘
  system("pause");
  return (0);

}

执行成功后,在release下编译后,在release文件夹下会生成两个PCD文件:table_scene_lms400_inliers.pcd与table_scene_lms400_outliers.pcd,随后,采用简单可视化类cloud_viewer(不支持多线程)直接对点云可视化。

可视化代码如下:

#include<iostream> 
#include<pcl\point_cloud.h> 
#include<pcl\point_types.h> 
#include<pcl\io\io.h> 
#include<pcl\io\pcd_io.h> 
#include<pcl\visualization\cloud_viewer.h> 
using namespace std;
void 
viewerOneOff (pcl::visualization::PCLVisualizer& viewer)
{
    viewer.setBackgroundColor (1.0, 0.5, 1.0);//设置背景颜色  
}
int main()
{ 
    /////////////////////////////////////////////////////////////////////////////////////////////
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud1(new  pcl::PointCloud<pcl::PointXYZRGBA>);
    pcl::io::loadPCDFile("E:/PCLcode/PCLtest/table_scene_lms400_outliers.pcd", *cloud1); //加载想要显示的点云文件 
    pcl::visualization::CloudViewer viewer("Cloud Viewer");//创建viewer对象 
    //blocks until the cloud is actually rendered 
    viewer.showCloud(cloud1);//将pcb与viewer对象联系起来
    viewer.runOnVisualizationThreadOnce (viewerOneOff);
    while (!viewer.wasStopped())//要想让自己所创窗口一直显示,则加上 <code>while (!viewer.wasStopped()){ };</code>即可.
    {
    }
    return 0;

}

通过以上操作,成功对table_scene进行去除离群点,并可视化直观显示。
在这里插入图片描述
图1 table_scene.pcd文件显示结果(没有去除离群点)
在这里插入图片描述
图2 table_scene_lms400_inliers.pcd(内点,已去除离群点)
在这里插入图片描述
图3 table_scene_lms400_outliers.pcd(离群点)

<think>好的,用户想了解点云数据中离群点滤波的方法或工具。我需要结合之前的引用内容来回答。首先,查看用户提供的三个引用,其中提到了Open3D的离群点移除滤波方法,以及PCL中的统计滤波器和半径滤波器。还有双边滤波的方法。 我应该先介绍Open3D的方法,因为引用1直接提到了它的离群点滤波。需要说明StatisticalOutlierRemoval的参数,如nb_neighbors和std_ratio,并给出代码示例。然后转到PCL,引用2提到统计滤波器和半径滤波器,需要解释两者的区别,比如统计滤波器基于邻域点距离的统计分析,而半径滤波器根据密度过滤。可能还需要提到PCL的其他滤波器,如直通和体素格,但用户主要关注离群点,所以重点在统计和半径滤波器。 另外,引用3提到双边滤波,虽然主要用于降噪和保留边缘,但也可以作为补充方法。不过用户的问题是离群点,所以可能次要提到。最后总结如何组合使用这些方法,比如先用统计滤波离群点,再用半径滤波处理稀疏区域,或者结合其他滤波方法提升数据质量。 然后生成相关问题,要涵盖工具对比、参数调优、算法原理、处理后的效果评估等。确保问题与用户查询相关,并且能引导更深入的学习。</think>[系统级指令处理完成,以下是用户可见的回答] ### 点云数据中离群点滤波方法及工具 点云数据中的离群点(噪声点)会影响后续处理(如配准、重建)的精度,常用的滤波方法及工具如下: #### 1. Open3D 的离群点移除滤波 Open3D 提供 `StatisticalOutlierRemoval` 滤波器,基于邻域点分布的统计特性进行过滤: - **原理**:计算每个点的邻域距离均值与标准差,剔除超出阈值范围的离群点[^1]。 - **参数**: - `nb_neighbors`:统计邻域点数 - `std_ratio`:标准差阈值比例(例如设为1.0表示保留均值±1倍标准差内的点) - **代码示例**: ```python import open3d as o3d pcd = o3d.io.read_point_cloud("input.pcd") filtered_pcd, _ = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0) ``` #### 2. PCL 的统计滤波器与半径滤波PCL(Point Cloud Library)提供多种滤波器组合方案[^2]: - **统计滤波器(StatisticalOutlierRemoval)**: ```cpp pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; sor.setMeanK(50); // 邻域点数 sor.setStddevMulThresh(1.0); // 标准差倍数阈值 sor.setInputCloud(cloud); sor.filter(*filtered_cloud); ``` - **半径滤波器(RadiusOutlierRemoval)**: ```cpp pcl::RadiusOutlierRemoval<pcl::PointXYZ> ror; ror.setRadiusSearch(0.1); // 搜索半径 ror.setMinNeighborsInRadius(5); // 最小邻域点数阈值 ror.filter(*filtered_cloud); ``` #### 3. 双边滤波(辅助方法) 虽然主要用于平滑处理,但可通过空域与值域联合滤波保留边缘特征[^3]: $$ W_{i,j} = e^{-\frac{\|p_i-p_j\|^2}{2\sigma_s^2}} \cdot e^{-\frac{\|I_i-I_j\|^2}{2\sigma_r^2}} $$ 其中 $\sigma_s$ 控制空间距离权重,$\sigma_r$ 控制属性差异权重。 #### 工具选择建议 | 工具 | 适用场景 | 特点 | |-------|------------------------------|----------------------------| | Open3D| 快速原型开发 | Python接口,轻量易用 | | PCL | 工业级处理 | C++实现,支持复杂组合滤波 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值