【问题标题】:I want to generate a mesh from a point cloud in Python我想从 Python 中的点云生成网格
【发布时间】:2019-02-27 05:33:34
【问题描述】:

我有一个来自人体不同部位的点云,比如眼睛,我想做一个网格。我尝试使用 Mayavi 和 Delaunay,但没有得到好的网格。云的点完全混乱。 我在 .npz 文件中有我的点云

使用 Mayavi

然后我想将我的模型保存在 obj 或 stl 文件中,但首先我想生成网格。 你推荐我用什么,我需要一个特殊的库吗?

【问题讨论】:

    标签: python-3.x numpy mesh point-clouds mayavi


    【解决方案1】:

    您可以使用 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()
    

    【讨论】:

    • 这无疑是最好的答案,不过我目前正在为 PyVista 文档苦苦挣扎,除了您推荐的官方网站之外,还有其他资源吗?
    【解决方案2】:

    如果您的点“完全无序”,并且如果您想生成一个网格,那么您需要从点云到网格的某种结构化网格点进行一些插值..

    在二维情况下,matplotlib 的三角测量可以提供帮助: matplotlib's triangulation 2dim.

    在 3 维情况下,有 2 个选项。根据数据,您可能希望将它们内插到 3 维表面。那么matplotlib's trisurf3d 可以帮上忙。

    如果您需要 3 维体积网格,那么您可能需要寻找 FEM(有限元)网格,例如FEnics

    可以在here找到使用 scipy 插值 3 维字段以进行轮廓绘制的示例

    【讨论】:

    • 谢谢,我要检查这些链接,我对这个主题了解不多,有什么文档可以指导我吗?
    • 我也没有更多文档(您对哪种类型的插值/网格感兴趣?)。通常我会尝试下载一个完整的可运行示例并逐步修改代码。
    • 你有可用的数据集来进行一些试验吗?
    • 我想使用四面体化或样条线来实现,但我无法从我的点云中找到任何方法。是的,当然我有一个 npz 格式的数据集。
    • 我还有一个问题,我可以使用 geomdl 使用 nurb 函数生成网格吗?
    【解决方案3】:

    数据

    让我们使用欧洲的首都。我们使用 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。对于 3-dim 示例,请参阅 HEREHEREhere(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()
    

    【讨论】:

      【解决方案4】:

      你试过这个例子吗? 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)
      

      【讨论】:

      • 我已经试过了,第二张图就是结果。我认为没有这么简单的方法来制作这个网格。我也有人体的其他部位,比如头骨和大脑。
      猜你喜欢
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 2018-01-29
      相关资源
      最近更新 更多