Как преобразовать трехмерное облако точек (.ply) в сетку (с гранями и вершинами)?

У меня есть файл трехмерного облака точек с 1 миллионом точек, который мне нужно преобразовать в файл сетки в триместре. Конечная цель здесь состоит в том, чтобы взять облако точек и определить, является ли это облако точек выпуклым или вогнутым (trimesh позволяет мне сделать это, как только я преобразую облако в сетку). Я открыт для других библиотек, чтобы решить эту проблему.

Я пробовал триангуляцию Делоне с помощью scipy, но я просто не могу преобразовать свое pointcloud в правильный формат, чтобы его можно было прочитать с помощью trimesh.

import open3d as o3d
import numpy as np
import trimesh
from scipy.spatial import Delaunay


pointcloud = o3d.io.read_triangle_mesh("pointcloud.ply")
points = np.array(pointcloud.points)
triangle_mesh = Delaunay(points)
#  How do i include triangle_mesh from Delaunay triangulation into processing the mesh file?
mesh = trimesh.load("pointcloud.ply")
print(trimesh.convex.is_convex(mesh))

ошибка

geometry::TriangleMesh appears to be a geometry::PointCloud (only contains vertices, but no triangles).
geometry::TriangleMesh with 1390073 points and 0 triangles.
expected = (faces.shape[0], faces.shape[1] * 2)
AttributeError: 'NoneType' object has no attribute 'shape'

3 ответа

В Open3d 0.8.0.0 теперь реализован алгоритм вращения катящегося шара для восстановления сетки из облака точек.

Я решил проблему создания тримеша из облака точек, используя следующее:

import open3d as o3d
import trimesh
import numpy as np

pcd = o3d.io.read_point_cloud("pointcloud.ply")
pcd.estimate_normals()

# estimate radius for rolling ball
distances = pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 1.5 * avg_dist   

mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
           pcd,
           o3d.utility.DoubleVector([radius, radius * 2]))

# create the triangular mesh with the vertices and faces from open3d
tri_mesh = trimesh.Trimesh(np.asarray(mesh.vertices), np.asarray(mesh.triangles),
                          vertex_normals=np.asarray(mesh.vertex_normals))

trimesh.convex.is_convex(tri_mesh)

просто узнать, что на самом деле делает эта строка кода? Он вызывает функцию с облаком точек, но что означает двойное векторное сечение? - o3d.utility.DoubleVector([радиус, радиус * 2])).

mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(pcd, o3d.utility.DoubleVector([радиус, радиус * 2]))

Чтобы сохранить сетку после следующего ответа /questions/49786482/kak-preobrazovat-trehmernoe-oblako-tochek-ply-v-setku-s-granyami-i-vershinami/55030035#55030035 , используйте параметры экспорта тримеши:

      trimesh.exchange.export.export_mesh(tri_mesh, 'output file path.ply .obj etc..')

https://trimsh.org/trimesh.exchange.ply.html

Если вы хотите сохранить цвета в тримеше, внесите это изменение:

      tri_mesh = trimesh.Trimesh(....., vertex_colors = np.asarray(mesh.vertex_colors))

https://trimsh.org/trimesh.base.html

В качестве альтернативы вы можете напрямую сохранить сетку, используя сам open3d:

o3d.io.write_triangle_mesh('file path .ply or .obj etc..', mesh, write_ascii=True (if needed as text and not binary file), compressed=False, print_progress=False)

Здесь также сохраняется цвет сетки, если он присутствует внутри переменной сетки.

http://www.open3d.org/docs/release/python_api/open3d.io.write_point_cloud.html#open3d.io.write_point_cloud

Другие вопросы по тегам