激光扫描可以生成很多点云的数据集。并且,测量误差会导致一些稀疏的异常值使得结果更差。这使得局部点云特征估计变得更加的复杂,产生一些错误的值,使得点云的识别失败。有些不规则的数据可以通过数理统计的方法来消除。我们稀疏异样消除是以计算输入集的点的近邻分布来进行的。我们假设分布是标准正太分布,所有在分布区间外的点都被当成异常点。下面的图展示了稀疏异常分析与消除,原来的数据集在左边,结果在右边。下面的图显示了在滤波之前的K个最近邻的平均距离。
下面是代码
#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>);// Fill in the cloud datapcl::PCDReader reader;// Replace the path below with the path where you saved your filereader.read<pcl::PointXYZ> ("table_scene_lms400.pcd", *cloud);std::cerr << "Cloud before filtering: " << std::endl;std::cerr << *cloud << std::endl;// Create the filtering objectpcl::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); }
我们创建了一个pcl::StatisticalOutlierRemoval这个滤波器。每个点的近邻分析的数量被设置为50,标准差是1.这意味着,只要有一个点的距离大于1个标准差的平均距离,这个点就会被当成异样点并被去除。
// Create the filtering objectpcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;sor.setInputCloud (cloud);sor.setMeanK (50);sor.setStddevMulThresh (1.0);sor.filter (*cloud_filtered);
并把正常的点存储到磁盘里面
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);