PCL点云分割:Conditional Euclidean Clustering

背景:

pcl官方教程:http://www.pointclouds.org/documentation/tutorials/conditional_euclidean_clustering.php#conditional-euclidean-clustering


1.使用感受

这个算法实际就是region growing segmentation的扩展版。你可以先看看我的另一个文章,关于region growing segmentation的:https://blog.csdn.net/AmbitiousRuralDog/article/details/80267519。Conditional Euclidean Clustering实际就是放开那个蔓延的condition, 你可以写一个自己的conditional函数,如官方教程中的enforceIntensitySimilarity, enforceCurvatureOrIntensitySimilarity 还有customRegionGrowing。而且一些阈值你需要在你的conditional函数里设置好,你的conditional函数变成一个回调函数setConditionFunction的输入。至于调参的感受和我的那篇region growing segmentation的文章里说的一样,调参起来还是相对容易的。主要需要调节蔓延时候用到的阈值。

如果你对你的场景里的墙壁地板这些物体的点的数目有个先验的信息,你可以在用户setMaxClusterSize()来过滤掉他们。再用setMinClusterSize()来过滤一些噪音。还可以调用getRemoveCluster()来获取这些被过滤掉的点云。


2. 算法细节

为了了解设置这些参数,让我们来了解一下如何内部细节。从官方的介绍里,算法的流程是写的很仔细的。为了让你更直观的明白,我概括的来说,就是从曲率小的面播种,从种子的位置出发,开始往四周搜索点,然后比对点于点之间的法线/Intensity/Color/Curvature等的差距,如果差距小于阈值就视为同一个cluster。如果一个cluster无法再蔓延,在剩下的点云里再播种,然后继续重复直到遍历完毕。


3.调参

略。可以参考我的关于region growing segmentation的文章。

可以参考

https://github.com/PointCloudLibrary/pcl/blob/master/segmentation/include/pcl/segmentation/conditional_euclidean_clustering.h里面的参数解释。


4.跑数据集

本来我想跑自己的数据集的,但我发现我的数据集少了一个维度的信息:intensity。Intensity数据在我看看来就是,激光雷达发出激光打到物体后反射回来的激光强度。

那就跑跑他们的数据吧,同时在代码最底部加了可视化:

#include <pcl/visualization/cloud_viewer.h> 
  pcl::visualization::CloudViewer viewer ("Cluster viewer");
  viewer.showCloud(cloud_out);
  while (!viewer.wasStopped ())
  {
  }

效果:

效果可以说是666了。在大范围的室外场景里,小至人,大至楼层,都被分割出来了。

但是,因为它利用了intensity的信息,我就在想,没了这一维度的信息,仅仅靠法线变化量做蔓延,效果还能这么好吗。所以我就把intensity变化量的阈值调到很大很大,基本多大的相邻点intensity变化量都小于这个阈值,也就是说intensity不再影响分割了。然后再跑一次,效果如下:

这种情况下呢,效果就不好了。建筑与地面融为一体,建筑楼层之间不能分开。只有那些本身与其他点云不接壤的点云被分割出来了。可能是法线变化量的阈值卡的不够小,然后我就调小。最后发现无论调小还是调大都没有提升效果。


5. 总结

Conditional Euclidean Clustering是一个能让使用者自己定义conditional函数的区域蔓延算法。官方的代码在官方提供的数据集(<pcl::PointXYZI>格式的数据集)呈现的效果很好,但对于没有intensity这个维度的数据集表现的不好。

猜你喜欢

转载自blog.csdn.net/ambitiousruraldog/article/details/80278210