# 可视化 MMDetection3D 提供了 `Det3DLocalVisualizer` 用来在训练及测试阶段可视化和存储模型的状态以及结果,其具有以下特性: 1. 支持多模态数据和多任务的基本绘图界面。 2. 支持多个后端(如 local,TensorBoard),将训练状态(如 `loss`,`lr`)或模型评估指标写入指定的一个或多个后端中。 3. 支持多模态数据真实标签的可视化,3D 检测结果的跨模态可视化。 ## 基本绘制界面 继承自 `DetLocalVisualizer`,`Det3DLocalVisualizer` 提供了在 2D 图像上绘制常见目标的界面,例如绘制检测框、点、文本、线、圆、多边形、二进制掩码等。关于 2D 绘制的更多细节,请参考 MMDetection 中的[可视化文档](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/visualization.html)。这里我们介绍 3D 绘制界面。 ### 在图像上绘制点云 通过使用 `draw_points_on_image`,我们支持在图像上绘制点云。 ```python import mmcv import numpy as np from mmengine import load from mmdet3d.visualization import Det3DLocalVisualizer info_file = load('demo/data/kitti/000008.pkl') points = np.fromfile('demo/data/kitti/000008.bin', dtype=np.float32) points = points.reshape(-1, 4)[:, :3] lidar2img = np.array(info_file['data_list'][0]['images']['CAM2']['lidar2img'], dtype=np.float32) visualizer = Det3DLocalVisualizer() img = mmcv.imread('demo/data/kitti/000008.png') img = mmcv.imconvert(img, 'bgr', 'rgb') visualizer.set_image(img) visualizer.draw_points_on_image(points, lidar2img) visualizer.show() ``` ![points_on_image](../../../resources/points_on_image.png) ### 在点云上绘制 3D 框 通过使用 `draw_bboxes_3d`,我们支持在点云上绘制 3D 框。 ```python import torch import numpy as np from mmdet3d.visualization import Det3DLocalVisualizer from mmdet3d.structures import LiDARInstance3DBoxes points = np.fromfile('demo/data/kitti/000008.bin', dtype=np.float32) points = points.reshape(-1, 4) visualizer = Det3DLocalVisualizer() # set point cloud in visualizer visualizer.set_points(points) bboxes_3d = LiDARInstance3DBoxes( torch.tensor([[8.7314, -1.8559, -1.5997, 4.2000, 3.4800, 1.8900, -1.5808]])) # Draw 3D bboxes visualizer.draw_bboxes_3d(bboxes_3d) visualizer.show() ``` ![mono3d](../../../resources/pcd.png) ### 在图像上绘制投影的 3D 框 通过使用 `draw_proj_bboxes_3d`,我们支持在图像上绘制投影的 3D 框。 ```python import mmcv import numpy as np from mmengine import load from mmdet3d.visualization import Det3DLocalVisualizer from mmdet3d.structures import CameraInstance3DBoxes info_file = load('demo/data/kitti/000008.pkl') cam2img = np.array(info_file['data_list'][0]['images']['CAM2']['cam2img'], dtype=np.float32) bboxes_3d = [] for instance in info_file['data_list'][0]['instances']: bboxes_3d.append(instance['bbox_3d']) gt_bboxes_3d = np.array(bboxes_3d, dtype=np.float32) gt_bboxes_3d = CameraInstance3DBoxes(gt_bboxes_3d) input_meta = {'cam2img': cam2img} visualizer = Det3DLocalVisualizer() img = mmcv.imread('demo/data/kitti/000008.png') img = mmcv.imconvert(img, 'bgr', 'rgb') visualizer.set_image(img) # project 3D bboxes to image visualizer.draw_proj_bboxes_3d(gt_bboxes_3d, input_meta) visualizer.show() ``` ### 绘制 BEV 视角的框 通过使用 `draw_bev_bboxes`,我们支持绘制 BEV 视角下的框。 ```python import numpy as np from mmengine import load from mmdet3d.visualization import Det3DLocalVisualizer from mmdet3d.structures import CameraInstance3DBoxes info_file = load('demo/data/kitti/000008.pkl') bboxes_3d = [] for instance in info_file['data_list'][0]['instances']: bboxes_3d.append(instance['bbox_3d']) gt_bboxes_3d = np.array(bboxes_3d, dtype=np.float32) gt_bboxes_3d = CameraInstance3DBoxes(gt_bboxes_3d) visualizer = Det3DLocalVisualizer() # set bev image in visualizer visualizer.set_bev_image() # draw bev bboxes visualizer.draw_bev_bboxes(gt_bboxes_3d, edge_colors='orange') visualizer.show() ``` ### 绘制 3D 分割掩码 通过使用 `draw_seg_mask`,我们支持通过逐点着色来绘制分割掩码。 ```python import numpy as np from mmdet3d.visualization import Det3DLocalVisualizer points = np.fromfile('demo/data/sunrgbd/000017.bin', dtype=np.float32) points = points.reshape(-1, 3) visualizer = Det3DLocalVisualizer() mask = np.random.rand(points.shape[0], 3) points_with_mask = np.concatenate((points, mask), axis=-1) # Draw 3D points with mask visualizer.set_points(points, pcd_mode=2, vis_mode='add') visualizer.draw_seg_mask(points_with_mask) visualizer.show() ``` ## 结果 如果想要可视化训练模型的预测结果,你可以运行如下指令: ```bash python tools/test.py ${CONFIG_FILE} ${CKPT_PATH} --show --show-dir ${SHOW_DIR} ``` 运行该指令后,绘制的结果(包括输入数据和网络输出在输入上的可视化)将会被保存在 `${SHOW_DIR}` 中。 运行该指令后,你将在 `${SHOW_DIR}` 中获得输入数据,网络输出和真是标签在输入上的可视化(如在多模态检测任务和基于视觉的检测任务中的 `***_gt.png` 和 `***_pred.png`)。当启用 `show` 时,[Open3D](http://www.open3d.org/) 将会用于在线可视化结果。如果你是在没有 GUI 的远程服务器上测试时,在线可视化是不被支持的。你可以从远程服务器中下载 `results.pkl`,并在本地机器上离线可视化预测结果。 使用 `Open3D` 后端离线可视化结果,你可以运行如下指令: ```bash python tools/misc/visualize_results.py ${CONFIG_FILE} --result ${RESULTS_PATH} --show-dir ${SHOW_DIR} ``` ![](../../../resources/open3d_visual.gif) 这需要在远程服务器中能够推理并生成结果,然后用户在主机中使用 GUI 打开。 ## 数据集 我们也提供了脚本来可视化数据集而无需推理。你可以使用 `tools/misc/browse_dataset.py` 来在线可视化加载的数据的真实标签,并保存在硬盘中。目前我们支持所有数据集的单模态 3D 检测和 3D 分割,KITTI 和 SUN RGB-D 的多模态 3D 检测,以及 nuScenes 的单目 3D 检测。如果想要浏览 KITTI 数据集,你可以运行如下指令: ```shell python tools/misc/browse_dataset.py configs/_base_/datasets/kitti-3d-3class.py --task lidar_det --output-dir ${OUTPUT_DIR} ``` **注意**:一旦指定了 `--output-dir`,当在 open3d 窗口中按下 `_ESC_` 时,用户指定的视图图像将会被保存下来。如果你想要对点云进行缩放操作以观察更多细节, 你可以在命令中指定 `--show-interval=0`。 为了验证数据的一致性和数据增强的效果,你可以加上 `--aug` 来可视化数据增强后的数据,指令如下所示: ```shell python tools/misc/browse_dataset.py configs/_base_/datasets/kitti-3d-3class.py --task det --aug --output-dir ${OUTPUT_DIR} ``` 如果你想显示带有投影的 3D 边界框的 2D 图像,你需要一个支持多模态数据加载的配置文件,并将 `--task` 参数改为 `multi-modality_det`。示例如下: ```shell python tools/misc/browse_dataset.py configs/mvxnet/mvxnet_fpn_dv_second_secfpn_8xb2-80e_kitti-3d-3class.py --task multi-modality_det --output-dir ${OUTPUT_DIR} ``` ![](../../../resources/browse_dataset_multi_modality.png) 你可以使用不同的配置浏览不同的数据集,例如在 3D 语义分割任务中可视化 ScanNet 数据集: ```shell python tools/misc/browse_dataset.py configs/_base_/datasets/scannet-seg.py --task lidar_seg --output-dir ${OUTPUT_DIR} ``` ![](../../../resources/browse_dataset_seg.png) 在单目 3D 检测任务中浏览 nuScenes 数据集: ```shell python tools/misc/browse_dataset.py configs/_base_/datasets/nus-mono3d.py --task mono_det --output-dir ${OUTPUT_DIR} ``` ![](../../../resources/browse_dataset_mono.png)