为了在每帧点云中滤除噪声点,选择了半径滤波器,也用高斯滤波器测试过,可是没有半径效果好,这里记录下在 octomap_server 中增长半径滤波器的步骤,并在 launch 中配置滤波器参数。html
放一张汇报用的 PPT 截图:函数
原理很简单就是判断一个点云周围(半径 R)有没有足够多(K)的邻居点,若是没有就删除这个点,不然就保留。学习
我通常学习技术喜欢到官网看最原始的教程:Removing outliers using a Conditional or RadiusOutlier removal,这个教程介绍了半径滤波器(我不清楚中文名到底叫什么滤波器)的基本用法:测试
#include <pcl/point_types.h> #include <pcl/filters/radius_outlier_removal.h> // 输入待滤波的原始点云指针 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); // 保存滤波后的点云指针 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>); // 建立滤波器对象 pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem; // 设置要滤波的点云 outrem.setInputCloud(cloud); // 设置滤波半径 outrem.setRadiusSearch(0.8); // 设置滤波最少近邻数 outrem.setMinNeighborsInRadius (2); // 执行半径滤波 outrem.filter (*cloud_filtered);
若是第一次使用 PCL 的滤波器,能够把这个教程本身运行一遍,我以前运行过了,此次就不贴代码了,下面分享下我在实际项目中若是使用这个半径滤波器对个人 octomap_server 构建的八叉树地图进行滤波。指针
半径滤波器有 2 个参数:滤波半径和半径内部邻居数,注意数据类型调试
// 滤波半径 double m_outrem_radius; // 半径内的邻居数 int m_outrem_neighbors;
在构造函数初始化列表中初始化:code
OctomapServer::OctomapServer(const ros::NodeHandle private_nh_, const ros::NodeHandle &nh_) : ..., m_outrem_radius(-std::numeric_limits<double>::max()), m_outrem_neighbors(-std::numeric_limits<int>::max()), ...
从 launch 中读取启动参数:server
// add outrem filter m_nh_private.param("outrem_radius", m_outrem_radius, m_outrem_radius); m_nh_private.param("outrem_neighbors", m_outrem_neighbors, m_outrem_neighbors);
在 InsertPointCloudCallBack 函数的 PassThough 前执行半径滤波,即对每一帧点云在构建八叉树地图前进行滤波,主要是为了去掉单独的离群点:xml
// 对一帧 pc 点云进行半径滤波 pcl::RadiusOutlierRemoval<pcl::PointXYZRGB> outrem; // 这里须要传递指针,由于个人 pc 不是指针,因此这里作了 makeShared outrem.setInputCloud(pc.makeShared()); // 设置滤波半径,这里设置为 1m outrem.setRadiusSearch(m_outrem_radius); // 设置滤波近邻数,这里设置为 10 个 outrem.setMinNeighborsInRadius (m_outrem_neighbors); // 执行滤波 outrem.filter(pc);
<param name = "outrem_radius" type = "double" value = "1.0"> <param name = "outrem_neighbors" type = "int" value = "10">
这样之后就能够从 launch 中直接配置滤波器的参数了,不用每次修改再从新编译,这样调试起来很是方便。htm
这是原始地图,15cm 分辨率,红框内部有不少单个的点:
这是滤波后的效果,滤波半径 1m,近邻点 10 个:
效果仍是能够的,但愿能对你有帮助,若是使用其余的滤波器,按照官方的教程来就好了,掌握学习方法才是最重要的:)