使用open3D python工具包画mesh图时出现错误

open3D工具包很好用,但是在我使用过程中发现目前(0.12.0版本)中 o3d.io.read_triangle_mesh函数不能正常读取.ply文件中的纹理及其对应坐标,需要进行手动添加。

import open3d as o3d

mesh = o3d.io.read_triangle_mesh(file_path)
mesh.compute_vertex_normals()

纹理图片已知,用一句即可读入:

mesh.textures = [o3d.io.read_image(texture_path)]

纹理对应坐标是一个(3*triangle_num, 2)的数组,可以参考这篇帖子。我是使用另一个包叫plyfile,读.ply里面的数据出来然后做处理的。将其赋值给mesh的trianlges_uvs属性

mesh.triangle_uvs = o3d.utility.Vector2dVector(uv)

本以为这样就完成了,但是在使用draw_geometries的时候并不能正确绘图,报错:

Process finished with exit code -1073741819 (0xC0000005)

后来在github和stack overflow里面找了好久,终于被我找到了端倪,原来还要定义一个mesh的属性,triangle_material_ids,原因是在0.10.0版本之后每隔mesh可以同时有多个纹理文件(这大概也是为什么前面在定义纹理图片的时候是使用的list作为输入)。

既然知道了原因就好办了,总之就是要定义一下这个属性,经过大胆猜测,应该就是全给个0(表示都用第一个纹理文件)就行了:

mesh.triangle_material_ids = o3d.utility.IntVector(np.zeros((len(mesh.triangles),)).astype(int))
o3d.visualization.draw_geometries([mesh])

总结一下,一个带有纹理的mesh想要正确输出,必须包含以下几个属性:

  • triangles
  • vertex
  • vertex_normals
  • textures
  • triangle_uvs
  • triangle_material_ids

---------------------------------

最后放一段代码,供参考(里面的v_uv实在没有耐心写了,就写了两个面)

    import numpy as np
    import open3d as o3d

    vert=[[0,0,0],[0,1,0],[1,1,0],[1,0,0],
          [0,0,1],[0,1,1],[1,1,1],[1,0,1]]

    faces=[[0, 1, 2], [0, 2, 3], [6, 5, 4],
           [7, 6, 4], [5, 1, 0], [0, 4, 5], [3, 2, 6],
           [6, 7, 3], [0, 3, 7], [0, 7, 4], [1, 5, 6],
           [1, 6, 2]]


    m=o3d.geometry.TriangleMesh(o3d.utility.Vector3dVector(vert),
                                o3d.utility.Vector3iVector(faces))
m.textures
=[o3d.io.read_image('QwIKM.png')] DX,DY=0.5/2,0.66/2 v_uv=[[DX,DY],[DX,2*DY],[2*DX,2*DY], [DX,DY],[2*DX,2*DY],[2*DX,DY], [3*DX,2*DY],[4*DX,2*DY],[4*DX,DY], [3*DX,DY],[3*DX,2*DY],[4*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY], [0,DX],[DX,1],[0,DX], [DX,1],[3*DX,2*DY],[3*DX,DY]] v_uv=np.asarray(v_uv) m.triangle_uvs = o3d.utility.Vector2dVector(v_uv)
m.triangle_material_ids
= o3d.utility.IntVector(np.zeros((len(m.triangles),)).astype(int))
m.compute_vertex_normals()
o3d.visualization.draw_geometries([m])

 

 

posted @ 2021-04-13 16:57  临界稳定  阅读(1663)  评论(0编辑  收藏  举报