PCL_几种点云滤波方法
杉木~ 2020-01-15 20:11:29 1608 收藏 2
分类专栏: PCL学习
版权
PCL学习
专栏收录该内容
22 篇文章5 订阅
订阅专栏
通常点云数据很大,同时带有噪声和离群点,在点云分析之前需要先进行滤波处理,学习郭浩老师的点云处理,总结几种滤波方法。
1. 直通滤波器
// 创建滤波器对象
pcl::PassThrough
pass.setInputCloud (cloud);
pass.setFilterFieldName ("z");
pass.setFilterLimits (0.0, 1.0);
//pass.setFilterLimitsNegative (true);
pass.filter (*cloud_filtered);
1
2
3
4
5
6
7
2. VoxelGrid滤波器
创建三维体素栅格,将体素栅格内所有点的重心代替体素中其他点,实现下采样。
// 创建滤波器对象
pcl::VoxelGrid
sor.setInputCloud(cloud);
sor.setLeafSize(0.01f, 0.01f, 0.01f);
sor.filter(*cloud_filtered);
1
2
3
4
5
3.StatisticalOutlireRemoval滤波器
对每一个点的近邻进行一个统计分析,计算点到近邻点的距离,计算所有近邻点的平均距离,平均距离在标准范围之外的点被视为离群点。
// 创建滤波器对象
pcl::StatisticalOutlierRemoval
sor.setInputCloud (cloud);
sor.setMeanK (50);
sor.setStddevMulThresh (1.0);
sor.filter (*cloud_filtered);
1
2
3
4
5
6
4. 使用参数化模型投影点云
基于对模型的结构和尺寸等信息,选择特殊模型,如:球等,设置参数进行滤波。
(1)填充ModelCoefficients的值,该例中使用X-Y平面
//创建一个系数为(0,0,1,0)的平面
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
coefficients->values.resize(4);
coefficients->values[0] = coefficients->values[1] = 0;
coefficients->values[2] = 1.0;
coefficients->values[3] = 0;
1
2
3
4
5
6
(2)创建ProjectInliers对象,使用ModelCoefficients作为投影对象的模型参数
//创建滤波器对象
pcl::ProjectInliers
proj.setModelType(pcl::SACMODEL_PLANE);
proj.setInputCloud(cloud);
proj.setModelCoefficients(coefficients);
proj.filter(*cloud_projected);
1
2
3
4
5
6
5. ExtractIndices滤波器
基于某一分割算法提取点云的一个子集
(1)使用VoxelGrid滤波器对数据下采样,加快处理速度
// 创建滤波器对象:使用叶大小为1cm的下采样
pcl::VoxelGrid
sor.setInputCloud(cloud_blob);
sor.setLeafSize(0.01f, 0.01f, 0.01f);
sor.filter(*cloud_filtered_blob);
1
2
3
4
5
(2)参数化分割
(3)设置extraction filter实际参数
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
pcl::PointIndices::Ptr inliers(new pcl::PointIndices());
// 创建分割对象
pcl::SACSegmentation
// 可选
seg.setOptimizeCoefficients(true);
// 必选
seg.setModelType(pcl::SACMODEL_PLANE);
seg.setMethodType(pcl::SAC_RANSAC);
seg.setMaxIterations(1000);
seg.setDistanceThreshold(0.01);
// 创建滤波器对象
pcl::ExtractIndices
int i = 0, nr_points = (int)cloud_filtered->points.size();
// 当还有30%原始点云数据时
while (cloud_filtered->points.size() > 0.3 * nr_points)
{
// 从余下的点云中分割最大平面组成部分
seg.setInputCloud(cloud_filtered);
seg.segment(*inliers, *coefficients);
if (inliers->indices.size() == 0)
{
std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
break;
}
// 分离内层
extract.setInputCloud(cloud_filtered);
extract.setIndices(inliers);
extract.setNegative(false);
extract.filter(*cloud_p);
std::cerr << "PointCloud representing the planar component: " << cloud_p->width * cloud_p->height << " data points." << std::endl;
std::stringstream ss;
ss << "table_scene_lms400_plane_" << i << ".pcd";
writer.write
// 创建滤波器对象
extract.setNegative(true);
extract.filter(*cloud_f);
cloud_filtered.swap(cloud_f);
i++;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
需要将sensor_msgs::PointCloud2::Ptr改为pcl::PCLPointCloud2::Ptr;pcl::fromROSMsg()改为pcl::fromPCLPointCloud2();
6. ConditionalRemoval或RadiusOutlierRemoval类
ConditionalRemoval滤波器可以删除设定的一个或多个条件指标的所有数据点;
(1)创建条件限定对象;
(2)为限定对象添加比较算子;
(3)创建滤波器并用条件定义对象初始化;
// 创建环境
pcl::ConditionAnd
pcl::ConditionAnd
range_cond->addComparison(pcl::FieldComparison
pcl::FieldComparison
range_cond->addComparison(pcl::FieldComparison
pcl::FieldComparison
// 创建滤波器
pcl::ConditionalRemoval
condrem.setInputCloud(cloud);
condrem.setKeepOrganized(true);
// 应用滤波
condrem.filter(*cloud_filtered);
1
2
3
4
5
6
7
8
9
10
11
12
13
RadiusOutlinerRemoval滤波器删除搜索半径内不满足设定的近邻点数,可用于移除离群点。
(1)创建滤波器;
(2)设置搜索半径;
(3)设置查询点的近邻点数;
(4)执行条件滤波。
pcl::RadiusOutlierRemoval
// 创建滤波器
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(0.8);
outrem.setMinNeighborsInRadius(2);
// 应用滤波器
outrem.filter(*cloud_filtered);
1
2
3
4
5
6
7
7. CropHull滤波器
获取2D封闭多边形内部或者外部的点云
(1)设置2D封闭多边形顶点;
(2)使用ConvexHull类构造2D凸包;
(3)创建Crophull对象,滤波获取凸包范围内的点云。
pcl::PointCloud
boundingbox_ptr->push_back(pcl::PointXYZ(0.1, 0.1, 0));
boundingbox_ptr->push_back(pcl::PointXYZ(0.1, -0.1, 0));
boundingbox_ptr->push_back(pcl::PointXYZ(-0.1, 0.1, 0));
boundingbox_ptr->push_back(pcl::PointXYZ(-0.1, -0.1, 0));
boundingbox_ptr->push_back(pcl::PointXYZ(0.15, 0.1, 0));
pcl::ConvexHull
hull.setInputCloud(boundingbox_ptr);
hull.setDimension(2);
std::vector
pcl::PointCloud
hull.reconstruct(*surface_hull, polygons);
pcl::PointCloud
pcl::CropHull
bb_filter.setDim(2);
bb_filter.setInputCloud(cloud);
bb_filter.setHullIndices(polygons);
bb_filter.setHullCloud(surface_hull);
bb_filter.filter(*objects);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
杉木~
关注
————————————————
版权声明:本文为CSDN博主「杉木~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhan_zhan1/article/details/103991733