简体   繁体   English

实时向点云添加新点 - Open3D

[英]Adding new points to point cloud in real time - Open3D

I am using Open3D to visualize point clouds in Python. Essentially, what I want to do is add another point to the point cloud programmatically and then render it in real time.我正在使用 Open3D 可视化 Python 中的点云。本质上,我想做的是以编程方式向点云添加另一个点,然后实时渲染它。

This is what I have so far.这是我到目前为止所拥有的。 I could not find any solution to this.我找不到任何解决方案。

In the code below, I show one possible solution, but it is not effective.在下面的代码中,我展示了一种可能的解决方案,但它并不有效。 The points get added and a new window is opened as soon as the first one is closed.积分得到添加,第一个关闭后立即打开一个新的 window。 This is not what I want.这不是我想要的。 I want it to dynamically show new points, without closing and opening again.我希望它动态地显示新点,而无需关闭和再次打开。 As well as the fact that a new variable is created, which I think can be problematic when working with larger and larger data sets以及创建新变量的事实,我认为在处理越来越大的数据集时可能会出现问题

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])

Is there any possible solution to this?有什么可能的解决方案吗?

If not, what other libraries can I look at that has the ability to render new incoming points in real time.如果没有,我可以看看还有哪些库具有实时渲染新传入点的能力。

New points can be added and visualized interactively to a PointCloud by extending PointCloud.points with the new coordinates.通过使用新坐标扩展PointCloud.points ,可以将新点以交互方式添加和可视化到PointCloud

This is because when we use numpy arrays, we need to create a Vector3dVector isntance which has the convenient method extend implemented.这是因为当我们使用 numpy arrays 时,我们需要创建一个Vector3dVector实例,它实现了方便的extend方法。 From the docs :文档

extend (* args , ** kwargs )扩展(* args , ** kwargs

Overloaded function.重载 function。

  1. extend(self: open3d.cpu.pybind.utility.Vector3dVector, L: open3d.cpu.pybind.utility.Vector3dVector) -> None扩展(自身:open3d.cpu.pybind.utility.Vector3dVector,L:open3d.cpu.pybind.utility.Vector3dVector)->无

Extend the list by appending all the items in the given list通过附加给定列表中的所有项目来扩展列表

  1. extend(self: open3d.cpu.pybind.utility.Vector3dVector, L: Iterable) -> None扩展(自我:open3d.cpu.pybind.utility.Vector3dVector,L:可迭代)->无

Extend the list by appending all the items in the given list通过附加给定列表中的所有项目来扩展列表

So we can use different object instances eg ndarrays , Vector3dVector , lists etc.所以我们可以使用不同的 object 实例,例如ndarraysVector3dVectorlists等。

A toy example and its result:玩具示例及其结果:

形象权

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()

Why not create an updated geometry and remove the old one?为什么不创建更新的几何体并删除旧的几何体?

For completeness, other (which I believe to be not better) alternative approach could consist on the following steps:为了完整起见,其他(我认为不是更好的)替代方法可能包括以下步骤:

  1. Remove the current PointCloud移除当前PointCloud
  2. concatenate the new points as in the OP's question按照OP的问题连接新点
  3. Create new Pointcloud and add it to the visualizer.创建新的Pointcloud并将其添加到可视化工具。

This yields worse perfomance and barely allows interaction with the visualization.这会产生更差的性能,并且几乎不允许与可视化进行交互。

To see this, let's have a look to the following comparison, with the same settings (code below).要了解这一点,让我们看一下下面的比较,使用相同的设置(下面的代码)。 Both versions run the same time (~10 secs).两个版本同时运行(约 10 秒)。

Using extend使用extend Removing and creating PointCloud删除和创建PointCloud
✔️ Allows interaction ✔️ 允许互动 ❌ Difficult interaction ❌ 互动困难
在此处输入图像描述 在此处输入图像描述
Mean execution time (for adding points): 0.590 ms平均执行时间(添加点): 0.590 毫秒 Mean execution time (for adding points): 1.550 ms平均执行时间(添加点): 1.550 毫秒

Code to reproduce:重现代码:

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()

In below page, it explains how to update visualizer without close the window.在下面的页面中,它解释了如何在不关闭 window 的情况下更新可视化工具。 http://www.open3d.org/docs/release/tutorial/visualization/non_blocking_visualization.html Code may look like below: http://www.open3d.org/docs/release/tutorial/visualization/non_blocking_visualization.html代码可能如下所示:

// set up an new empty pcd //设置一个新的空pcd

// init visualizer // 初始化可视化器

// for loop: // for 循环:

//add new points into pcd

//visualizer update as sample code

//done //完毕

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM