参考:【PCL】—超体聚类点云分割算法详解
💥Voxel体素预了解:
图中是3D数据的不同表示类型:(a)点云(Point clouds);(b) 体素网格(Voxel grids); (c) 多边形网格(Polygon meshes); (d) 多视图表示(Multi-view representations)
其中:
a. 点云是三维空间(xyz坐标)点的集合。
b. 体素是3D空间的像素。量化的,大小固定的点云。每个单元都是固定大小和离散坐标。
c. mesh是面片的集合。
d. 多视图表示是从不同模拟视点渲染的2D图像集合。
💫为了解释体素网格(Voxel grid),首先我们要了解占据栅格地图(Occupancy Grid Map)
画一个二维网格,每个网格单元里有实体的话就为占据状态(1),空的话就为(0)
💫 体素就是固定分辨率的三维栅格地图。体素网格是固定分辨率的,与之对应可变分辨率的网格叫八叉树地图(Octomap)。
🕳总结:
体素网格是用固定大小的立方块作为最小单元,来表示三维物体的一种数据结构。
体素可以看成粗略版的点云。___________________________________________________________________________
一、超体素
💛超体素(supervoxel):是一种集合,集合的元素是“体”。本质是一个个的小方块。超体素是二维算法简单的扩展到三维的应用,这种方法不能应用在三维的无序空间中,只能在有规则的体素中起作用(超体素的局限性);本质上这种方法是对局部的一种总结,纹理,材质,颜色类似的部分会被自动的分割成一块,有利于后续识别工作。
💚三维体素分割的优点:直接作用于点云,比在投影图像平面上操作的现有方法有优势。最重要的是能够分割来自多种传感器捕获的点云数据,算法是具有通用性的。
💛超体聚类目的:不是分割出某种特定物体,而是对点云实施过分割(over segmentation),将场景点云化成很多小块,并研究每个小块之间的关系。
💗点云和图像不一样,其不存在像素邻接关系。所以,超体聚类之前,必须以八叉树对点云进行划分,获得不同点团之间的邻接关系。与图像相似点云的邻接关系也有很多,如面邻接,线邻接,点邻接。
💙PCL库中,超体素分割是一种基于点云体素的连通性分段算法。是一种应用在RGBD相机获取的点云数据中,通过使用基于三维空间的播种方法和使用颜色、几何特征的约束来实现点云的局部约束与聚类。就是把点云按照颜色和空间位置进行有意义的分割,将其分割成小块。
———————————————————————————————————————————
二、超体素聚类的实现步骤
解释:其过程和结晶类似。但不是水结晶成冰,而是盐溶液过饱和状态下的多晶核结晶。所有的晶核(seed)同时开始生长,最终填满整个空间,使物质具有晶体结构。
超体聚类是一种特殊的区域生长算法。和无限制的生长不同,需要规律的布置区域生长“晶核”。
晶核在空间中均匀分布。并指定晶核距离(Rseed),再指定粒子距离(Rvoxel),再指定最小晶粒(MOV),过小的晶粒需要融入最近的大晶粒。
Rseed——确定超级体素之间的距离
Rvoxel确定点云量化的分辨率
Rsearch用于确定是否有足够数量的种子占用体素。
有了晶粒和结晶范围之后,我们只需要控制结晶过程,就能将整个空间划分开了。结晶过程的本质就是不断吸纳类似的粒子(八分空间)。类似是一个比较模糊的概念,关于类似的定义有以下公式:
公式中的Dc表示颜色上的差异,Dn表示法线上的差异,Ds代表点距离上的差异。
w_*表示一系列权重,用于控制结晶形状。
在晶核周围寻找一圈,D最小的体素被认为是下一个“被发展的党员”。需要注意的是,结晶过程并不是长完一个晶核再长下一个,而是所有的晶核同时开始生长(虽然计算机计算时必然有先后,但从层次上来说是同时的),其生长顺序如下图所示:
接下来所有晶核继续公平竞争,发展第二个“党员”,以此循环。最终所有晶体应该几乎同时完成生长,整个点云也被晶格所分割开来,并且保证了一个晶包里的粒子都是类似的。
———————————————————————————————————————————
三、基于几何约束的超体素
💛点云体素连接性分割(VCCS)是一种从三维点云数据生成超像素和超体素的新方法。
💛优点:VCCS产生的超体素比最新的方法更符合物体边界,同时该方法实时性更好。VCCS使用k-means聚类的变体来生成其点的标记,有两个重要的约束:
1)超体素簇的种子是通过分割三维空间而不是投影到图像层面来实现的。这可以确保超体素是根据场景的几何属性均匀分布。
2)迭代聚类算法在考虑聚类点时,对被占用的体素进行严格的空间连通性。这意味着超体素不能在三维空间中连接不相交的边界,即使它们在投影平面上是相连的。
———————————————————————————————————————————
描述相邻体素是如何计算的 // 如何生成种子 // 如何滤波
如何对特征和距离进行聚类 // 如何迭代聚类算法增加空间连通性
———————————————————————————————————————————
四、晶体种子的生成与滤波
算法步骤:若干种子点云用于初始化超体素【将空间点云划分为一个具有选定分辨率Rseed的体素化网格,该Rseed的大小是明显高于Rvoxel。】————选择点云中最靠近我们种子体素中心的点作为种子候选点【知道候选点了,就要去除候选的噪声点种子】。。。这时候算法为每个种子建立了一个较小的搜索半径Rsearch,用来删除被覆盖面积不到Rsearch一半的点云种子。。。。图中绿色部分为过滤后的部分。————过滤后我们将剩余的种子归类为搜索体积中体素最小的连接体素,其中梯度计算公式如下:————一旦种子体素被选中,我们通过在特征空间中找到种子体素的中心和两个体素内的连接邻域来初始化超体素特征向量。
———————————————————————————————————————————
五、 超体的特征和距离测度进行聚类
VCCS超体素聚类是在39个维度上进行的:F={x,y,z,L,a,b,FPFH}
FPFH:局部几何特征点特征直方图。具有空间不变性的描述局部表面模型的特征。
为了计算空间中的距离算法,首先规范化空间中的点的距离这个分量,该分量取决于种子分辨率Rseed。FPFH空间中的距离Df是使用直方图相交核计算的,这就引出了标准化距离D的方程式:
———————————————————————————————————————————
六、基于约束的迭代聚类(Flow Constrained Clustering)
空间连通性问题:
💛关键:邻接性。确保各个超体素不会在空间中不相连的边界上有交集。
体素化三维空间中,相邻的定义有:共享一个面6、边18、点26。
💛构建体素点云的邻接图——》KDTree来实现。
eg:使用26个相邻体素,其所有的26个相邻体素的中心都一定要在根号3*Rvoxle中。
Rvoxel是指用于分割的体素分辨率,并且在该分辨率下将离散的元素称之为体素。
---------------------------------------------------------------------------------------------------------------------------------
💚迭代地将体素点云指定给超体素,显著的区别在于我们在将像素指定给聚类时考虑连通性和流。一般过程如下:
(1)从距离点云簇中心最近的体素开始,我们向外流动到相邻的体素,并使用方程计算每个体素到超体素中心的距离。如果距离是该体素所看到的最小距离,则设置其标签,并使用邻接图将其距离中心更远的邻居添加到该标签的搜索队列中。
(2)然后迭代下一个超级体素,这样从中心向外的每一层都会同时考虑所有的超级体素。我们反复向外搜索,直到找到每个超级体素的搜索体积的边缘(或者没有更多的邻居可以检查),这相当于邻接图的广度优先搜索,在深入搜索图之前,我们检查所有超级体素的相同级别。重要的是,需要避免了相邻体素的边,当我们到达一个超级体素的邻接图的所有叶节点或者在当前级别中搜索的节点都没有设置为其标签时,搜索就结束了。这个搜索过程下图所示,与现有的相比有两个重要优点。下图为流约束聚类算法的搜索顺序。
1,由于算法只考虑相邻的体素,因此超体素标签不能跨越在三维空间中实际不接触的对象边界
2,超级体素标签在三维空间中往往是连续的,因为标签从每个超级体素的中心向外流动,在空间中以相同的速率扩展。
一旦所有超体素邻接图的搜索结束,我们就通过取其所有成分的平均值来更新每个超体素簇的中心。这是以迭代的方式完成的;要么直到集群中心稳定下来,要么进行固定次数的迭代。实验中发现超体素在5次迭代之后是稳定的。