使用ConditionalRemoval或RadiusOutlinerRemove移除离群点

ConditionalRemoval滤波器:可以一次删除满足对输入的点云设定的一个或多个条件指标的所有数据点。可以删除点云中不符合用户指定的一个或多个条件的数据点。
RadiusOutlineRemoval滤波器:可以删除在输入点云一定范围内没有达到至少近邻点要求的所有数据点。可以设定每个点的周围至少有足够多的近邻点,不满足这个要求的点就会被删除。

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>

int main(int argc,char ** argv) {
//确保输入的参数
if (argc!=2){
std::cerr<<"please specify command line arg '-r' or '-c'"<<std::endl;
return 0;
}
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

cloud->width=10;
cloud->height=1;
cloud->resize(cloud->height*cloud->width);

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);
}

//strcmp用于比较两个字符串s1和s2。如果s1<s2,返回值<0;如果s1=s2,返回值=0;如果s1>s2,则返回值>0
if (strcmp(argv[1],"-r")==0){
//如果输入的是-r,则执行下面的部分
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;//创建半径外点滤波器
outrem.setInputCloud(cloud);//设定输入点云
outrem.setRadiusSearch(0.8);//设定搜索半径
outrem.setMinNeighborsInRadius(2);//设定半径内的内点阈值,半径内的点如果小于阈值,则会被滤除
outrem.setKeepOrganized(false);
outrem.filter(*cloud_filtered);//输出处理结果
} else if(strcmp(argv[1],"-c")==0){

pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>);//创建条件定义对象
//为此条件对象添加比较算子
range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new pcl::FieldComparison<pcl::PointXYZ>("z",pcl::ComparisonOps::GT,0.0)));//添加在z字段上大于0的比较算子
range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new pcl::FieldComparison<pcl::PointXYZ>("z",pcl::ComparisonOps::LT,0.8)));//添加在z字段上小于0.8的比较算子

pcl::ConditionalRemoval<pcl::PointXYZ> condrem;//创建条件滤波器
condrem.setInputCloud(cloud);//设定输入点云
condrem.setCondition(range_cond);//设定条件
condrem.setKeepOrganized(false);//设定为true则保留点云的结构,否则不保留,默认为false
condrem.filter(*cloud_filtered);//输出结果
} else{
std::cerr<<"Please specify common line arg '-r' or '-c'"<<std::endl;
return 0;
}
std::cerr<<"Cloud before filtering: "<<std::endl;
for (size_t i = 0; i < cloud->points.size(); ++i) {
std::cerr<<" "<<cloud->points[i].x<<" "
<<cloud->points[i].y<<" "
<<cloud->points[i].z<<" "
<<std::endl;
}
std::cerr<<"Cloud after filtering: "<<std::endl;
for (size_t i = 0; i < cloud_filtered->points.size(); ++i) {
std::cerr<<" "<<cloud_filtered->points[i].x<<" "
<<cloud_filtered->points[i].y<<" "
<<cloud_filtered->points[i].z<<" "
<<std::endl;
}
return 0;
}

滤波结果演示(-c 保留了点云结构)

滤波结果演示(-c 未保留点云结构)

感谢您的阅读。 🙏 关于转载请看这里