我使用 open3d 来可视化点云 (*.bin) 和预测的边界框(下面的代码,https://github.com/shangjie-li/pointpillars/blob/master/utils/open3d_vis_utils.py)。该代码显示点云和边界框 1.5 秒,然后关闭当前窗口并在新窗口中显示下一个文件。我想知道如何修改我的代码,以便能够将点云序列可视化为视频(实时),而无需打开/关闭窗口。
import open3d
import torch
import matplotlib
import numpy as np
import time
from . import common_utils, box_utils
box_colormap = {
'Car': (0, 1, 0),
} # RGB
def draw_scenes(points, gt_boxes=None, ref_boxes=None, ref_labels=None,
point_colors=None, point_size=1.0, window_name='Open3D'):
if isinstance(points, torch.Tensor):
points = points.cpu().numpy()
if isinstance(gt_boxes, torch.Tensor):
gt_boxes = gt_boxes.cpu().numpy()
if isinstance(ref_boxes, torch.Tensor):
ref_boxes = ref_boxes.cpu().numpy()
if isinstance(point_colors, torch.Tensor):
point_colors = point_colors.cpu().numpy()
vis = open3d.visualization.Visualizer()
vis.create_window(window_name=window_name, width=1280, height=720)
vis.get_render_option().point_size = point_size
vis.get_render_option().background_color = np.asarray([0.4, 0.4, 0.4])
pts = open3d.geometry.PointCloud()
pts.points = open3d.utility.Vector3dVector(points[:, :3])
vis.add_geometry(pts)
if point_colors is not None:
pts.colors = open3d.utility.Vector3dVector(point_colors)
else:
pts.colors = open3d.utility.Vector3dVector(np.ones((points.shape[0], 3)) * 0.9)
if gt_boxes is not None:
vis = draw_box(vis, gt_boxes, color=(1, 0, 0))
if ref_boxes is not None:
if ref_labels is not None:
vis = draw_box(vis, ref_boxes, ref_labels)
else:
vis = draw_box(vis, ref_boxes, color=(0, 1, 0))
#press esc or q to close the pointcloud window
# vis.run()
# vis.destroy_window()
#close the pointcloud window after 1.5s
vis.poll_events()
vis.update_renderer()
time.sleep(1.5)
vis.destroy_window()
def draw_box(vis, boxes, labels=None, color=(1, 0, 0)):
"""
7 -------- 4
/| /|
6 -------- 5 .
| | | |
. 3 -------- 0
|/ |/
2 -------- 1
Args:
boxes: [x, y, z, dx, dy, dz, heading], (x, y, z) is the box center
labels: [name]
Returns:
"""
for i in range(boxes.shape[0]):
corners3d = box_utils.boxes_to_corners_3d(np.array([boxes[i]]))[0]
edges = np.array([
[0, 1], [1, 2], [2, 3], [3, 0],
[4, 5], [5, 6], [6, 7], [7, 4],
[0, 4], [1, 5], [2, 6], [3, 7],
[0, 5], [1, 4], # heading
])
line_set = open3d.geometry.LineSet()
line_set.points = open3d.utility.Vector3dVector(corners3d)
line_set.lines = open3d.utility.Vector2iVector(edges)
if labels is not None:
line_set.paint_uniform_color(box_colormap[labels[i]])
else:
line_set.paint_uniform_color(color)
vis.add_geometry(line_set)
return vis
我感谢您提前提供的任何帮助。
谢谢,
阿巴斯
阅读此处的官方教程,了解有关非阻塞可视化的信息。下面的代码将展示如何生成新的点云数据并更新
Visualizer
中的点云。这将生成动态可视化。
import time
import numpy as np
import open3d as o3d
# Create a visualization object and window
vis = o3d.visualization.Visualizer()
vis.create_window()
# create pcd object
point_cloud_o3d = o3d.geometry.PointCloud() # Important to use same object for repeated call to update_geometry
dataset = o3d.data.PLYPointCloud()
start_time = time.time()
prev_sec = -1
translation_index = 0
translation_speed = 0.01
first_call = True
while True:
curr_sec = int(time.time() - start_time)
if curr_sec - prev_sec >= 1.0: # Check if 1 second has passed
prev_sec = curr_sec
# Create a sample pointcloud
office = o3d.io.read_point_cloud(dataset.path)
points = np.asarray(office.points) + translation_index * translation_speed
# Modify original pointcloud a little to show a video
# Note - Always edit in-place.
point_cloud_o3d.points = o3d.utility.Vector3dVector(points)
# add or update geometry objects
if first_call:
vis.add_geometry(point_cloud_o3d) # add point cloud
first_call = False # change flag
else:
vis.update_geometry(point_cloud_o3d) # update point cloud
translation_index += 1
# update o3d window
if not vis.poll_events():
break
vis.update_renderer()
vis.close()
vis.destroy_window()
我在 Open3D 学习过程中后期意识到的一件事是
vis.add_geometry(point_cloud_o3d)
将 point_cloud_o3d
的内存绑定到图形管道 (opengl)。问题是,如果您在空几何体(又名 vis.add_geometry(point_cloud_o3d)
)上调用 point_cloud_o3d = o3d.geometry.PointCloud()
,它将不会为 point_cloud_o3d.points
(在 C++ 中属于 std::vector
类型)分配内存。因此,即使您稍后将点添加到点云对象,OpenGL 管道也会绑定到错误的地址。
此外,请参阅 C++ 的相关 SO 答案 以及更多备注。另外,请参阅这个SO答案,它重点关注
remove_geometry
和reset_bounding_box
参数。