理论入门
首先要用各点的曲率值对点进行排序,因为一个区域要从它曲率最小值的点开始生长。因为从曲率最小点可以定位到平坦的区域,而从最平坦区域的增长可以减少分割区域的数量。
因此先对点云进行一下排序。在云中存在未标记(这个标记我认为是人工手动标记)的点之前,算法会选择具有最小曲率值的点并开始该区域的增长。此过程如下:
选择的点被添加到称为种子的集合中。
对于每个种子点算法找到其相邻点。
- (1)测试每个相邻点的法线与当前种子点法线之间的角度。如果角度小于阈值,则将当前点添加到当前区域。
- (2)测试完角度之后,再测试每个相邻点的曲率值。如果曲率小于阈值,则将该点添加到种子集合中。
- (3)从种子集合中除去当前的种子。
(1)中,因为当前的选取的种子点就是曲率最小的点了,所以就先测与一下周围点法线的夹角,如果角度不大的话(角度小于指定阈值),就进行区域生长。先假设最初的种子点周围的相邻点巧了嘿,都满足这个条件,都被种子点发展过来了。
(2)好了,经过(1)可以看到,最初的种子点已经尽力自己最大的努力,最多也就才能把它周围的所有点都发展来(归到生长区域),再靠外的点它接触不到了。然而我们生长算法算是贪心的吧,还想继续扩大自己领地(继续生长)。
这时候就委屈一下了,曲率最小的点只有一个,只能退而求其次。现在开始睁一只眼闭一只眼,规定了一个曲率的阈值。只要是初始种子点的发展来的,就是(1)中新生长的区域只要满足曲率小于规定的阈值,就可以把他们加入到种子点集合中(相当于提高了权限哈)。
现在假设,哎,刚好有一个点满足相邻点曲率的条件(也可以是多个点满足)!把这个点加入到种子集合中(有了接班人相当于)。走到(3)把最初种子点去除,然而还有刚才(2)中新加入到种子点集合中的新成员。再把它作为选定的种子点重复(1)。循环往复,直到遇到了种子点集合为空的情况停止生长。
现在假设刚才新发展来的相邻点全都不符合了曲率条件。这。。。走到(3)就要把最初种子点去除了,种子集合中也就没了种子点,成了空集。则意味着算法已经完全生长了该区域并且要从头开始重复该过程。可以在下面找到所述算法的伪代码。
Inputs:
- Point cloud =
- Point normals =
- Points curvatures =
- Neighbour finding function
- Curvature threshold
- Angle threshold
Initialize:
- Region list
- Available points list
Algorithm:
While
is not empty do
Current region
Current seeds
Point with minimum curvature in
注:这里应该是从点集A剔除的意思
for
to size (
) do
Find nearest neighbours of current seed point
for
to size (
) do
Current neighbour point
If
contains
and
then
If
then
end if
end if
end for
end for
Add current region to global segment list
- end while
- Return