0

我目前正在学习用于可视化点云数据的 open3d。我设法使用此处介绍的非阻塞可视化实时可视化从一系列 .pcd 文件(一个文件用于一个点云)中读取的一系列点云:非阻塞可视化

通过遵循文档,我能够更新“点云”类型的几何图形。这是我进行可视化的方式:

    import open3d as o3d
    import numpy as np
    import time

    geometry = o3d.geometry.PointCloud()
    geometry.points = o3d.utility.Vector3dVector(pt_clouds[0])
    o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug)

    vis = o3d.visualization.Visualizer()
    vis.create_window()
    vis.add_geometry(geometry)

    for pt_cloud in pt_clouds: #pt_clouds are the point cloud data from several .pcf files

        geometry.points = o3d.utility.Vector3dVector(pt_cloud)
        vis.update_geometry(geometry)
        vis.poll_events()
        vis.update_renderer()
        time.sleep(1 / 20)

    vis.destroy_window()

但是,除了点云之外,我还有一组由中心坐标 [cx, cy, cz] 给定的每个点云的边界框,围绕 z 轴“rot_z”的旋转和边界的 [长度、宽度、高度]盒子。我想找到一种方法来渲染边界框以及点云并在每一帧更新它们(对于每一帧,有一个点云+不同数量的边界框要渲染,最后一帧的旧渲染需要被清除和更新)。

有没有办法做到这一点?如果 open3d 无法做到这一点,那么在 python 中执行此操作的常用方法/库是什么?

任何建议将不胜感激,在此先感谢!

4

1 回答 1

2

为了可视化边界框,您必须将框从

[cx, cy, cz, rot_z, length, width, height]到代表盒子 8 个角的点数组。

您可以使用这样的函数,它接受一个包含 的数组[x,y,z,h,w,l,r],并返回一个[8, 3]矩阵,该矩阵代表[x, y, z]盒子的每 8 个角:

def box_center_to_corner(box_center):
    # To return
    corner_boxes = np.zeros((8, 3))

    translation = box[0:3]
    h, w, l = size[3], size[4], size[5]
    rotation = box[6]

    # Create a bounding box outline
    bounding_box = np.array([
        [-l/2, -l/2, l/2, l/2, -l/2, -l/2, l/2, l/2],
        [w/2, -w/2, -w/2, w/2, w/2, -w/2, -w/2, w/2],
        [-h/2, -h/2, -h/2, -h/2, h/2, h/2, h/2, h/2]])

    # Standard 3x3 rotation matrix around the Z axis
    rotation_matrix = np.array([
        [np.cos(rotation), -np.sin(rotation), 0.0],
        [np.sin(rotation), np.cos(rotation), 0.0],
        [0.0, 0.0, 1.0]])

    # Repeat the [x, y, z] eight times
    eight_points = np.tile(translation, (8, 1))

    # Translate the rotated bounding box by the
    # original center position to obtain the final box
    corner_box = np.dot(
        rotation_matrix, bounding_box) + eight_points.transpose()

    return corner_box.transpose()

将边界框转换为[8, 3]表示角的矩阵后,您可以使用LineSet对象在 Open3D 中显示它们:

# Our lines span from points 0 to 1, 1 to 2, 2 to 3, etc...
lines = [[0, 1], [1, 2], [2, 3], [0, 3],
         [4, 5], [5, 6], [6, 7], [4, 7],
         [0, 4], [1, 5], [2, 6], [3, 7]]

# Use the same color for all lines
colors = [[1, 0, 0] for _ in range(len(lines))]

line_set = o3d.geometry.LineSet()
line_set.points = o3d.utility.Vector3dVector(corner_box)
line_set.lines = o3d.utility.Vector2iVector(lines)
line_set.colors = o3d.utility.Vector3dVector(colors)

# Create a visualization object and window
vis = o3d.visualization.Visualizer()
vis.create_window()

# Display the bounding boxes:
vis.add_geometry(corner_box)

关于每个时间步更新边界框,请参阅 Open3D Visualizer对象的文档,其中有清除所有几何体 ( clear_geometries())、清除特定几何体 ( remove_geometry(geometry)) 等的方法。

希望这个答案还为时不晚。祝你好运!

于 2021-03-02T16:05:53.193 回答