本文主要是介绍CGAL的表面网格分割,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
应用于大象的形状-直径函数和相应的分割(使用6个聚类)。
1、介绍
网格分割是将网格分解为更小、更有意义的子网格的过程。该过程用于建模、装配、纹理、形状检索、变形等应用。我们参考了关于网格分割的不同分割技术的综合调查。
SDF是Shape Diameter Function的缩写,中文意思是形状直径函数。它是一种测量二维或三维几何形状局部直径的函数,广泛应用于计算机图形学、计算几何和几何计算等领域
该软件包提供了一种依赖于形状直径函数的算法实现。给定一个包围三维实体物体的三角表面网格(以下简称网格),SDF为网格的每个面提供了一个局部物体直径的估计(SDF值)。分割算法首先使用相关的SDF值对网格的面进行软聚类。然后通过图切割算法获得最终分割,该算法考虑基于表面的特征(二面角和凹度)以及软聚类的结果。
此软件包将SDF值和网格分割结果作为独立函数进行计算。这允许将SDF的替代实现直接插入分割算法中,并允许为分割算法多次使用具有不同参数的SDF值。
2、整体流程
2.1、形状直径函数
形状直径函数在表面网格和被截取的3D有界物体的体积之间建立了联系。更具体地说,SDF是在网格面上定义的标量值函数,用于测量相应的局部物体直径。SDF通过在面上添加局部厚度概念来区分薄和厚部分。此外,SDF是姿态不变的:在改变姿态后,SDF值基本上不受影响(如下图所示)。
对于给定的输入网格,通过逐个处理每个面来计算原始的SDF值。对于每个面,在以面中心为顶点、以内法线为轴构建的锥体中采样若干射线。每条射线被截断成一段,其端点是锥体的顶点和第一个网格面交点。通过直观地对应于局部体积采样的这些截断射线的长度,首先应用异常值去除程序,然后取长度的平均值来计算原始的SDF值。
通过函数sdf_values()计算原始的SDF值,将postprocess设置为false。
此包还接受带有孔的输入网格。在这种情况下,不能被截断为分段的射线,或者与第一相交小平面的向内法线形成钝角的射线被忽略。只有没有射线的面才能获得原始SDF值
原始SDF值的后处理
在计算了每个面的原始SDF值之后,在分割算法中使用的SDF值是几个后处理步骤的结果:
没有原始SDF值的面被分配给其边缘相邻邻居的平均原始SDF值。如果仍然存在没有SDF值的面,则将其分配给所有SDF值中的最小值。不将0分配给没有SDF值的面的主要原因是,这会妨碍在segmentation_from_sdf_values()的开头进行的对数归一化过程。
应用了双边平滑。这种平滑技术可以去除噪波,同时尝试保持SDF值的快速变化不变,因为它们是线段边界的自然候选。双边平滑有三个参数,设置如下:
大窗口尺寸在消除噪声方面更有效,但可能会使SDF值沿线段边界过于平滑。大范围参数使平滑更接近高斯平滑,也可能导致SDF值过平滑。
SDF值在[0,1]之间进行线性归一化。
这些后处理步骤可以使用函数SDF_values_postprocessing()应用于原始SDF值(或与facet相关联的一组类似标量值)。
2.2、软聚类
给定k个簇的数量,软聚类是一个高斯混合模型,由k个高斯分布拟合面SDF值的分布组成。它使用k-means++ 进行初始化,并使用随机种子多次运行。在这些运行中,最好的结果用于初始化拟合高斯分布的期望最大化算法。
簇的数量(软聚类的参数)与最终的段数之间没有直接关系。直观地说,簇的数量表示通过聚类具有接近SDF值的面的分割级别数,而不考虑它们的连接性。然而,大量的簇可能会导致网格的详细分割,分割成大量的段,如下图所示。
簇的数量对分割的影响。簇的数量分别设置为4、3和2。
这个过程的输出是一个矩阵,其中包含每个面属于每个簇的概率值。这些概率值用作硬聚类的输入。
2.3、硬聚类
硬聚类产生了输入网格的最终分割,并来自于最小化结合上述概率矩阵和几何表面特征的能量函数。
使用alpha-扩展图切割算法最小化的能量函数定义如下:
注意能量函数的两个项,e1和e2,都是非负的。能量函数的第一个项提供了软聚类概率的贡献。能量函数的第二个项是一个几何准则,两个不属于同一聚类的相邻面之间的二面角越接近±π,这个几何准则就越大。平滑参数使得这个几何准则或多或少地普遍存在。
给平滑参数赋予一个高值会导致分割数量较少(因为构造一个分割边界会很昂贵)。换句话说,将放置在不同聚类下的面合并比将它们分开并创建边界要便宜。相反,平滑参数取较小的值会导致分割数量增多,通过更接近软聚类的结果(请注意,将λ设置为0提供软聚类的结果)。图描述了平滑参数的影响。
使用10个集群进行分割时,平滑参数λ的影响。平滑参数分别设置为0.0、0.1、0.25、0.5和1.0。着色反映了在将每个连接组件分配给自己的段之前,分割的结果。
硬聚类将每个面分配一个簇id(参见图(a))。一个段由同一簇中的一组连接的面组成(参见图(b))。默认情况下,函数segmentation_from_sdf_values()将每个面的id分配给其段。当output_cluster_ids设置为true时,它将每个面的id分配给其簇。
簇和段。输入的簇数量设置为5。 (a) 硬聚类的结果。 (b) 从计算出的簇中提取段。
2.4、总结
sdf_values():计算输入网格中每个面的体素场值,结果可以是原始形式或经过后处理的形式。体素场值通过属性映射(参见CGAL和Boost属性映射)与面相关联。
sdf_values_postprocessing():对原始体素场值进行后处理。该后处理与sdf_values()函数分离,以允许使用其他方法计算体素场值或添加其他后处理步骤。
segmentation_from_sdf_values():根据输入网格中每个面的体素场值计算网格分割。输入的体素场值可以是与每个面相关联的任何标量值,只要它们已归一化在0和1之间。此函数允许在分割阶段使用不同的参数使用相同的体素场值。分段或聚类id通过属性映射与面相关联。
segmentation_via_sdf_values():结合上述三个函数。
这些函数期望的输入是一个三维实体的三角化表面网格,具有以下属性:组合上为2-流形;当从物体外部看到时,面的顶点按逆时针方向定向;无交集;无边界。
注意:
当前实现对于不符合这些属性的网格执行良好,但可能产生不可靠或无意义的分割。
当前SDF值的计算依赖于3D快速交集和距离计算包。当提供的AABBTraits模型具有精确谓词时,此操作是可靠的。建议将CGAL::Exact_predicates_inexact_constructions_kernel用作此算法的几何特征。
3、性能
下表提供了函数sdf_values()和segmentation_from_sdf_values的运行时。结果是在CGAL的4.4版本中产生的,该版本在带有8GB RAM的Intel i7 3.2 GHz笔记本电脑上,由Visual C++2010编译,带有/O2选项。多面体类型使用polyhedron_items_with_id_3作为项类。用于基准的模型是具有7828个刻面的恐龙模型、具有20188个刻面的熊模型和具有88928个刻面的大象模型。
sdf_values()的运行时间(以秒为单位),其中25条射线显示了稳健性的成本:
Number of triangles | Simple_cartesian<double> | Exact_predicates_inexact_constructions_kernel (EPICK ) |
---|---|---|
7,828 | 2.3 | 3.8 |
20,188 | 6.1 | 9.5 |
88,928 | 46.1 | 62.3 |
segmentation_from_sdf_values()的运行时间(以毫秒为单位)(使用Simple_cartesian<double>或EPICK会给出相同的结果),图形切割部分使用库MaxFlow v2.21:
Number of triangles | Number of cluster = 2 | Number of cluster = 5 | Number of cluster = 10 | Number of cluster = 15 |
---|---|---|---|---|
7,828 | 38 | 61 | 141 | 204 |
20,188 | 50 | 163 | 483 | 608 |
88,928 | 314 | 1,260 | 2,736 | 4,239 |
4、其他
传统的k-means算法在选择初始聚类中心时是随机选择的,这可能会导致算法陷入局部最优解,或者得到的结果不稳定。而k-means++算法在选择初始聚类中心时,采取了一种启发式的方法,旨在选择更加分散和均匀的初始聚类中心。
具体来说,k-means++算法的步骤如下:随机选择一个点作为第一个聚类中心;对于每个后续的聚类中心,选择一个离已选择的聚类中心最远的点;重复步骤2,直到选择了k个聚类中心;使用选择的k个聚类中心对数据进行聚类。
这种选择初始聚类中心的方法可以确保初始聚类中心更加分散和均匀,从而提高了k-means算法的准确性和稳定性。
Alpha-expansion graph cut algorithm是一种基于图论的图像分割算法。该算法通过构建一个图,其中像素点作为图的顶点,相邻像素之间通过边相连,然后利用图割技术进行图像分割。
Alpha-expansion算法的基本思想是通过不断添加新的顶点来扩展一个已有的分割区域,同时更新对应的能量函数以最小化能量代价。在算法执行过程中,会不断迭代地扩展每个区域的边界,直到达到预设的停止条件或达到最大迭代次数。
该算法的主要步骤包括:初始化:将图像中的像素点作为图的顶点,相邻像素之间通过边相连,并初始化一个种子区域作为分割区域。计算能量:根据当前分割区域和种子区域计算能量函数值,能量函数通常由区域相似度、边界强度和区域一致性等因素组成。Alpha-expansion:选择一个种子点,将其扩展到一个相邻的未被分割的区域,并更新能量函数值。更新区域:根据新的种子点和能量函数值更新分割区域。迭代执行:重复步骤2-4直到满足停止条件或达到最大迭代次数。
Alpha-expansion算法在图像分割领域具有较好的效果,尤其在处理复杂背景和动态场景时表现优异。它能够有效地将目标物体从背景中分离出来,并保持较好的分割边缘和细节。然而,该算法的计算复杂度较高,需要较长的运行时间,并且对于噪声和光照变化等干扰因素较为敏感。
CGAL 5.6 - Triangulated Surface Mesh Segmentation: User Manual
这篇关于CGAL的表面网格分割的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!