Marching Cubes算法
- 1. 简介
- 2. 算法原理的理解
- 2.1 如何找到面经过的这些小块(六面体)?
- 2.2 找到后,如何又进一步的找到面与这些小块(六面体)的交点;
- 2.3 这些交点按照怎么的拓扑连接关系连接,是怎么操作的?
- 3. 总结
- 4. 参考
1. 简介
在学习网格生成算法之前,推荐大家先了解Marching Cube(MC)算法,为什么呢,他也不是一个端到端的网格生成算法?因为很多连续算法在最后提取等值面的时候都会采用marching cube或其改进版本,可以说MC算法是很多算法的后处理。如果不理解这一步怎么做的,也很难理解其他算法之前的那么多计算的目的是什么。除此之外可以大大简化其他算法的解释过程,最后一步,就可以忽略不解释了。所以我们大家开始吧。
在解释MC算法前,我们先来解释一下等值面。
等值面是什么?
首先等值面是空间中的一个曲面,我们规定空间中每一个点都有一个属性值,属性值相等连续空间组成的曲面,我们称之为等值面。可能还是不太直接,跟我们网格生成有什么关系,我们接下来看。
我们在采集深度点云时,由于传感器自身精度以及配准的误差在一个地方会采集到很多点,可以认为是空间连续点的采样,而且点的位置会有很大的波动。我们通过一些其他方法可以得出这些点与真正的面(这里就是我们所说的等直面)的差值,
那么怎么搞清楚真正的面在哪里呢?
假如一个点在面的前方,我们标记为+1,一个点在真实面的后方,标记为-1,我们可以认为这个真正的面就在这两个点的中间。
我们还可以这么认为,空间内真正的面,会产生一个场,场内有无数个等值面,这个值我们暂且称之为空间场值,空间场值在面的前方为正值,后方为负值。离真实面越近,空间场值的绝对值越小,真实面的空间场值为0(暂定为0,也可以是其他的)。我们的目的就是在对这个场进行采样后,找到空间内真正的面。
2. 算法原理的理解
MarchingCube算法的核心是:为了提取空间中的等值面,并用三角面近似(mesh数据格式)的表示出来。
打个比方:我们可以在CAT影像数据中测量组织的密度,并在组织变得坚硬且致密的点处创建一个表面,因此我们可以创建头骨的 3D 模型,以帮助外科医生进行修复。下图显示了使用 March Cubes 算法根据 CAT-Scan 数据重建的人类头骨。
那么,Marching Cube 的算法流程是怎么的呢?
首先将空间分成众多的六面体网格,类似将空间分成很多的小块,分成的小块数越多,则分辨率越高,更能适配局部表面的复杂性,但耗时比较久。如下,右侧划分的小块要多一些。
然后找到等值面经过的小块(六面体):划分成一个个小块后 ,一个个小块上进行迭代(“行进”)。如果立方体的所有 8 个顶点均为正值,或者所有 8 个顶点均为负值,则立方体完全高于或完全低于表面,所以不会产生任何三角形。否则,表面会经过这些小块,并且与边产生交点,将这些交点按照一定的拓扑连接关系连接起来,作为0等值面在该小块(六面体网格)中的近似表示。注意是近似表示,我们采用三角形。
那么问题来了。
- 如何找到面经过的这些小块(六面体)?
- 找到后,如何又进一步的找到面与这些小块(六面体)的交点?
- 这些交点按照怎么的拓扑连接关系连接,是怎么操作的?
2.1 如何找到面经过的这些小块(六面体)?
前面我们提到过,我们有很多的已知采样点,并且知道这些点在空间中的空间场值,现在我们将空间分为很多个小格子,每个小格子都有8个顶点,我们通过计算8个顶点周围(范围与六面体的大小相关)的采样点,近似计算出8个顶点的空间场值(加权评价等方法)。我们就可以对六面体做以下分类,我们分析一下以下情况:
- 八个顶点都没有空间场值,0等值面不经过或者经过但是没有采样,我们没有办法进行近似,所以不处理。
- 八个顶点都有或部分有空间场值,当空间场值都是正值或者都是负值时,说明0等值面,不在六面体内。
- 当六面体内的的顶点的空间场值有正有负时,则说明有0等直面穿过六面体。我们需要从众多六面体内,筛选出这样的六面体。
2.2 找到后,如何又进一步的找到面与这些小块(六面体)的交点;
因为六面体有8个顶点,8个顶点的状态就有2^8 = 25种分布状态,但是由于六面体是有对称性的,我们通过对称性,可以简化这些状态至15种状态,至于怎么简化,为什么相等,大家简单想一想就好,这个并不复杂。我们看一下15种状态:
我们上面展示了等值面与六面体相交的情况一共就这样15种,其中还有一个没有交点的,也可以说14种。现在我们就需要精算出来,这个交点的具体的位置,下面我们举一个例子:
我们先给六面体的所有的顶点和边坐上标记:
假如体素下方的顶点3(点的序号见上图)的值小于等值面值,其他顶点上的值都大于等值面值,那么我们可以生成一个与体素边2,3,11相交的三角面片,而三角面片顶点的具体位置则需要根据等值面值和边顶点3-2,3-0,3-7的值线性插值计算得到。
我们将交点坐标用P表示,P1、P2代表边上两个端点的坐标,V1、V2代表这两个端点上的值,V代表等值面值,那么交点坐标的计算公式如下(就是简单的线性差值,当然还有很多种方法,先简单介绍一个简单的线性插值):
P = P1 + (V – V1)·(P2 – P1)/(V2 – V1)
那么现在我们对所有的含有等值面的六面体计算出了其与等值面的角点。下一步也就是最后一步,就是将这些角点链接成三角形就好了。我们来看看怎么做的。
2.3 这些交点按照怎么的拓扑连接关系连接,是怎么操作的?
其实每个顶点的状态,会为这256种情况制作一个8位索引,这个8位索引一般用16进制表示。一般会有2个查找表,第一个表是8个顶点上下关系的二进制表示,即edgeTable查找表,第二个表是triTable查找表。这些表在较早的时候有人手动统计的。
3. 总结
Marching Cubes等值面提取算法在原理和实现上都比较简单直观
经典的Marching Cubes算法还存在一些问题:
- 缺陷一:拓扑连接二义性,如下图所示
- 缺陷二:效率低下,需要借助分层结构和并行计算
4. 参考
- Lorensen W E, Cline H E. Marching cubes: A high resolution 3D surface construction algorithm[J]. Acm Siggraph Computer Graphics, 1987, 21(4):163-169.
- Marching Cubes Part 1: Explaining marching cubes
- 网格生成之marching cube算法学习笔记