如何在open3d.visualization.O3DVisualizer类中添加另一个面板或窗口?
背景
我正在尝试为concept-graphs映射系统的映射脚本添加一个图形用户界面(gui)。现在代码看起来很乱,但你可以在这里查看。
这个映射系统需要输入RGB图像、深度图像和位姿,然后逐步构建一个基于物体的3D地图,同时还编码了一些语义特征。我希望能够可视化整个地图构建的过程,这样我就可以在构建的同时检查地图和调试问题。
所以我查看了一些Python示例,发现multiple_windows.py这个示例似乎有我想要的功能,可以可视化物体的点云和边界框等。我可以做到这一点,到目前为止效果很好。
问题
问题是我还想显示更多信息。我希望在地图旁边的面板中看到:当前的RGB图像、当前的深度图像、当前的标注图像、当前的帧、当前的物体数量等等。
我希望它能像文档中的dense_slam_gui.py示例那样。
我尝试了很多方法,但似乎无法在o3d.visualization.O3DVisualizer中添加一个面板,也无法添加另一个窗口或其他可以同时更新的东西。如果不是同一个窗口也没关系,我只想在地图旁边的某个地方看到这些信息,这样可以帮助我改进映射系统。
我的代码
这里有一些相关的代码片段。
这是我创建应用程序的方式(如你所见,我尝试了添加另一个窗口或面板的各种方法,但到目前为止所有尝试都导致了一些错误)
def run(self):
app = o3d.visualization.gui.Application.instance
app.initialize()
self.main_vis = o3d.visualization.O3DVisualizer(
"Open3D - Multi-Window Demo")
self.main_vis.add_action("Take snapshot in new window",
self.on_snapshot)
self.main_vis.add_action("Pause/Resume updates", lambda vis: self.toggle_pause())
self.main_vis.set_on_close(self.on_main_window_closing)
app.add_window(self.main_vis)
# app.add_window(self.images_window)
# # Setup the secondary window for images
# # self.setup_image_display_window()
# # self.image_window = app.create_window("RGB and Depth Images", 640, 480)
# self.image_window = gui.Application.instance.create_window("RGB and Depth Images", 640, 480)
# # self.image_window.create_window()
# # self.image_window = o3d.visualization.Visualizer("RGB and Depth Images", 640, 480)
# self.layout = o3d.visualization.gui.Vert(0, o3d.visualization.gui.Margins(10))
# self.image_window.add_child(self.layout)
# # Create image widgets
# self.rgb_widget = o3d.visualization.gui.ImageWidget()
# self.depth_widget = o3d.visualization.gui.ImageWidget()
# # Add image widgets to the layout
# self.layout.add_child(self.rgb_widget)
# self.layout.add_child(self.depth_widget)
# app.add_window(self.image_window)
self.snapshot_pos = (self.main_vis.os_frame.x, self.main_vis.os_frame.y)
threading.Thread(target=self.update_thread).start()
app.run()
这是我进行更新线程的方式:
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.
... lots of code, basically the whole mapping script ...
def my_update_cloud():
# Remove previous objects
for obj_name in self.prev_obj_names:
self.main_vis.remove_geometry(obj_name)
self.prev_obj_names = []
# Remove previous bounding boxes
for bbox_name in self.prev_bbox_names:
self.main_vis.remove_geometry(bbox_name)
self.prev_bbox_names = []
# Add the new objects and bounding boxes
for obj_num, obj in enumerate(self.objects):
obj_label = f"{obj['curr_obj_num']}_{obj['class_name']}"
obj_name = f"obj_{obj_label}"
bbox_name = f"bbox_{obj_label}"
self.prev_obj_names.append(obj_name)
self.main_vis.add_geometry(obj_name, obj['pcd'])
self.prev_bbox_names.append(bbox_name)
self.main_vis.add_geometry(bbox_name, obj['bbox'] )
if self.is_done: # might have changed while sleeping
break
o3d.visualization.gui.Application.instance.post_to_main_thread(
self.main_vis, my_update_cloud)
我想做的事情
首先,我只想能够更新显示当前的RGB和深度图像,也许还有当前的帧编号?我想象的效果是:
def update_images(self):
# Convert numpy images to Open3D images and update widgets
o3d_rgb_image = o3d.geometry.Image(self.curr_image_rgb)
o3d_depth_image = o3d.geometry.Image((self.curr_depth_array / self.curr_depth_array.max() * 255).astype(np.uint8)) # Example normalization
self.rgb_widget.update_image(o3d_rgb_image)
self.depth_widget.update_image(o3d_depth_image)
# and then in the main update thread loop I would do
self.curr_image_rgb = image_rgb
self.curr_depth_array = depth_array
o3d.visualization.gui.Application.instance.post_to_main_thread(
self.image_window, self.update_images())
我希望你能理解我想要实现的目标。如果有人能给我指个方向,我将非常感激。我已经在网上搜索并询问了很多,但都没有找到解决办法。
谢谢你们的时间和帮助。
0 个回答
暂无回答