簡體   English   中英

實時向點雲添加新點 - Open3D

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

我正在使用 Open3D 可視化 Python 中的點雲。本質上,我想做的是以編程方式向點雲添加另一個點,然后實時渲染它。

這是我到目前為止所擁有的。 我找不到任何解決方案。

在下面的代碼中,我展示了一種可能的解決方案,但它並不有效。 積分得到添加,第一個關閉后立即打開一個新的 window。 這不是我想要的。 我希望它動態地顯示新點,而無需關閉和再次打開。 以及創建新變量的事實,我認為在處理越來越大的數據集時可能會出現問題

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.points ,可以將新點以交互方式添加和可視化到PointCloud

這是因為當我們使用 numpy arrays 時,我們需要創建一個Vector3dVector實例,它實現了方便的extend方法。 文檔

擴展(* args , ** kwargs

重載 function。

  1. 擴展(自身:open3d.cpu.pybind.utility.Vector3dVector,L:open3d.cpu.pybind.utility.Vector3dVector)->無

通過附加給定列表中的所有項目來擴展列表

  1. 擴展(自我:open3d.cpu.pybind.utility.Vector3dVector,L:可迭代)->無

通過附加給定列表中的所有項目來擴展列表

所以我們可以使用不同的 object 實例,例如ndarraysVector3dVectorlists等。

玩具示例及其結果:

形象權

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 秒)。

使用extend 刪除和創建PointCloud
✔️ 允許互動 ❌ 互動困難
在此處輸入圖像描述 在此處輸入圖像描述
平均執行時間(添加點): 0.590 毫秒 平均執行時間(添加點): 1.550 毫秒

重現代碼:

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

在下面的頁面中,它解釋了如何在不關閉 window 的情況下更新可視化工具。 http://www.open3d.org/docs/release/tutorial/visualization/non_blocking_visualization.html代碼可能如下所示:

//設置一個新的空pcd

// 初始化可視化器

// for 循環:

//add new points into pcd

//visualizer update as sample code

//完畢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM