如何使用 Open3d 将多个点云文件可视化为视频?

问题描述 投票:0回答:1

我使用 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

我感谢您提前提供的任何帮助。

谢谢,

阿巴斯

python video point-clouds bin open3d
1个回答
0
投票

阅读此处的官方教程,了解有关非阻塞可视化的信息。下面的代码将展示如何生成新的点云数据并更新

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
参数。

© www.soinside.com 2019 - 2024. All rights reserved.