對每個點的鄰域進行一個統計分析,並修剪掉一些不符合一定標準的點,稀疏離羣點移除方法基於在輸入數據中對點到臨近點的距離分佈的計算,對每一個點,計算它到它的所有臨近點的平均距離,假設得到的結果是一個高斯分佈,其形狀是由均值和標準差決定,平均距離在標準範圍之外的點,可以被定義爲離羣點並可從數據中去除。
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
int
main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
// 定義讀取對象
pcl::PCDReader reader;
// 讀取點雲文件
reader.read<pcl::PointXYZ> ("table_scene_lms400.pcd", *cloud);
std::cerr << "Cloud before filtering: " << std::endl;
std::cerr << *cloud << std::endl;
// 創建濾波器,對每個點分析的臨近點的個數設置爲50 ,並將標準差的倍數設置爲1 這意味着如果一
//個點的距離超出了平均距離一個標準差以上,則該點被標記爲離羣點,並將它移除,存儲起來
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; //創建濾波器對象
sor.setInputCloud (cloud); //設置待濾波的點雲
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::PCDWriter writer;
writer.write<pcl::PointXYZ> ("table_scene_lms400_inliers.pcd", *cloud_filtered, false);
sor.setNegative (true);
sor.filter (*cloud_filtered);
writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);
return (0);
}