Open3D Surface reconstruction 表面重建

这篇具有很好参考价值的文章主要介绍了Open3D Surface reconstruction 表面重建。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Surface reconstruction 表面重建

在许多情况下,我们希望生成密集的3D几何体,即三角形网格(triangle mesh)。然而,从多视点立体方法或深度传感器中,我们只能获得非结构化的点云。要从此非结构化输入中获取三角形网格,我们需要执行表面重建。在文献中存在几种方法,Open3D目前实现了以下方法:
Alpha shapes(阿尔法形状)
Ball pivoting(球旋转)
Poisson surface reconstruction(泊松表面重建)

Alpha shapes

阿尔法形状[Edelsbrunner1983]是凸壳的推广。正如这里[https://graphics.stanford.edu/courses/cs268-11-spring/handouts/AlphaShapes/as_fisher.pdf]所描述的,人们可以直观地将阿尔法形状想象成:想象一大堆冰淇淋,其中包含这些点作为硬巧克力块。使用其中一个球形冰淇淋勺子,我们雕刻出冰淇淋块的所有部分,我们可以在不碰到巧克力块的情况下到达,从而甚至在内部雕刻出孔洞(例如,只需从外面移动勺子就无法到达的部分)。我们最终将得到一个由大写字母、弧线和点边界的(不一定是凸的)物体。如果我们现在将所有圆面拉直为三角形和线段,则可以直观地描述所谓的 alpha 形状S。

Open3D 实现了涉及权衡参数alpha的方法create_from_point_cloud_alpha_shape。

bunny = o3d.data.BunnyMesh()
mesh = o3d.io.read_triangle_mesh(bunny.path)
mesh.compute_vertex_normals()

pcd = mesh.sample_points_poisson_disk(750)
o3d.visualization.draw_geometries([pcd])
alpha = 0.03
print(f"alpha={alpha:.3f}")
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd, alpha)
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh], mesh_show_back_face=True)

该实现基于点云的凸壳。如果我们想从给定的点云中计算多个 alpha 形状,那么我们可以通过只计算凸壳一次并将其传递给 create_from_point_cloud_alpha_shape来节省一些计算。

tetra_mesh, pt_map = o3d.geometry.TetraMesh.create_from_point_cloud(pcd)
for alpha in np.logspace(np.log10(0.5), np.log10(0.01), num=4):
    print(f"alpha={alpha:.3f}")
    mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(
        pcd, alpha, tetra_mesh, pt_map)
    mesh.compute_vertex_normals()
    o3d.visualization.draw_geometries([mesh], mesh_show_back_face=True)

Ball pivoting

球枢轴算法(ball pivoting algorithm,BPA)[Bernardini1999]是一种与阿尔法形状相关的表面重建方法。直观地说,想想一个具有给定半径的3D球,我们将其落在点云上。如果它击中任何3个点(并且它没有落在这3个点上),它就会创建一个三角形。然后,算法开始从现有三角形的边缘旋转,每次它击中球没有落下的3个点时,我们都会创建另一个三角形。
Open3D 在create_from_point_cloud_ball_pivoting中实现了此方法。该方法接受与在点云上旋转的各个球的半径相对应的参数列表radii。
Note:此方法假设点云具有法线。

bunny = o3d.data.BunnyMesh()
gt_mesh = o3d.io.read_triangle_mesh(bunny.path)
gt_mesh.compute_vertex_normals()
pcd = gt_mesh.sample_points_poisson_disk(3000)
o3d.visualization.draw_geometries([pcd])


radii = [0.005, 0.01, 0.02, 0.04]
rec_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
    pcd, o3d.utility.DoubleVector(radii))
o3d.visualization.draw_geometries([pcd, rec_mesh])

Poisson surface reconstruction

泊松曲面重构方法 [Kazhdan2006] 求解了一个正则化优化问题,得到了一个光滑的曲面。因此,泊松曲面重建可能比上述方法更可取,因为它们会产生非平滑的结果、因为PointCloud点也是所得三角形网格的点vertices,无需任何修改。

Open3D实现了该方法create_from_point_cloud_poisson,该方法基本上是Kazhdan代码的包装器。该函数的一个重要参数depth是定义用于表面重建的八叉树的深度,因此意味着所得三角形网格的分辨率。depth值越高,表示网格具有更多细节。
Note:此方法假设点云具有法线。

