简体   繁体   English

如何使用 Open3D 创建带有点云更新的基本 gui?

[英]How to create a basic gui with pointcloud updates using Open3D?

I'm updating a point cloud from a depth camera stream and I'd like to create a basic UI for a bounding box to crop the point cloud.我正在从深度相机 stream 更新点云,我想为边界框创建一个基本 UI 以裁剪点云。

I've made progress using open3d.visualization.VisualizerWithKeyCallback but I haven't figured out a way to get access to the window it creates.我在使用open3d.visualization.VisualizerWithKeyCallback方面取得了进展,但我还没有找到访问它创建的 window 的方法。 (VisualizerWithKeyCallback's create_window() simply returns a boolean). (VisualizerWithKeyCallback 的create_window()只返回一个布尔值)。

I've also tried adapting the Open3D video example , however it's unclear how I would adapt the add_geometry() / update_geometry() approach I used with VisualizerWithKeyCallback as Open3DScene works differently.我也尝试过调整Open3D 视频示例,但不清楚如何调整我与VisualizerWithKeyCallback一起使用的add_geometry() / update_geometry()方法,因为Open3DScene工作方式不同。

For example, here's how I've attempted to add the pointcloud:例如,这是我尝试添加点云的方式:

def _update_thread(self):
        # This is NOT the UI thread, need to call post_to_main_thread() to update
        # the scene or any part of the UI.
        while not self.is_done:
            time.sleep(0.100)

            if new_frame_is_valid:
                self.point_cloud_o3d.points = o3d.utility.Vector3dVector(points_np)

                
            # Update the images. This must be done on the UI thread.
            def update():
                if self.frame_count == 1:
                    self.widget3d.scene.add_geometry('original point cloud', self.point_cloud_o3d, self.lit)
                    print('added geometry')
                
            if not self.is_done:
                gui.Application.instance.post_to_main_thread(
                    self.window, update)

            self.frame_count += 1

This results in it appears to be blank window which turns black whenever I try to zoom/rotate.这导致它看起来是空白的 window ,每当我尝试缩放/旋转时它都会变黑。

Additionally I've thought about using the multiple_windows example however this simply crashes with my setup (Windows 11, Python 3.6.4, Open3D 0.15.1).此外,我考虑过使用multiple_windows 示例,但这只是在我的设置(Windows 11、Python 3.6.4、Open3D 0.15.1)中崩溃。

What's the simplest method of creating a basic UI using Open3D using a point cloud that needs constant updating (eg from a live depth camera)?使用需要不断更新的点云(例如来自实时深度相机)使用 Open3D 创建基本 UI 的最简单方法是什么?

I found a working answer in this Open3D github issue .我在这个Open3D github 问题中找到了一个有效的答案。

For reference, here's a modified version:作为参考,这里有一个修改版本:

import numpy as np
import open3d as o3d

class Viewer3D(object):

    def __init__(self, title):
        app = o3d.visualization.gui.Application.instance
        app.initialize()

        self.main_vis = o3d.visualization.O3DVisualizer(title)
        app.add_window(self.main_vis)
        
        self.setup_depth_streaming()
        self.setup_point_clouds()
        self.setup_o3d_scene()

    def setup_depth_streaming(self):
        # TODO: setup your depth / point cloud streaming source here
        pass

    def setup_point_clouds(self):
        # setup an empty point cloud to be later populated with live data
        self.point_cloud_o3d = o3d.geometry.PointCloud()
        # the name is necessary to remove from the scene
        self.point_cloud_o3d_name = "point cloud"
        
    def update_point_clouds(self):
        # update your point cloud data here: convert depth to point cloud / filter / etc.
        pass

    def setup_o3d_scene(self):
        self.main_vis.add_geometry(self.point_cloud_o3d_name, self.point_cloud_o3d)
        self.main_vis.reset_camera_to_default()
        # center, eye, up
        self.main_vis.setup_camera(60,
                                    [4, 2, 5],
                                    [0, 0, -1.5],
                                    [0, 1, 0])

    def update_o3d_scene(self):
        self.main_vis.remove_geometry(self.point_cloud_o3d_name)
        self.main_vis.add_geometry(self.point_cloud_o3d_name, self.point_cloud_o3d)

    def run_one_tick(self):
        app = o3d.visualization.gui.Application.instance
        tick_return = app.run_one_tick()
        if tick_return:
            self.main_vis.post_redraw()
        return tick_return

viewer3d = Viewer3D("point cloud gui")

try:
    while True:
        # Step 1) Perturb the cloud with a random walk to simulate an actual read
        # (based on https://github.com/isl-org/Open3D/blob/master/examples/python/visualization/multiple_windows.py)
        viewer3d.update_point_clouds()
        # Step 2) Update the cloud and tick the GUI application
        viewer3d.update_o3d_scene()
        viewer3d.run_one_tick()
except Exception as e:
    print(e)

This is not perfect, but it's a start in terms of getting a point cloud to update and having a window reference ( main_vis ) to add controls to.这并不完美,但它是更新点云并拥有 window 参考 ( main_vis ) 以添加控件的开始。

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

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