Open3D体素化问题:部分三角形面填充不完整
Open3D立方体网格体素化仅沿三角形边缘分布的问题
问题描述
使用Open3D v0.17.0对TriangleMesh创建的立方体进行体素化时,生成的VoxelGrid仅沿三角形边缘分布体素,未填满整个三角面,立方体侧面该现象尤为明显。原本期望体素能均匀填充立方体所有表面三角面,但可视化后仅上下底面填充完整,侧面体素主要沿三角形对角线分布。
请问这是Open3D体素化的预期行为,还是实现方式存在误区?
使用代码如下:
import open3d as o3d import numpy as np new_room = o3d.geometry.TriangleMesh.create_box(10,10,10) lines = [] for triangle in np.array(new_room.triangles): lines.extend([(triangle[0], triangle[1]), (triangle[1], triangle[2]), (triangle[2], triangle[0])]) line_set = o3d.geometry.LineSet() vertices = np.array(new_room.vertices) line_set.points = o3d.utility.Vector3dVector(vertices) line_set.lines = o3d.utility.Vector2iVector(lines) voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh(new_room, voxel_size=0.5) o3d.visualization.draw_geometries([new_room, line_set, voxel_grid])
解答
核心结论
这是Open3D create_from_triangle_mesh方法的预期行为,而非实现误区。
原因分析
create_from_triangle_mesh的体素化逻辑仅标记与三角网格表面相交的体素,而非填充三角面覆盖的全部区域。- Open3D默认创建的立方体,每个侧面由两个沿对角线分割的三角形组成,体素只会落在这些三角形的边缘及相交位置,因此呈现沿对角线分布的视觉效果。
- 立方体上下底面的三角形是完整矩形面(无对角线分割),体素与面的相交区域覆盖整个底面,所以看起来填充完整。
实现表面填充式体素化的方案
若需要体素均匀填满三角面覆盖区域,可通过「表面点采样+点云体素化」的方式实现:
- 对三角网格的每个面进行密集点采样,获取覆盖整个表面的点云
- 基于采样点云创建体素网格,标记所有包含采样点的体素
修改后的代码示例:
import open3d as o3d import numpy as np # 创建立方体网格并计算法向量(辅助采样) new_room = o3d.geometry.TriangleMesh.create_box(10,10,10) new_room.compute_vertex_normals() # 对三角面进行均匀密集采样,num_points控制采样密度 sampled_points = new_room.sample_points_uniformly(num_points=10000) # 基于采样点云生成体素网格 voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(sampled_points, voxel_size=0.5) # 构建线框用于可视化对比 lines = [] for triangle in np.array(new_room.triangles): lines.extend([(triangle[0], triangle[1]), (triangle[1], triangle[2]), (triangle[2], triangle[0])]) line_set = o3d.geometry.LineSet() line_set.points = o3d.utility.Vector3dVector(np.array(new_room.vertices)) line_set.lines = o3d.utility.Vector2iVector(lines) # 可视化结果 o3d.visualization.draw_geometries([new_room, line_set, voxel_grid])
注意事项
- 采样点数量
num_points需结合体素大小调整:体素越小,需要的采样点越多,才能保证覆盖所有目标体素。 create_from_point_cloud会标记所有包含采样点的体素,因此能实现表面填充的效果。
内容的提问来源于stack exchange,提问作者Yash Kumar
相关产品推荐
相关产品推荐