import open3d as o3d
eagle_path = r'../data/EaglePointCloud.ply'
pcd = o3d.io.read_point_cloud(eagle_path)

print(pcd)
o3d.visualization.draw_geometries([pcd],
                                  zoom=0.664,
                                  front=[-0.4761, -0.4698, -0.7434],
                                  lookat=[1.8900, 3.2596, 0.9284],
                                  up=[0.2304, -0.8825, 0.4101])


print('run Poisson surface reconstruction')
with o3d.utility.VerbosityContextManager(
        o3d.utility.VerbosityLevel.Debug) as cm:
    mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
        pcd, depth=9)
print(mesh)
o3d.visualization.draw_geometries([mesh],
                                  zoom=0.664,
                                  front=[-0.4761, -0.4698, -0.7434],
                                  lookat=[1.8900, 3.2596, 0.9284],
                                  up=[0.2304, -0.8825, 0.4101])

泊松表面重建也会在低点密度区域创建三角形,甚至推断到某些区域(见上面鹰输出的底部)。函数create_from_point_cloud_poisson具有第二个返回值densities,该值指示每个顶点的密度。低密度值意味着顶点仅由输入点云中的少量点支持。

在下面的代码中,我们使用伪彩色在3D中可视化密度。紫色表示低密度,黄色表示高密度。

print('visualize densities')
densities = np.asarray(densities)
density_colors = plt.get_cmap('plasma')(
    (densities - densities.min()) / (densities.max() - densities.min()))
density_colors = density_colors[:, :3]
density_mesh = o3d.geometry.TriangleMesh()
density_mesh.vertices = mesh.vertices
density_mesh.triangles = mesh.triangles
density_mesh.triangle_normals = mesh.triangle_normals
density_mesh.vertex_colors = o3d.utility.Vector3dVector(density_colors)
o3d.visualization.draw_geometries([density_mesh],
                                  zoom=0.664,
                                  front=[-0.4761, -0.4698, -0.7434],
                                  lookat=[1.8900, 3.2596, 0.9284],
                                  up=[0.2304, -0.8825, 0.4101])

我们可以进一步使用密度值来删除具有低支撑的顶点和三角形。在下面的代码中,我们删除了密度值低于0.01所有密度值的分位数的所有顶点(和连接的三角形)。

print('remove low density vertices')
vertices_to_remove = densities < np.quantile(densities, 0.01)
mesh.remove_vertices_by_mask(vertices_to_remove)
print(mesh)
o3d.visualization.draw_geometries([mesh],
                                  zoom=0.664,
                                  front=[-0.4761, -0.4698, -0.7434],
                                  lookat=[1.8900, 3.2596, 0.9284],
                                  up=[0.2304, -0.8825, 0.4101])

Normal estimation 法线估计

在上面的例子中,我们假设点云具有指向外部的法线。但是,并非所有点云都已附带相关的法线。Open3D 可用estimate_normals估计点云法线,其局部拟合每个 3D 点的平面以推导出法线。但是,估计的法线可能不是一致的。 orient_normals_consistent_tangent_plane使用最小生成树传播法线。文章来源地址https://www.toymoban.com/news/detail-426504.html

bunny = o3d.data.BunnyMesh()
gt_mesh = o3d.io.read_triangle_mesh(bunny.path)

pcd = gt_mesh.sample_points_poisson_disk(5000)
pcd.normals = o3d.utility.Vector3dVector(np.zeros(
    (1, 3)))  # invalidate existing normals

pcd.estimate_normals()
o3d.visualization.draw_geometries([pcd], point_show_normal=True)


pcd.orient_normals_consistent_tangent_plane(100)
o3d.visualization.draw_geometries([pcd], point_show_normal=True)

到了这里,关于Open3D Surface reconstruction 表面重建的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • open3d 0.17.0的open3d.visualization.ViewControl类有bug

    在使用过程中发现 open3d.visualization.ViewControl 的如下方法,在 open3d 0.17.0 环境下不起作用,点云的显示视场还是默认配置;而在 open3d 0.16.0 环境下却正常工作。 rotate set_front set_lookat set_up set_zoom 上述测试代码在如下虚拟环境中进行过测试,均失败。 在如下虚拟环境中正常工作

    2024年02月21日
    浏览(44)
  • Open3D点云数据处理(一):VSCode配置python,并安装open3d教程

    专栏地址:https://blog.csdn.net/weixin_46098577/category_11392993.html 在很久很久以前,我写过这么一篇博客,讲的是open3d点云处理的基本方法。👇 当时是 PyCharm + Anaconda + python3.8 + open3d 0.13 已经是2023年了,现在有了全新版本。目前python由当年的3.8更新到了3.11版本,open3d也从0.13来到了

    2024年02月07日
    浏览(46)
  • 【Open3D可视化——添加标签】:如何在Open3D的可视化窗口中添加文字标签?

    【Open3D可视化——添加标签】:如何在Open3D的可视化窗口中添加文字标签? Open3D是一个基于Python语言开发的跨平台开源工具包,主要用于三维数据处理和可视化。在进行三维数据可视化过程中,往往需要在场景中添加标签来标识物体、点云等信息。本文将介绍如何在Open3D的可

    2024年02月11日
    浏览(41)
  • Open3D学习笔记

    Open3D是一个开源库,它支持处理3D数据的软件的快速开发。Open3D前端在C++和Python中有一些公开的数据结构和算法。后端经过高度优化,并设置为并行化。 PCL也是3D点云数据处理的优秀开源库,在C++平台上表现较好,但是在Python上python-pcl长时间不更新,维护少,不太好用,不建

    2024年02月01日
    浏览(30)
  • Open3D读取文件

    Open3D可以读取点云文件,三角网格文件,也可以读取图片。具体方法如下: 一、点云文件操作         Open3D支持的文件格式有xyz,xyzn,xyzrgb,pts,ply,pcd等文件。读取的方式也非常简单。data = o3d.io.read_point_cloud(\\\"文件名“) 1、读写文件         函数原型如下:    

    2024年02月08日
    浏览(38)
  • 什么是open3D?

    目录 一、说明 二、如何安装open3d?  三、显示点云数据 3.1 显示点云场景数据 3.2 体素下采样 3.3 顶点法线估计         对于点云 处理,这里介绍哦pen3d,该软件和opencv同样是interl公司的产品。         Open3D 是一个开源库,支持快速开发处理 3D 数据的软件。 Open3D 前

    2024年02月03日
    浏览(43)
  • Open3D-读取深度图

           深度图像(Depth Images)也被称为距离影像(Range Image),是指将从图像采集器到场景中各点的距离值作为像素值的图像,它直接反应了 景物可见表面的几何形状 。获取方法有: 激光雷达深度成像法、计算机立体视觉成像、坐标测量机法、莫尔条纹法、结构光法。

    2024年02月13日
    浏览(31)
  • Open3d入门教程

    【英文版】 Open3D Python包通过 PyPI 和 Conda发布。 支持的Python版本: 3.6 3.7 3.8 支持的操作系统: Ubuntu 18.04+ macOS 10.14+ Windows 10 (64-bit) 如果你有其他Python版本(比如 Python 2) 或操作系统,请参考 编译源码 并从源代码处编译Open3D。 Pip (PyPI) 注意: 一般来说,我们建议使用虚拟环境 来集

    2024年02月16日
    浏览(43)
  • open3d io操作

    目录 1. read_image, write_image 2. read_point_cloud, write_point_cloud 3. 深度相机IO操作 4. Mesh文件读取 读取jpg. png. bmp等文件 image_io.py 读写点云pcd, ply等文件 point_cloud_io.py 读取深度相机 realsense_io.py  读取mesh网格数据,ply等文件 triangle_mesh_io.py

    2024年02月03日
    浏览(38)
  • open3d点云平移

    功能简介 open3d中点云的平移函数为:pcd.translate((tx, ty, tz), relative=True)。当relative为True时,(tx, ty, tz)表示点云平移的相对尺度,也就是平移了多少距离。当relative为False时,(tx, ty, tz)表示点云中心(质心)平移到的指定位置。质心可以坐标可以通过pcd.get_center()得到。 代码

    2024年01月22日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包