我想在 Python 中从点云生成网格
I want to generate a mesh from a point cloud in Python
我有一个来自人体不同部位的点云,比如一只眼睛,我想做一个网格。我尝试使用 Mayavi 和 Delaunay,但我没有得到好的网格。云点完全混乱。
我在 .npz 文件中有我的点云
使用 Mayavi
然后我想将我的模型保存在 obj 或 stl 文件中,但首先我想生成网格。
你推荐我用什么,我需要一个特殊的库吗?
如果你的点是 "are in total disorder",并且你想生成一个网格,那么你需要从点云到网格的某种结构化网格点进行一些插值..
在二维情况下,matplotlib 的三角剖分可以提供帮助:
matplotlib's triangulation 2dim.
在 3 维情况下有 2 个选项。根据数据,您可能希望将它们插值到 3 维表面。那么 matplotlib's trisurf3d 可以帮上忙。
如果您需要 3 维体积网格,那么您可能需要寻找 FEM(有限元)网格,例如FEnics
可以找到使用 scipy 插值 3 维场进行轮廓绘制的示例 here
你试过这个例子吗? https://docs.enthought.com/mayavi/mayavi/auto/example_surface_from_irregular_data.html
相关部分在这里
# Visualize the points
pts = mlab.points3d(x, y, z, z, scale_mode='none', scale_factor=0.2)
# Create and visualize the mesh
mesh = mlab.pipeline.delaunay2d(pts)
surf = mlab.pipeline.surface(mesh)
数据
让我们使用欧洲的首都。我们用 Pandas:
从 Excel 读入它们
import pandas as pd
dg0 = pd.read_excel('psc_StaedteEuropa_coord.xlsx') # ,header=None
dg0.head()
City Inhabit xK yK
0 Andorra 24574.0 42.506939 1.521247
1 Athen 664046.0 37.984149 23.727984
2 Belgrad 1373651.0 44.817813 20.456897
3 Berlin 3538652.0 52.517037 13.388860
4 Bern 122658.0 46.948271 7.451451
三角网格化
我们使用 Scipy for that. For a 3-dim example see HERE and HERE or here(CGAL 有一个 Python 包装器)
import numpy as np
from scipy.spatial import Delaunay
yk, xk, city = np.array(dg0['xK']), np.array(dg0['yK']), np.array(dg0['City'])
X1 = np.vstack((xk,yk)).T
tri = Delaunay(X1)
图形
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
#--- grafics -------
figX = 25; figY = 18
fig1 = plt.figure(figsize=(figX, figY), facecolor='white')
myProjection = ccrs.PlateCarree()
ax = plt.axes(projection=myProjection)
ax.stock_img()
ax.set_extent([-25, 40, 35, 65], crs=myProjection)
plt.triplot(X1[:,0], X1[:,1], tri.simplices.copy(), color='r', linestyle='-',lw=2)
plt.plot(X1[:,0], X1[:,1], 's', color='w')
plt.scatter(xk,yk,s=1000,c='w')
for i, txt in enumerate(city):
ax.annotate(txt, (X1[i,0], X1[i,1]), color='k', fontweight='bold')
plt.savefig('Europe_A.png')
plt.show()
您可以使用pyvista 进行3D 插值。但是,您需要手动使用控制两点链接距离的 alpha 参数。
import numpy as np
import pyvista as pv
# points is a 3D numpy array (n_points, 3) coordinates of a sphere
cloud = pv.PolyData(points)
cloud.plot()
volume = cloud.delaunay_3d(alpha=2.)
shell = volume.extract_geometry()
shell.plot()
我有一个来自人体不同部位的点云,比如一只眼睛,我想做一个网格。我尝试使用 Mayavi 和 Delaunay,但我没有得到好的网格。云点完全混乱。 我在 .npz 文件中有我的点云
使用 Mayavi
然后我想将我的模型保存在 obj 或 stl 文件中,但首先我想生成网格。 你推荐我用什么,我需要一个特殊的库吗?
如果你的点是 "are in total disorder",并且你想生成一个网格,那么你需要从点云到网格的某种结构化网格点进行一些插值..
在二维情况下,matplotlib 的三角剖分可以提供帮助: matplotlib's triangulation 2dim.
在 3 维情况下有 2 个选项。根据数据,您可能希望将它们插值到 3 维表面。那么 matplotlib's trisurf3d 可以帮上忙。
如果您需要 3 维体积网格,那么您可能需要寻找 FEM(有限元)网格,例如FEnics
可以找到使用 scipy 插值 3 维场进行轮廓绘制的示例 here
你试过这个例子吗? https://docs.enthought.com/mayavi/mayavi/auto/example_surface_from_irregular_data.html
相关部分在这里
# Visualize the points
pts = mlab.points3d(x, y, z, z, scale_mode='none', scale_factor=0.2)
# Create and visualize the mesh
mesh = mlab.pipeline.delaunay2d(pts)
surf = mlab.pipeline.surface(mesh)
让我们使用欧洲的首都。我们用 Pandas:
从 Excel 读入它们import pandas as pd
dg0 = pd.read_excel('psc_StaedteEuropa_coord.xlsx') # ,header=None
dg0.head()
City Inhabit xK yK
0 Andorra 24574.0 42.506939 1.521247
1 Athen 664046.0 37.984149 23.727984
2 Belgrad 1373651.0 44.817813 20.456897
3 Berlin 3538652.0 52.517037 13.388860
4 Bern 122658.0 46.948271 7.451451
三角网格化
我们使用 Scipy for that. For a 3-dim example see HERE and HERE or here(CGAL 有一个 Python 包装器)
import numpy as np
from scipy.spatial import Delaunay
yk, xk, city = np.array(dg0['xK']), np.array(dg0['yK']), np.array(dg0['City'])
X1 = np.vstack((xk,yk)).T
tri = Delaunay(X1)
图形
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
#--- grafics -------
figX = 25; figY = 18
fig1 = plt.figure(figsize=(figX, figY), facecolor='white')
myProjection = ccrs.PlateCarree()
ax = plt.axes(projection=myProjection)
ax.stock_img()
ax.set_extent([-25, 40, 35, 65], crs=myProjection)
plt.triplot(X1[:,0], X1[:,1], tri.simplices.copy(), color='r', linestyle='-',lw=2)
plt.plot(X1[:,0], X1[:,1], 's', color='w')
plt.scatter(xk,yk,s=1000,c='w')
for i, txt in enumerate(city):
ax.annotate(txt, (X1[i,0], X1[i,1]), color='k', fontweight='bold')
plt.savefig('Europe_A.png')
plt.show()
您可以使用pyvista 进行3D 插值。但是,您需要手动使用控制两点链接距离的 alpha 参数。
import numpy as np
import pyvista as pv
# points is a 3D numpy array (n_points, 3) coordinates of a sphere
cloud = pv.PolyData(points)
cloud.plot()
volume = cloud.delaunay_3d(alpha=2.)
shell = volume.extract_geometry()
shell.plot()