背景:
pcl官方教程:
http://www.pointclouds.org/documentation/tutorials/progressive_morphological_filtering.php#progressive-morphological-filtering
论文:http://users.cis.fiu.edu/~chens/PDF/TGRS.pdf
注:
这个算法本身用于处理高空获取的激光雷达数据,把地面与非地面的物体分割,来获取地貌3d地图的。我跑到数据与这类数据有一个明显的区别,就是x,y的范围与z的范围相差不多,而他们的高空数据,z的变化范围相比其他两个轴较小。但是我同样想试试它是否能帮我鲁棒地去除地面的点来达到分割物体和地面的效果。
还有,因为我的数据本来z轴不是对应着向上的方向,我还旋转点云来调整了一下。
1.使用感受
参数多,不看论文细节,无法调参数。如果参数不调好,算法耗时很长。对使用者极度不友好。
2.算法细节(从代码和论文里理解的)
首先根据数据里x, y的范围值,2d栅格化点云所占的空间。每个格子拥有0个或多个点,只是他们的高度(论文里的evaluation)不同。那么对于这个格子,如果0个点,用插值找一个点;如果多个点,把最低的点留下来。所以说,现在,每个格子都拥有一个格子内最低点(这里用lpt(lowest point)替代)。然后,
遍历每一行()
遍历每一个格子()
做一个“开”运算。开运算需要两个输入: 窗口大小(=窗口包括了四周哪几个的格子),以及窗口内lpt的高度合集。
那么开运算是什么呢,后面会解释。
把开运算的结果设置为以这一个格子为中心的“窗口内最低点”的高度值。
如果当前格子的lpt 高于这个“窗口内最低点”到一定程度(高度差距阈值), 这个格子原本包含的所有点(包括lpt)都
是非地面点,而这个"窗口内最低点"替代这个格子的lpt成为新的lpt。(你可以理解为,我先四周找找附近地区的洼点,如果我现在站的位置比这个洼点高了半层楼那么高,那么我这个地方不算是地面,那个洼点替代我的位置成为地面应该所在的位置。否则,我现在这个位置算是地面点)。
end
end
为了使算法里的“窗口内最低点”参考更大范围的局部点云(也就是我四周看的时候看更远一点),算法每运行完上面那个循环,就增大窗口大小和高度阈值一点,然后再运行循环。只要有一个循环里,一个格子的所有点被视为非地面点,那么这些点以后都是非地面点,以后的循环也不用遍历这个格子了。遍历若干次后,有些格子的lpt被窗口内最低点替代成为新的lpt了,有些没有,但它们现在都有它自己的lpt。最后的这些lpt合集就是地面点云。
2.1 开运算(谷歌上找资料自己理解的)
那么,开运算是什么鬼?其实很简单