离群点移除 -理解
稀疏离群值的消除基于输入数据集中点到邻居距离的分布的计算。对于每个点,我们计算从它到所有相邻点的平均距离。通过假设结果分布是具有均值和标准差的高斯分布,可以将其平均距离在由全局距离均值和标准差定义的区间之外的所有点视为离群值并从数据集中进行修剪。 下图显示了稀疏离群值分析和删除的效果:原始数据集显示在左侧,结果数据集显示在右侧。数据集图显示了滤波前后每个点的邻域中平均K最近邻距离
接下来,使用StatisticalOutlierRemoval(统计学离群点移除过滤器)移除噪点。
#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <iostream>
#include <vector>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
main (int argc, char **argv)
{
ros::init (argc, argv, "pcl_create");
ros::NodeHandle nh;
ros::Publisher pcl_pub = nh.advertise<sensor_msgs::PointCloud2> ("pcl_output", 1);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud3 (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCLPointCloud2 cloud1;
sensor_msgs::PointCloud2 output;
pcl::io::loadPCDFile("/home/zjh/cloud_test/table_scene_lms400.pcd",cloud);
pcl::fromPCLPointCloud2 (cloud,*cloud3);
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud (cloud3);
// 创建过滤器,每个点分析计算时考虑的最近邻居个数为50个;
// 设置标准差阈值为1,这意味着所有距离查询点的平均距离的标准偏差均大于1个标准偏差的所有点都将被标记为离群值并删除。
// 计算输出并将其存储在cloud_filtered中
// 设置平均距离估计的最近邻居的数量K
sor.setMeanK (50);
// 设置标准差阈值系数
sor.setStddevMulThresh (1.0);
// 执行过滤
sor.filter (*cloud_filtered);
std::cerr << "Cloud after filtering: " << std::endl;
std::cerr << *cloud_filtered << std::endl;
pcl::toROSMsg(*cloud_filtered, output);
output.header.frame_id = "odom";
ros::Rate loop_rate(1);
while (ros::ok()) {
pcl_pub.publish(output);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
来对比一下效果非常的明显
移除之前:
移除之后:
干净多了。