PCL——Filter

博客介绍了PCL中需要进行点云滤波处理的情况,包括平滑数据密度、去除离群点、下采样和去除噪声等。还详细阐述了多种滤波器,如直通滤波器、双边滤波器、体素格滤波器等的原理和适用场景,为点云处理提供了多种方法。

PCL中总结了需要进行点云滤波处理的情况:
1、点云数据密度不规则需要平滑。
2、因为遮挡等问题造成离群点需要去除。
3、大量数据需要进行下采样。
4、噪声数据需要去除。

滤波器种类:
1、直通滤波;
2、双边滤波;
3、体素格滤波;
4、均匀采样;
5、增采样;
6、统计滤波;
7、半径滤波;
8、参数化模型投影点云;
9、ExtractIndices滤波;
10、ConditionalRemoval;
11、RadiusOutilerRemoval;
12、CropHull任意多边形内部点云提取;

直通滤波器

过滤掉在指定维度方向上取值不在给定阈值内的点

实现原理:
1、首先,指定一个维度以及该维度下的值域;
2、其次,遍历点云中的每个点,判断该点在指定维度上的取值是否在值域内,删除取值不在值域内的点;
3、最后,遍历结束,留下的点即构成滤波后的点云。

直通滤波器简单高效,适用于消除背景,消除高程等操作。

双边滤波器

核心思想:通过邻近采样点的加权平均来修正当前采样点的位置。同时也会有选择的剔除部分与当前采样点差异太大的相邻采样点,从而达到保持原有特征的目的。

滤波器核有两个函数生成:空间域核,值域核。

双边滤波可以保边去噪。双边滤波卷积计算两个权值,一个用于空间域核(高斯滤波),一个用于值域核,如果卷积在边缘(特征差异较大),值域核权值将会变小降低权重,抑制空间域核的作用。

体素格滤波器(VoxelGrid)

体素化网格实现下采样(减少点的数量),同时保持点云的形状特征。

实现原理:
(1)使用点云数据创建出相应的三维体素栅格(微小三维立方体的集合)
(2)然后在每个体素内,用体素内所有点的重心来近似代表其他的点(体素内的所有点用其重心点表示)

均匀采样(UniformSampling)

实现原理:和VoxelGrid滤波很相似,但是VoxelGrid滤波采用的是立方体体素重心,而UniformSamping取半径r的球体的重心。

增采样(UpSampling)

增采样是一种表面重建方法,当点云数据少时,增采样可以通过内插目前拥有的点云数据,恢复出原有的表面。

统计滤波器(StatisticOutilerRemoval)

使用统计分析技术来去除离群点。

核心思想:假设点云中所有的点与其最近的k个邻居点的平均距离满足高斯分布,那么,根据均值和方差可以确定一个距离阈值,当某个点与其最近k个点的平均距离大于这个阈值时,判定该点为离群点并去除。

实现原理:首先,遍历点云,计算每个点与其最近的k个邻居点之间的平均距离;其次,计算所有平均距离的均值μ与标准差σ,则距离阈值dmax可表示为dmax=μ+α×σ,α是一个常数,可称为比例系数,它取决于邻居点的数目;最后,再次遍历点云,剔除与k个邻居点的平均距离大于dmax的点。

参数化模型投影点云

将点云投影到参数化模型上(平面,球)。参数化模型由一组参数来设定。比如平面ax + by + cy + d = 0由四个参数所确定。PCL中有特意存储常见模型系数的数据结构。

ExtractIndices滤波器

基于某一分割算法提取点云中的一个子集。

RadiusOutilerRemoval

RadiusOutilerRemoval核心思想:删除输入点云一定范围内近邻点数量没有达到要求的点。

ConditionalRemoval

用于删除点云中不符合用户指定的一个或多个条件的点。

CropHull任意多边形内部点云提取

输入一个2D封闭的多边形和一个2D平面点云(这些平面点是多边形的顶点),然后提取属于该2D封闭的多边形内部或外部的点。

### PCL 点云处理使用教程 #### 安装配置环境 为了能够顺利使用PCL进行点云处理,首先需要安装并配置好开发环境。这通常涉及下载和编译PCL库以及设置IDE以便于编写和调试代码[^2]。 #### 创建基本的点云集 创建一个简单的点云集是学习PCL的第一步。可以通过读取文件或者直接在程序中生成一些随机分布的数据点作为起点。下面是一段用来初始化简单点云的例子: ```cpp #include <pcl/point_cloud.h> #include <pcl/point_types.h> int main () { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); // 添加几个测试点到cloud对象里去 cloud->width = 5; cloud->height = 1; cloud->points.resize(cloud->width * cloud->height); for (size_t i = 0; i < cloud->points.size (); ++i){ cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } } ``` 这段代码展示了如何声明一个新的`PointCloud<PointXYZ>`类型的指针变量,并向其中填充五个随机位置的空间坐标点[^1]。 #### 可视化点云数据 一旦有了点云数据之后,就可以考虑将其显示出来观察效果了。PCL自带了一个叫做`visualization`模块可以帮助完成这项工作。这里给出一段用于渲染上述创建好的点云实例的小例子: ```cpp #include <pcl/visualization/cloud_viewer.h> // ... 继续上面main函数... if (pcl::io::loadPCDFile<pcl::PointXYZ> ("test_pcd.pcd", *cloud) == -1){ //* 加载pcd文件失败 */ PCL_ERROR ("Couldn't read file test_pcd.pcd \n"); } // 显示窗口直到用户关闭它为止... pcl::visualization::CloudViewer viewer("Simple Cloud Viewer"); viewer.showCloud(cloud); while (!viewer.wasStopped ()) {} ``` 此片段说明了怎样加载外部`.pcd`格式文件并将结果显示在一个交互式的图形界面当中。 #### 数据预处理——半径异常移除过滤器 当面对实际场景下的复杂点云时,往往存在噪声干扰等问题影响后续分析质量。此时可以采用诸如半径异常移除这样的预处理手段来改善输入条件。具体做法如下所示: ```cpp #include <pcl/filters/radius_outlier_removal.h> //...继续之前的main() 函数体内部... pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem; outrem.setInputCloud(cloud); // 设置待处理的目标点集 outrem.setRadiusSearch(0.8); // 设定搜索邻域大小参数 outrem.setMinNeighborsInRadius (2); // 至少要有两个邻居才保留该点 outrem.filter (*cloud_filtered); // 执行滤波操作, 输出结果保存至cloud_filtered容器内 ``` 以上就是关于利用C++结合PCL库来进行基础级别的点云处理与可视化的入门指南[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值