
本教程详细阐述了如何使用open3d库通过体素化方法,在目标三维模型(如`.obj`文件)的实体区域内精确插入一个缺陷模型(如`.ply`文件),同时避免空隙和顶点干扰。文章解决了在使用`voxelgrid`时常见的`attributeerror`和`typeerror`,指出了正确的api调用方式`get_voxel_center_coordinate`并强调了访问`voxel`对象的`grid_index`属性的重要性,最终提供了一个完整的、可操作的代码示例。
在三维几何处理中,体素化是将连续的三维模型离散化为一系列规则排列的小立方体(体素)的过程。这种方法在许多应用中都非常有用,例如碰撞检测、体积计算以及本文讨论的在复杂模型内部插入其他几何体。当我们需要在一个可能包含空洞或复杂内部结构的三维对象(如一个中空物体)中插入一个“缺陷”时,体素化提供了一种可靠的机制来识别并定位目标对象内的实体区域,从而避免将缺陷放置在模型的空隙或表面顶点上。
传统的基于顶点或面的几何操作可能难以精确控制插入位置,特别是在需要确保缺陷完全位于目标对象的“实体”部分时。体素网格通过将空间划分为离散单元,允许我们识别哪些体素被目标对象占据,从而为缺陷的定位提供了一个结构化的参考系。
Open3D是一个强大的开源库,用于处理三维数据。它提供了o3d.geometry.VoxelGrid类,用于创建和操作体素网格。
创建体素网格: 我们可以通过o3d.geometry.VoxelGrid.create_from_triangle_mesh()方法从三角网格(o3d.geometry.TriangleMesh)创建体素网格。这个方法需要两个主要参数:
获取占据的体素: 创建体素网格后,可以使用get_voxels()方法获取所有被几何体占据的体素列表。这个方法返回一个open3d.cpu.pybind.geometry.Voxel对象的列表,每个Voxel对象都包含其在体素网格中的grid_index(一个三维整数坐标)以及颜色信息。
在尝试将缺陷模型平移到目标体素的中心时,用户经常会遇到以下两种错误:
这个错误表明VoxelGrid对象没有名为get_voxel_center的方法。根据Open3D的官方文档,正确的API是get_voxel_center_coordinate。
错误原因: 用户可能参考了旧版本API或混淆了其他库的命名约定。
解决方案: 将try_voxel_grid.get_voxel_center(selected_voxel)替换为try_voxel_grid.get_voxel_center_coordinate(selected_voxel.grid_index)。
这个错误发生在尝试手动计算体素中心时,因为get_voxels()返回的是Voxel对象,而不是一个可以直接进行数学运算的坐标数组。
错误原因:selected_voxel是一个open3d.cpu.pybind.geometry.Voxel类型的对象,它不能直接与浮点数进行乘法运算。要获取体素的网格索引(即其在体素网格中的整数坐标),需要访问其grid_index属性。
解决方案: 在手动计算体素中心时,应使用selected_voxel.grid_index来获取体素的整数坐标。然而,更推荐的方法是使用Open3D提供的get_voxel_center_coordinate方法,因为它已经封装了这些计算,并考虑了体素网格的内部结构和原点。
下面是一个修正后的完整代码示例,演示了如何将一个球形缺陷模型精确地插入到另一个三维对象的实体区域内。
import open3d as o3d
import numpy as np
def main():
# 1. 文件路径
# 请根据您的实际文件路径修改
try_obj_path = '/Users/xd_anshul/Desktop/Research/try.obj'
defect_path = '/Users/xd_anshul/Desktop/Research/Project Defect/sphere.ply'
# 2. 加载网格模型
try_mesh = o3d.io.read_triangle_mesh(try_obj_path)
defect_mesh = o3d.io.read_triangle_mesh(defect_path)
# 3. 对缺陷模型进行预处理(缩放)
# 假设需要将缺陷缩小一半,并以其自身中心为缩放点
scaled_defect = defect_mesh.scale(0.5, center=defect_mesh.get_center())
# 确保缺陷网格的法线正确,以便体素化和可视化
scaled_defect.compute_vertex_normals()
# 4. 将网格转换为体素网格
# 调整体素尺寸以平衡精度和性能
voxel_size = 0.2
try_voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh(try_mesh, voxel_size)
# 5. 获取目标网格中被占据的体素
# get_voxels() 返回 Voxel 对象的列表
occupied_voxels = try_voxel_grid.get_voxels()
if not occupied_voxels:
print("Warning: No occupied voxels found in the target mesh. Check voxel_size or mesh integrity.")
return
# 6. 随机选择一个被占据的体素作为缺陷的插入点
voxel_index_in_list = np.random.randint(0, len(occupied_voxels))
selected_voxel = occupied_voxels[voxel_index_in_list]
# 7. 获取所选体素的中心坐标
# 关键修正:使用 get_voxel_center_coordinate 并传入 Voxel 对象的 grid_index
translation_vector = try_voxel_grid.get_voxel_center_coordinate(selected_voxel.grid_index)
# 8. 将缺陷模型平移到选定体素的中心
# 缺陷模型会以其当前原点为参考点进行平移
scaled_defect.translate(translation_vector, relative=False) # relative=False表示绝对平移到指定位置
# 9. 合并网格并可视化
combined_mesh = try_mesh + scaled_defect
combined_mesh.compute_vertex_normals() # 重新计算法线以获得更好的渲染效果
o3d.visualization.draw_geometries([combined_mesh], window_name="Combined Mesh with Defect")
if __name__ == "__main__":
main()代码解析:
通过Open3D的体素化功能,我们能够有效地在三维模型内部的实体区域精确插入其他几何体。解决get_voxel_center方法不存在以及Voxel对象不能直接进行数值运算的TypeError的关键在于正确使用get_voxel_center_coordinate方法,并传入Voxel对象的grid_index属性。掌握这些技术,可以为三维数据处理中的缺陷建模、结构分析等任务提供强大的工具。
以上就是在Open3D中利用体素网格坐标进行三维模型缺陷定位与插入的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号