【1】RadiusOutlierRemova移除离群点
原理:删除在输入的点云一定范围内没有达到足够多领域的所有数据点。
通俗的讲:就是以一个点p给定一个范围r,领域点要求的个数为m,r若在这个点的r范围内部的个数大于m则保留,小于m则删除。
【2】ConditionalRemoval移除离群点
原理:可以一次删除满足对输入的点云设定的一个或者多个条件指标的所有数据点。
通俗的讲:ConditionalRemova滤波器就是设定几个条件,每个维度上面的限制条件。
【3】实例
//移除离群点
#include "pch.h"
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>
int
main666(int argc, char** argv)
{
if (argc != 2)
{
std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
exit(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 = 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);
}
if (strcmp(argv[1], "-r") == 0) {
// RadiusOutlierRemoval滤波器设定滤波器的半径范围和滤波的点数
// RadiusOutlierRemoval创建滤波器 半径距离范围
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
outrem.setInputCloud(cloud); // 载入点云
outrem.setRadiusSearch(0.8); // 设定滤波半径
outrem.setMinNeighborsInRadius(2); // 设定滤波半径范围内部的最低点云个数,小于次数的点被滤除
// 应用滤波器
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(range_cond);
condrem.setInputCloud(cloud);
condrem.setKeepOrganized(true);//设置保持点云的结构
// 应用滤波器
condrem.filter(*cloud_filtered);
}
else {
std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
exit(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);
}