实时向点云添加新点 - Open3D

2023-12-31

我正在使用 Open3D 在 Python 中可视化点云。本质上,我想做的是以编程方式向点云添加另一个点,然后实时渲染它。

这是我到目前为止所拥有的。我找不到任何解决方案。

在下面的代码中,我展示了一种可能的解决方案,但它并不有效。第一个窗口关闭后,点将被添加并打开一个新窗口。这不是我想要的。我希望它能够动态显示新点,而无需再次关闭和打开。以及创建一个新变量的事实,我认为在处理越来越大的数据集时可能会出现问题

import open3d as o3d
import numpy as np

#Create two random points
randomPoints = np.random.rand(2, 3)

pointSet = o3d.geometry.PointCloud()

pointSet.points = o3d.utility.Vector3dVector(randomPoints)

#Visualize the two random points
o3d.visualization.draw_geometries([pointSet])

#Here I want to add more points to the pointSet
#This solution does not work effective

#Create another random set
p1 = np.random.rand(3, 3)

p2 = np.concatenate((pointSet.points, p1), axis=0)

pointSet2 = o3d.geometry.PointCloud()

pointSet2.points = o3d.utility.Vector3dVector(p2)

o3d.visualization.draw_geometries([pointSet2])

有没有可能解决这个问题?

如果没有,我还可以查看哪些其他库能够实时渲染新的传入点。


可以交互式地添加新点并使其可视化PointCloud通过扩展PointCloud.points与新坐标。

这是因为当我们使用numpy数组时,我们需要创建一个Vector3dVector有方便方法的实例extend实施的。来自docs http://www.open3d.org/docs/release/python_api/open3d.utility.Vector3dVector.html#open3d.utility.Vector3dVector.extend:

extend(*args, **kwargs)

重载功能。

  1. 扩展(自我:open3d.cpu.pybind.utility.Vector3dVector,L: open3d.cpu.pybind.utility.Vector3dVector) -> 无

通过附加给定列表中的所有项目来扩展列表

  1. 扩展(自我:open3d.cpu.pybind.utility.Vector3dVector,L:可迭代)-> 没有任何

通过附加给定列表中的所有项目来扩展列表

所以我们可以使用不同的对象实例,例如ndarrays, Vector3dVector, lists etc.

一个玩具示例及其结果:

import open3d as o3d
import numpy as np
import time


# create visualizer and window.
vis = o3d.visualization.Visualizer()
vis.create_window(height=480, width=640)

# initialize pointcloud instance.
pcd = o3d.geometry.PointCloud()
# *optionally* add initial points
points = np.random.rand(10, 3)
pcd.points = o3d.utility.Vector3dVector(points)

# include it in the visualizer before non-blocking visualization.
vis.add_geometry(pcd)

# to add new points each dt secs.
dt = 0.01
# number of points that will be added
n_new = 10

previous_t = time.time()

# run non-blocking visualization. 
# To exit, press 'q' or click the 'x' of the window.
keep_running = True
while keep_running:
    
    if time.time() - previous_t > dt:
        # Options (uncomment each to try them out):
        # 1) extend with ndarrays.
        pcd.points.extend(np.random.rand(n_new, 3))
        
        # 2) extend with Vector3dVector instances.
        # pcd.points.extend(
        #     o3d.utility.Vector3dVector(np.random.rand(n_new, 3)))
        
        # 3) other iterables, e.g
        # pcd.points.extend(np.random.rand(n_new, 3).tolist())
        
        vis.update_geometry(pcd)
        previous_t = time.time()

    keep_running = vis.poll_events()
    vis.update_renderer()

vis.destroy_window()

为什么不创建更新的几何图形并删除旧的几何图形呢?

为了完整起见,其他(我认为不是更好)替代方法可以包括以下步骤:

  1. 删除当前的PointCloud
  2. 连接OP问题中的新点
  3. 创建新的Pointcloud并将其添加到可视化工具中。

这会产生更差的性能,并且几乎不允许与可视化进行交互。

为了了解这一点,让我们看看下面的比较,使用相同的设置(下面的代码)。两个版本运行时间相同(约 10 秒)。

Using extend Removing and creating PointCloud
✔️ Allows interaction ❌ Difficult interaction
enter image description here enter image description here
Mean execution time (for adding points): 0.590 ms Mean execution time (for adding points): 1.550 ms

重现代码:

import open3d as o3d
import numpy as np
import time

# Global settings.
dt = 3e-2 # to add new points each dt secs.
t_total = 10 # total time to run this script.
n_new = 10 # number of points that will be added each iteration.

#---
# 1st, using extend. Run non-blocking visualization.

# create visualizer and window.
vis = o3d.visualization.Visualizer()
vis.create_window(height=480, width=640)

# initialize pointcloud instance.
pcd = o3d.geometry.PointCloud()
# *optionally* add initial points
points = np.random.rand(10, 3)
pcd.points = o3d.utility.Vector3dVector(points)
# include it in the visualizer before non-blocking visualization.
vis.add_geometry(pcd)

exec_times = []

current_t = time.time()
t0 = current_t

while current_t - t0 < t_total:

    previous_t = time.time()

    while current_t - previous_t < dt:
        s = time.time()

        # Options (uncomment each to try it out):
        # 1) extend with ndarrays.
        pcd.points.extend(np.random.rand(n_new, 3))

        # 2) extend with Vector3dVector instances.
        # pcd.points.extend(
        #     o3d.utility.Vector3dVector(np.random.rand(n_new, 3)))

        # 3) other iterables, e.g
        # pcd.points.extend(np.random.rand(n_new, 3).tolist())

        vis.update_geometry(pcd)

        current_t = time.time()
        exec_times.append(time.time() - s)

    vis.poll_events()
    vis.update_renderer()

print(f"Using extend\t\t\t# Points: {len(pcd.points)},\n"
      f"\t\t\t\t\t\tMean execution time:{np.mean(exec_times):.5f}")

vis.destroy_window()

# ---
# 2nd, using remove + create + add PointCloud. Run non-blocking visualization.

# create visualizer and window.
vis = o3d.visualization.Visualizer()
vis.create_window(height=480, width=640)

# initialize pointcloud instance.
pcd = o3d.geometry.PointCloud()
points = np.random.rand(10, 3)
pcd.points = o3d.utility.Vector3dVector(points)
vis.add_geometry(pcd)

exec_times = []

current_t = time.time()
t0 = current_t
previous_t = current_t

while current_t - t0 < t_total:

    previous_t = time.time()

    while current_t - previous_t < dt:
        s = time.time()

        # remove, create and add new geometry.
        vis.remove_geometry(pcd)
        pcd = o3d.geometry.PointCloud()
        points = np.concatenate((points, np.random.rand(n_new, 3)))
        pcd.points = o3d.utility.Vector3dVector(points)
        vis.add_geometry(pcd)

        current_t = time.time()
        exec_times.append(time.time() - s)

    current_t = time.time()

    vis.poll_events()
    vis.update_renderer()

print(f"Without using extend\t# Points: {len(pcd.points)},\n"
      f"\t\t\t\t\t\tMean execution time:{np.mean(exec_times):.5f}")

vis.destroy_window()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实时向点云添加新点 - Open3D 的相关文章

随机推荐