一、概述
近期有需求要对三维网格模型的边界进行检测提取,虽然在meshlab中可以直接显示出三维网格模型的边界,但是经过我各种摸索最后发现好像没有方法能够将显示出的边界信息保存下来,没办法,只能自己手写一个检测方法了。而恰好三维网格模型的边界检测非常简单,只需要根据其拓扑结构,找到只属于一个面的边即为边界。虽然实现出来了,但是在效率上比较低,对点数较多的模型,需要耗费较多的时间,只用几次,我也懒得优化了。
二、代码
没什么好说的,思想很简单,就是找到只属于一个面的边,把这条边包含的点标记为边界点即可。
import time
time_start = time.time()
filename = "*****.ply"
filename1 = "*****.ply"
edges = []
num_edge = []
boundarypoint = []
temp = []
j = 0
pointIdx = 0
print(['3', '5']+['4'])
with open(filename, 'r') as f:
str = f.readline()
while str :
if len(str.strip().split(' ')) == 3 and str.split(' ')[1] == 'vertex':
pointnum = int(str.split(' ')[2])
print("number of points is: {}".format(pointnum))
if str == "end_header\n":
print(str+"----")
break
str = f.readline()
for i in range(pointnum):
str = f.readline()
str = f.readline()
while str:
if str.split(' ')[0]=='3':
edge0 = sorted([str.split(' ')[1], str.split(' ')[2]])
edge1 = sorted([str.split(' ')[1], str.split(' ')[3]])
edge2 = sorted([str.split(' ')[2], str.split(' ')[3]])
if edge0 not in edges:
edges.append(edge0)
num_edge.append(1)
else:
num_edge[edges.index(edge0)] += 1
if edge1 not in edges:
edges.append(edge1)
num_edge.append(1)
else:
num_edge[edges.index(edge1)] += 1
if edge2 not in edges:
edges.append(edge2)
num_edge.append(1)
else:
num_edge[edges.index(edge2)] += 1
str = f.readline()
for i in range(len(num_edge)):
if num_edge[i] == 1:
temp = [int(edges[i][0]), int(edges[i][1])]
boundarypoint += temp
j += 1
print(j)
print(boundarypoint)
f.close()
time_end = time.time()
print("time cost {} s".format(time_end-time_start))
with open(filename1,'a') as f1:
f1.write("""ply
format ascii 1.0
comment VCGLIB generated
element vertex {}
property float x
property float y
property float z
property float nx
property float ny
property float nz
property uchar red
property uchar green
property uchar blue
end_header
""".format(pointnum))
with open(filename, 'r') as f:
str = f.readline()
while str:
if str == "end_header\n":
break
str = f.readline()
str = f.readline().strip()
pointIdx = 0
for i in range(pointnum):
f1.write(str)
if pointIdx in boundarypoint:
f1.write(" 0 255 0 \n")
else:
f1.write(" 130 130 130 \n")
str = f.readline().strip()
pointIdx += 1
f1.close()
f.close()
三、实验结果
首先利用meshlab对模型检测显示得到的结果为:
可以看到,meshlab检测得到的边界边的数量为165条。
而通过上述代码检测得到的数量也是165条,所以检测的结果是与meshlab一致的。
利用代码检测结果如下图:
检测之后我只保存了点的信息,并没有面和边的信息。