• [可视化] 点云可视化工具open3d的使用


    1. open3d 可视化语义分割点云和box(with angle)

    • visualize semantic segmentation points
    
    def draw_boxes(vis, boxes, color):
        """
        Args:
            vis: o3d.visualization.Visualizer
            boxes: (N, 7)
            color: (0, 1, 0)
        """
        for i, box in enumerate(boxes):
            b = o3d.geometry.OrientedBoundingBox()
            b.center = box[:3]
            b.extent = box[3:6]
            print(box[6])
            R = o3d.geometry.OrientedBoundingBox.get_rotation_matrix_from_xyz((0, 0, box[6]))
            b.rotate(R, b.center)
            b.color = color
            vis.add_geometry(b) 
    
    point_cloud = o3d.geometry.PointCloud()
    point_cloud.points = o3d.utility.Vector3dVector(valid_points1[:, :])
    point_cloud.colors = o3d.utility.Vector3dVector(colors[valid_points[:, 8].astype(np.int32)])
    vis = o3d.visualization.Visualizer()
    vis.create_window()
    vis.add_geometry(point_cloud)
    draw_boxes(vis, boxes, (0,1,0))
    vis.get_render_option().background_color = np.asarray([0, 0, 0])  # you can set the bg color
    vis.run()
    vis.destroy_window()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • visualize box with angle
    # (N, 7)
    point_cloud = o3d.geometry.PointCloud()
    point_cloud.points = o3d.utility.Vector3dVector(valid_points1[:, :])
    point_cloud.colors = o3d.utility.Vector3dVector(colors[valid_points[:, 8].astype(np.int32)])
    vis = o3d.visualization.Visualizer()
    vis.create_window()
    vis.add_geometry(point_cloud)
    for i, box in enumerate(bboxes):
        b = o3d.geometry.OrientedBoundingBox()
        b.center = box[:3]
        b.extent = box[3:6]
        # with heading
        R = o3d.geometry.OrientedBoundingBox.get_rotation_matrix_from_xyz((0, 0, box[6]))
        b.rotate(R, b.center)  
        # 2nd method
        #lines_box = np.array([[0, 1], [1, 2], [0, 3], [2, 3], [4, 5], [4, 7], [5, 6], [6, 7],
        #                    [0, 4], [1, 5], [2, 6], [3, 7]])
        #colors = np.array([[0, 1, 0] for j in range(len(lines_box))])
        #line_set = o3d.geometry.LineSet()
        #line_set.lines = o3d.utility.Vector2iVector(lines_box)
        #line_set.colors = o3d.utility.Vector3dVector(colors)
        #line_set.points = o3d.utility.Vector3dVector(points_3dbox)
        #vis.add_geometry(line_set)
        vis.add_geometry(b)
    vis.get_render_option().background_color = np.asarray([0, 0, 0]) # 设置一些渲染属性
    vis.run()
    vis.destroy_window()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 将vis可视化效果保存为图片形式
    vis.capture_screen_image("temp_%04d.jpg" % i)
    
    • 1

    2. 一些官方示例-用于参考

      
    # ----------------------------------------------------------------------------
    # -                        Open3D: www.open3d.org                            -
    # ----------------------------------------------------------------------------
    # The MIT License (MIT)
    #
    # Copyright (c) 2018-2021 www.open3d.org
    #
    # Permission is hereby granted, free of charge, to any person obtaining a copy
    # of this software and associated documentation files (the "Software"), to deal
    # in the Software without restriction, including without limitation the rights
    # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    # copies of the Software, and to permit persons to whom the Software is
    # furnished to do so, subject to the following conditions:
    #
    # The above copyright notice and this permission notice shall be included in
    # all copies or substantial portions of the Software.
    #
    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    # IN THE SOFTWARE.
    # ----------------------------------------------------------------------------
    
    from time import sleep
    from numpy import outer
    import open3d as o3d
    
    if __name__ == "__main__":
        # o3d.visualization.webrtc_server.enable_webrtc()
        # cube_red = o3d.geometry.TriangleMesh.create_box(1, 2, 4)
        # cube_red.compute_vertex_normals()
        # cube_red.paint_uniform_color((1.0, 0.0, 0.0))
        # o3d.visualization.draw(cube_red)
        import numpy as np
        import open3d.ml as ml3d
        # or import open3d.ml.tf as ml3d
        # OPEN3D.ML.VISUALIZER不行
        # data = [ {
        #     'name': 'my_point_cloud',
        #     'points': np.random.rand(100,3).astype(np.float32),
        #     'point_attr1': np.random.rand(100).astype(np.float32),
        #     } ]
        # box1 = o3d.ml.vis.BoundingBox3D((20,1,1), front=(1,1,0),
        #                             up = (0,0,1),
        #                             left=(-1,1,0),
        #                             size=(2,2,4), 
        #                             label_class=1, 
        #                             confidence=0.5, 
        #                             show_class=True, 
        #                             show_confidence=True, 
        #                             arrow_length=1.0)
        # box2 = o3d.ml.vis.BoundingBox3D((10,1,1), front=(1,0,0),
        #                             up = (0,0,1),
        #                             left=(0,1,0),
        #                             size=(4,2,2), 
        #                             label_class=0, 
        #                             confidence=0.5, 
        #                             arrow_length=1.0)
        # lut = o3d.ml.vis.LabelLUT()
        # lut.add_label("car", 1, (1,0,0))
        # lut.add_label("people", 0, (0,1,0))
        # # box_cl = o3d.ml.vis.BoundingBox3D.create_lines(data_box["bboxes"], lut, out_format="lineset")
    
        # vis = ml3d.vis.Visualizer()
        # vis.visualize(data, lut, bounding_boxes=[box2, box1])
    
        # import pickle
        # import numpy as np
        # with open("train_0_197.pkl", 'rb') as f:
        #     data = pickle.load(f)
        #     #print(len(data))
        #     #print(data[0])
        #     for k, v in data[0].items():
        #         print(k)
        #     # print(data[0]['point_cloud'])
        # np.set_printoptions(suppress=True)
        # data = np.fromfile("0000000.bin", dtype=np.float32)
        # data = data.reshape(-1, 6)
    
        
    
        # import time
        # import open3d as o3d
        # # Monkey-patch torch.utils.tensorboard.SummaryWriter
        # from open3d.visualization.tensorboard_plugin import summary
        # # Utility function to convert Open3D geometry to a dictionary format
        # from open3d.visualization.tensorboard_plugin.util import to_dict_batch
        # from torch.utils.tensorboard import SummaryWriter
    
        # cube = o3d.geometry.TriangleMesh.create_box(1, 2, 4)
        # cube.compute_vertex_normals()
        # cylinder = o3d.geometry.TriangleMesh.create_cylinder(radius=1.0,
        #                                                     height=2.0,
        #                                                     resolution=20,
        #                                                     split=4)
        # cylinder.compute_vertex_normals()
        # colors = [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)]
        # # ... geometry creation code as above ...
        # logdir = "/home/shimingli/Projects/3d_seg_head/scripts/test"
        # writer = SummaryWriter(logdir)
        # box1 = o3d.ml.vis.BoundingBox3D((20,1,1), front=(1,1,0),
        #                             up = (0,0,1),
        #                             left=(-1,1,0),
        #                             size=(2,2,4), 
        #                             label_class=1, 
        #                             confidence=0.5, 
        #                             show_class=True, 
        #                             show_confidence=True, 
        #                             arrow_length=1.0)
        # box2 = o3d.ml.vis.BoundingBox3D((10,1,1), front=(1,0,0),
        #                             up = (0,0,1),
        #                             left=(0,1,0),
        #                             size=(4,2,2), 
        #                             label_class=0, 
        #                             confidence=0.5, 
        #                             arrow_length=1.0)
        # print(to_dict_batch([cylinder]))
        # import torch
        # shape = data[None, :, :3].shape
    
        # data = {
        #     "vertex_positions": data[None, :, :3],
        #     "vertex_colors": np.zeros(shape)
        # }
    
        # data_box = {
        #     "bboxes":[box1, box2],
        # }
        # lut = o3d.ml.vis.LabelLUT()
        # lut.add_label("car", 1, (1,0,0))
        # lut.add_label("people", 0, (0,1,0))
        # box_cl = o3d.ml.vis.BoundingBox3D.create_lines(data_box["bboxes"], lut, out_format="lineset")
        
        # # print(box_cl)
        # # bbox_labels and bbox_confidences not supported in v14
        # # box_cl.pop("bbox_labels")
        # # box_cl.pop("bbox_confidences")
        # # writer.add_3d('points', data, step=0)
        # writer.add_3d("bboxes", to_dict_batch([box_cl]),step=1)
        # writer.add_text('bboxes', 'This is an lstm', 0)
    
        # mat = o3d.visualization.rendering.MaterialRecord()
        # mat.shader = "unlitLine"
        # mat.line_width = 5  # note that this is scaled with respect to pixels,
        # # so will give different results depending on the
        # # scaling values of your system
        # o3d.visualization.draw({
        #     "name": "lines",
        #     "geometry": box_cl,
        #     "material": mat
        # })
        # #writer.add_3d("color", box_cl,step=0)
        # # for step in range(3):
        # #     cube.paint_uniform_color(colors[step])
        # #     writer.add_3d('cube', data, step=step)
        # #     # cylinder.paint_uniform_color(colors[step])
        # #     # writer.add_3d('cylinder', to_dict_batch([cylinder]), step=step)
        # #     time.sleep(1)
    
        import numpy as np
        import open3d as o3d
        import open3d.visualization.gui as gui
        import open3d.visualization.rendering as rendering
        app = gui.Application.instance
        app.initialize()
        def make_point_cloud(npts, center, radius):
            pts = np.random.uniform(-radius, radius, size=[npts, 3]) + center
            cloud = o3d.geometry.PointCloud()
            cloud.points = o3d.utility.Vector3dVector(pts)
            colors = np.random.uniform(0.0, 1.0, size=[npts, 3])
            cloud.colors = o3d.utility.Vector3dVector(colors)
            return cloud
    
        points = make_point_cloud(100, (0, 0, 0), 1.0)
    
        vis = o3d.visualization.O3DVisualizer("Open3D - 3D Text", 1024, 768)
        vis.show_settings = True
        vis.add_geometry("Points", points)
        for idx in range(0, len(points.points)):
            vis.add_3d_label(points.points[idx], "{}".format(idx))
        vis.reset_camera_to_default()
        
    
        app.add_window(vis)
        app.run()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190

    3. 绘制箭头

    refs

    tensorboard 联合

    可以和tensorboard融合,但是要与pip install tensorboard, 不是tensorflow的tensorboard; anaconda/bin/tensorboard 是可以的,否则出现datest not found问题

    参考文献


  • 相关阅读:
    RabbitMQ和Kafka的区别
    leetcode 32. 最长有效括号 (困难)
    PHP之美团餐饮系统,订单推送,订单同步,订单消息回调
    基于Docker的深度学习环境NVIDIA和CUDA部署以及WSL和linux镜像问题
    可循环视频播放器丨VideoPlayer丨StreamingAssets加载
    DirectX12(D3D12)基础教程(十八)—— PBR基础从物理到艺术(中)
    贵金属金银铂铑钯回收-HP4080
    SELinux零知识学习二十三、SELinux策略语言之类型强制(8)
    基于Python分析实现酒店评论的中文情感
    899-900 案例:高亮显示,案例:王者荣耀手风琴效果(JQuery)
  • 原文地址:https://blog.csdn.net/mingshili/article/details/124714290