Open3d使用estimate_normals函数来计算法向量。其参数设置Open3d提供了3中参数搜索的方法(所有计算的法向量模长为1):
open3d.geometry.KDTreeSearchParamKNN(knn=20) # 计算近邻的20个点
open3d.geometry.KDTreeSearchParamRadius(radius=0.01) # 计算指定半径内的点
open3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=20) # 同时考虑搜索半径和近邻点个数
Open3d绘制点云draw_geometries的参数说明:
def draw_geometries(*args, **kwargs): # real signature unknown; restored from __doc__"""draw_geometries(*args, **kwargs)Overloaded function.1. draw_geometries(geometry_list, window_name='Open3D', width=1920, height=1080, left=50, top=50, point_show_normal=False, mesh_show_wireframe=False, mesh_show_back_face=False)Function to draw a list of geometry.Geometry objectsArgs:geometry_list (List[open3d.geometry.Geometry]): List of geometries to be visualized.window_name (str, optional, default='Open3D'): The displayed title of the visualization window.width (int, optional, default=1920): The width of the visualization window.height (int, optional, default=1080): The height of the visualization window.left (int, optional, default=50): The left margin of the visualization window.top (int, optional, default=50): The top margin of the visualization window.point_show_normal (bool, optional, default=False): Visualize point normals if set to true.mesh_show_wireframe (bool, optional, default=False): Visualize mesh wireframe if set to true.mesh_show_back_face (bool, optional, default=False): Visualize also the back face of the mesh triangles.Returns:None2. draw_geometries(geometry_list, window_name='Open3D', width=1920, height=1080, left=50, top=50, point_show_normal=False, mesh_show_wireframe=False, mesh_show_back_face=False, lookat, up, front, zoom)Function to draw a list of geometry.Geometry objectsArgs:geometry_list (List[open3d.geometry.Geometry]): List of geometries to be visualized.window_name (str, optional, default='Open3D'): The displayed title of the visualization window.width (int, optional, default=1920): The width of the visualization window.height (int, optional, default=1080): The height of the visualization window.left (int, optional, default=50): The left margin of the visualization window.top (int, optional, default=50): The top margin of the visualization window.point_show_normal (bool, optional, default=False): Visualize point normals if set to true.mesh_show_wireframe (bool, optional, default=False): Visualize mesh wireframe if set to true.mesh_show_back_face (bool, optional, default=False): Visualize also the back face of the mesh triangles.lookat (numpy.ndarray[numpy.float64[3, 1]]): The lookat vector of the camera.up (numpy.ndarray[numpy.float64[3, 1]]): The up vector of the camera.front (numpy.ndarray[numpy.float64[3, 1]]): The front vector of the camera.zoom (float): The zoom of the camera.Returns:None"""pass
法向量计算与可视化代码:
import open3d
import numpy as np
import mayavi.mlab as mlab
# 4. 法向量的计算
def open3d_vector_compute():pcd_path = r"E:\xxxx\open3d_xxxx\ICP_data\cloud_bin_0.pcd"pcd = open3d.io.read_point_cloud(pcd_path)pcd.estimate_normals(search_param=open3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30))normals = np.array(pcd.normals) # 法向量结果与点云维度一致(N, 3)points = np.array(pcd.points)print(normals.shape, points.shape)# 验证法向量模长为1(模长会有一定的偏差,不完全为1)normals_length = np.sum(normals**2, axis=1)flag = np.equal(np.ones(normals_length.shape, dtype=float), normals_length).all()print('all equal 1:', flag)# 法向量可视化open3d.visualization.draw_geometries([pcd],window_name="Open3d",point_show_normal=True,width=800, # 窗口宽度height=600) # 窗口高度
if __name__ == '__main__':open3d_vector_compute()