import open3d as o3d
mesh = o3d.io.read_triangle_mesh("mode/Fantasy Dragon.ply")
mesh.compute_vertex_normals()
三维模型使用R,T两个参数来变换,视图的空间坐标系建立:向上为z轴,向右为y轴,x轴指向屏幕前。使用transform
方法变换坐标,变换矩阵为[4*4]的矩阵,transform([[R, T], [0, 1]])
。
正常读取一个ply文件:
import open3d as o3d
pcd = o3d.io.read_point_cloud("mode/Fantasy Dragon.ply")
o3d.visualization.draw_geometries([pcd], width=1280, height=720)
显示效果如图:
使用转换函数,把他横着放,且头部面向屏幕。那么就是将原来的z轴换到y轴,y轴换到x轴,x轴换到z轴,所以代码为:
import open3d as o3d
mesh = o3d.io.read_triangle_mesh("mode/Fantasy Dragon.ply")
mesh.compute_vertex_normals()
mesh.transform([[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 0, 0, 1]])
o3d.visualization.draw_geometries([mesh], width=1280, height=720)
import open3d as o3d
import numpy as np
mesh = o3d.io.read_triangle_mesh("mode/Fantasy Dragon.ply")
mesh.compute_vertex_normals()
v_mesh = np.asarray(mesh.vertices)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(v_mesh)
o3d.visualization.draw_geometries([pcd], width=1280, height=720)
对于ply格式的文件还好,但若是stl这种三角形网格,转化的结果会有点不理想。
open3d提供了一种采样方式,可设置采样点,简化模型。
import open3d as o3d
mesh = o3d.io.read_triangle_mesh("mode/ganyu.STL")
mesh.compute_vertex_normals()
pcd = o3d.geometry.TriangleMesh.sample_points_uniformly(mesh, number_of_points=10000) # 采样点云
o3d.visualization.draw_geometries([pcd], width=1280, height=720)
体素化,能简化模型,得到均匀网格。
import open3d as o3d
import numpy as np
print("Load a ply point cloud, print it, and render it")
mesh = o3d.io.read_triangle_mesh("mode/ganyu.STL")
mesh.compute_vertex_normals()
mesh.scale(1 / np.max(mesh.get_max_bound() - mesh.get_min_bound()), center=mesh.get_center())
voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh(mesh, voxel_size=0.05)
o3d.visualization.draw_geometries([voxel_grid], width=1280, height=720)
import open3d as o3d
import numpy as np
print("Load a ply point cloud, print it, and render it")
pcd = o3d.io.read_point_cloud("mode/Fantasy Dragon.ply")
pcd.scale(1 / np.max(pcd.get_max_bound() - pcd.get_min_bound()), center=pcd.get_center())
pcd.colors = o3d.utility.Vector3dVector(np.random.uniform(0,1,size=(2000,3)))
print('voxelization')
voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd, voxel_size=0.05)
o3d.visualization.draw_geometries([voxel_grid], width=1280, height=720)
voxel_down_pcd = pcd.voxel_down_sample(voxel_size=0.05)
voxel_down_pcd.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
o3d.visualization.draw_geometries([voxel_down_pcd], point_show_normal=True, width=1280, height=720)
estimate_normals
计算每个点的法线。该函数查找相邻点并使用协方差分析计算相邻点的主轴。
该函数将KDTreeSearchParamHybrid
类的实例作为参数。两个关键参数为指定搜索半径和最大最近邻。
radius=0.1, max_nn=30
即以10cm为搜索半径,并最多只考虑30个临近点以节省计算时间。
print("打印第一个向量:")
print(voxel_down_pcd.normals[0])
#打印第一个向量:
#[ 0.51941952 0.82116269 -0.23642166]
#打印前十个法线向量
print(np.asarray(voxel_down_pcd.normals)[:10,:])
sample_points_poisson_disk()
方法采样。