為了在每幀點云中濾除噪聲點舰攒,選擇了半徑濾波器败富,也用高斯濾波器測試過,但是沒有半徑效果好摩窃,這里記錄下在 octomap_server 中增加半徑濾波器的步驟兽叮,并在 launch 中配置濾波器參數(shù)。
一偶芍、半徑濾波器基本原理
放一張匯報用的 PPT 截圖:
原理很簡單就是判斷一個點云周圍(半徑 R)有沒有足夠多(K)的鄰居點充择,如果沒有就刪除這個點德玫,否則就保留匪蟀。
二、基本用法
我一般學習技術喜歡到官網(wǎng)看最原始的教程: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>);
// 創(chuàng)建濾波器對象
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
// 設置要濾波的點云
outrem.setInputCloud(cloud);
// 設置濾波半徑
outrem.setRadiusSearch(0.8);
// 設置濾波最少近鄰數(shù)
outrem.setMinNeighborsInRadius (2);
// 執(zhí)行半徑濾波
outrem.filter (*cloud_filtered);
如果第一次使用 PCL 的濾波器材彪,可以把這個教程自己運行一遍,我之前運行過了琴儿,這次就不貼代碼了段化,下面分享下我在實際項目中如果使用這個半徑濾波器對我的 octomap_server 構建的八叉樹地圖進行濾波。
三造成、給我的地圖濾波
3.1 定義半徑濾波器參數(shù)
半徑濾波器有 2 個參數(shù):濾波半徑和半徑內部鄰居數(shù)显熏,注意數(shù)據(jù)類型
// 濾波半徑
double m_outrem_radius;
// 半徑內的鄰居數(shù)
int m_outrem_neighbors;
在構造函數(shù)初始化列表中初始化:
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 中讀取啟動參數(shù):
// 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);
3.2 執(zhí)行半徑濾波
在 InsertPointCloudCallBack 函數(shù)的 PassThough 前執(zhí)行半徑濾波,即對每一幀點云在構建八叉樹地圖前進行濾波晒屎,主要是為了去掉單獨的離群點:
// 對一幀 pc 點云進行半徑濾波
pcl::RadiusOutlierRemoval<pcl::PointXYZRGB> outrem;
// 這里需要傳遞指針喘蟆,因為我的 pc 不是指針,所以這里做了 makeShared
outrem.setInputCloud(pc.makeShared());
// 設置濾波半徑鼓鲁,這里設置為 1m
outrem.setRadiusSearch(m_outrem_radius);
// 設置濾波近鄰數(shù)蕴轨,這里設置為 10 個
outrem.setMinNeighborsInRadius (m_outrem_neighbors);
// 執(zhí)行濾波
outrem.filter(pc);
3.3 在 launch 中配置半徑濾波器參數(shù)
<param name = "outrem_radius" type = "double" value = "1.0">
<param name = "outrem_neighbors" type = "int" value = "10">
這樣以后就可以從 launch 中直接配置濾波器的參數(shù)了,不用每次修改再重新編譯骇吭,這樣調試起來非常方便橙弱。
3.4 濾波結果
這是原始地圖,15cm 分辨率燥狰,紅框內部有很多單個的點:
這是濾波后的效果棘脐,濾波半徑 1m,近鄰點 10 個:
效果還是可以的龙致,希望能對你有幫助蛀缝,如果使用其他的濾波器,按照官方的教程來就行了净当,掌握學習方法才是最重要的:)