法向量
关于法向量估计的环节我们仍然应用前文的最小生成树估计法。
目前来看最小生成树是有效的估计法向量不可缺少的的步骤。
朝向计算依据
指向分布
法向量指向的分布的计算本文应用向量夹角计算。
但是,我们平时所说相同朝向相同的法向量并不可能是完全相同的方向,这个平面法向量是允许和我们所指示的方向偏离一定的容忍度。
图中如果有两片近似平面的点云,而我们将向量v1作为此分组的朝向。想要将这两块平面点云归为一组,则需要v1与v2向量的夹角小于一定的阈值:阈值夹角a就是我们的偏离容忍度。
方向主轴
由于分割的点云组数完全就是基于我们人为规定的主方向数目,则此处是本分割方法的关键。
在我们的方法中,暂时将分组的主轴分为xyz三个向量:【1,0,0】,【0,1,0】,【0,0,1】
容忍度角度设置为40度。
要怎么选择这些主轴,就全凭大家想象了。
逻辑流
1.录入老朋友bunny.pcd点云,进行法向量估计。
2.设置分组方向主轴,和各个方向的容忍度。
3.计算所有法向量与所有主轴的夹角,将处于容忍度内的法向量归入各个主轴集合。
完整代码
import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("../bunny_pcd.pcd")
pcd.paint_uniform_color([0.5, 0.5, 0.5])
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
pcd.orient_normals_consistent_tangent_plane(8)
normals = np.asarray(pcd.normals)
orient_x = [1,0,0]
orient_y = [0,1,0]
orient_z = [0,0,1]
orient_test = [orient_x,orient_y,orient_z]
angle_recolist = []
for i in range(len(normals)):
angle_recolist_pre = []
for j in range(len(orient_test)):
a = np.array(normals[i])
b = np.array(orient_test[j])
a_norm = np.sqrt(np.sum(a * a))
b_norm = np.sqrt(np.sum(b * b))
cos_value = np.dot(a, b) / (a_norm * b_norm)
arc_value = np.arccos(cos_value)
angle_value = arc_value * 180 / np.pi
if angle_value < 40:
angle_recolist_pre.append(1)
else:
angle_recolist_pre.append(0)
angle_recolist.append(angle_recolist_pre)
print(angle_recolist)
for i in range(len(angle_recolist)):
np.asarray(pcd.colors)[i] = angle_recolist[i]
o3d.visualization.draw_geometries([pcd], point_show_normal=False, window_name="三相法向量语义分割",
width=1024, height=768,
left=50, top=50,
mesh_show_back_face=False)
朝向z轴的是蓝色
朝向x轴的是红色
朝向y轴的是绿色