Unverified Commit cf922153 authored by Shilong Zhang's avatar Shilong Zhang Committed by GitHub
Browse files

[Docs] Replace markdownlint with mdformat for avoiding installing ruby (#1489)

parent 7f4bb54d
This diff is collapsed.
......@@ -88,27 +88,27 @@ kitti
- `kitti_gt_database/xxxxx.bin`: 训练数据集中包含在 3D 标注框中的点云数据
- `kitti_infos_train.pkl`:训练数据集的信息,其中每一帧的信息包含下面的内容:
- info['point_cloud']: {'num_features': 4, 'velodyne_path': velodyne_path}.
- info['annos']: {
- 位置:其中 x,y,z 为相机参考坐标系下的目标的底部中心(单位为米),是一个尺寸为 Nx3 的数组
- 维度: 目标的高、宽、长(单位为米),是一个尺寸为 Nx3 的数组
- 旋转角:相机坐标系下目标绕着 Y 轴的旋转角 ry,其取值范围为 [-pi..pi] ,是一个尺寸为 N 的数组
- 名称:标准框所包含的目标的名称,是一个尺寸为 N 的数组
- 困难度:kitti 官方所定义的困难度,包括 简单,适中,困难
- 组别标识符:用于多部件的目标
}
- (optional) info['calib']: {
- P0:校对后的 camera0 投影矩阵,是一个 3x4 数组
- P1:校对后的 camera1 投影矩阵,是一个 3x4 数组
- P2:校对后的 camera2 投影矩阵,是一个 3x4 数组
- P3:校对后的 camera3 投影矩阵,是一个 3x4 数组
- R0_rect:校准旋转矩阵,是一个 4x4 数组
- Tr_velo_to_cam:从 Velodyne 坐标到相机坐标的变换矩阵,是一个 4x4 数组
- Tr_imu_to_velo:从 IMU 坐标到 Velodyne 坐标的变换矩阵,是一个 4x4 数组
}
- (optional) info['image']:{'image_idx': idx, 'image_path': image_path, 'image_shape', image_shape}.
**注意**:其中的 info['annos'] 中的数据均位于相机参考坐标系中,更多的细节请参考[此处](http://www.cvlibs.net/publications/Geiger2013IJRR.pdf)
- info\['point_cloud'\]: {'num_features': 4, 'velodyne_path': velodyne_path}.
- info\['annos'\]: {
- 位置:其中 x,y,z 为相机参考坐标系下的目标的底部中心(单位为米),是一个尺寸为 Nx3 的数组
- 维度: 目标的高、宽、长(单位为米),是一个尺寸为 Nx3 的数组
- 旋转角:相机坐标系下目标绕着 Y 轴的旋转角 ry,其取值范围为 \[-pi..pi\] ,是一个尺寸为 N 的数组
- 名称:标准框所包含的目标的名称,是一个尺寸为 N 的数组
- 困难度:kitti 官方所定义的困难度,包括 简单,适中,困难
- 组别标识符:用于多部件的目标
}
- (optional) info\['calib'\]: {
- P0:校对后的 camera0 投影矩阵,是一个 3x4 数组
- P1:校对后的 camera1 投影矩阵,是一个 3x4 数组
- P2:校对后的 camera2 投影矩阵,是一个 3x4 数组
- P3:校对后的 camera3 投影矩阵,是一个 3x4 数组
- R0_rect:校准旋转矩阵,是一个 4x4 数组
- Tr_velo_to_cam:从 Velodyne 坐标到相机坐标的变换矩阵,是一个 4x4 数组
- Tr_imu_to_velo:从 IMU 坐标到 Velodyne 坐标的变换矩阵,是一个 4x4 数组
}
- (optional) info\['image'\]:{'image_idx': idx, 'image_path': image_path, 'image_shape', image_shape}.
**注意**:其中的 info\['annos'\] 中的数据均位于相机参考坐标系中,更多的细节请参考[此处](http://www.cvlibs.net/publications/Geiger2013IJRR.pdf)
获取 kitti_infos_xxx.pkl 和 kitti_infos_xxx_mono3d.coco.json 的核心函数分别为 [get_kitti_image_info](https://github.com/open-mmlab/mmdetection3d/blob/7873c8f62b99314f35079f369d1dab8d63f8a3ce/tools/data_converter/kitti_data_utils.py#L140)[get_2d_boxes](https://github.com/open-mmlab/mmdetection3d/blob/7873c8f62b99314f35079f369d1dab8d63f8a3ce/tools/data_converter/kitti_converter.py#L378).
......@@ -150,9 +150,9 @@ train_pipeline = [
```
- 数据增强:
- `ObjectNoise`:对场景中的每个真实标注框目标添加噪音。
- `RandomFlip3D`:对输入点云数据进行随机地水平翻转或者垂直翻转。
- `GlobalRotScaleTrans`:对输入点云数据进行旋转。
- `ObjectNoise`:对场景中的每个真实标注框目标添加噪音。
- `RandomFlip3D`:对输入点云数据进行随机地水平翻转或者垂直翻转。
- `GlobalRotScaleTrans`:对输入点云数据进行旋转。
## 评估
......@@ -191,4 +191,4 @@ mkdir -p results/kitti-3class
./tools/dist_test.sh configs/pointpillars/hv_pointpillars_secfpn_6x8_160e_kitti-3d-3class.py work_dirs/hv_pointpillars_secfpn_6x8_160e_kitti-3d-3class/latest.pth 8 --out results/kitti-3class/results_eval.pkl --format-only --eval-options 'pklfile_prefix=results/kitti-3class/kitti_results' 'submission_prefix=results/kitti-3class/kitti_results'
```
在生成 `results/kitti-3class/kitti_results/xxxxx.txt` 后,您可以提交这些文件到 KITTI 官方网站进行基准测试,请参考 [KITTI 官方网站]((http://www.cvlibs.net/datasets/kitti/index.php))获取更多细节。
在生成 `results/kitti-3class/kitti_results/xxxxx.txt` 后,您可以提交这些文件到 KITTI 官方网站进行基准测试,请参考 [KITTI 官方网站](<(http://www.cvlibs.net/datasets/kitti/index.php)>)获取更多细节。
......@@ -89,21 +89,21 @@ mmdetection3d
- `lyft_database/xxxxx.bin` 文件不存在:由于真实标注框的采样对实验的影响可以忽略不计,在 Lyft 数据集中不会提取该目录和相关的 `.bin` 文件。
- `lyft_infos_train.pkl`:包含训练数据集信息,每一帧包含两个关键字:`metadata``infos`
`metadata` 包含数据集自身的基础信息,如 `{'version': 'v1.01-train'}`,然而 `infos` 包含和 nuScenes 数据集相似的数据集详细信息,但是并不包含一下几点:
- info['sweeps']:扫描信息.
- info['sweeps'][i]['type']:扫描信息的数据类型,如 `'lidar'`
Lyft 数据集中的一些样例具有不同的 LiDAR 设置,然而为了数据分布的一致性,这里将一直采用顶部的 LiDAR 设备所采集的数据点信息。
- info['gt_names']:在 Lyft 数据集中有 9 个类别,相比于 nuScenes 数据集,不同类别的标注不平衡问题更加突出。
- info['gt_velocity'] 不存在:Lyft 数据集中不存在速度评估信息。
- info['num_lidar_pts']:默认值设置为 -1。
- info['num_radar_pts']:默认值设置为 0。
- info['valid_flag'] 不存在:这个标志信息因无效的 `num_lidar_pts``num_radar_pts` 的存在而存在。
`metadata` 包含数据集自身的基础信息,如 `{'version': 'v1.01-train'}`,然而 `infos` 包含和 nuScenes 数据集相似的数据集详细信息,但是并不包含一下几点:
- info\['sweeps'\]:扫描信息.
- info\['sweeps'\]\[i\]\['type'\]:扫描信息的数据类型,如 `'lidar'`
Lyft 数据集中的一些样例具有不同的 LiDAR 设置,然而为了数据分布的一致性,这里将一直采用顶部的 LiDAR 设备所采集的数据点信息。
- info\['gt_names'\]:在 Lyft 数据集中有 9 个类别,相比于 nuScenes 数据集,不同类别的标注不平衡问题更加突出。
- info\['gt_velocity'\] 不存在:Lyft 数据集中不存在速度评估信息。
- info\['num_lidar_pts'\]:默认值设置为 -1。
- info\['num_radar_pts'\]:默认值设置为 0。
- info\['valid_flag'\] 不存在:这个标志信息因无效的 `num_lidar_pts``num_radar_pts` 的存在而存在。
- `nuscenes_infos_train_mono3d.coco.json`:包含 coco 类型的训练数据集相关的信息。这个文件仅包含 2D 相关的信息,不包含 3D 目标检测所需要的信息,如相机内参。
- info['images']:包含所有图像信息的列表。
- 仅包含 `'file_name'`, `'id'`, `'width'`, `'height'`
- info['annotations']:包含所有标注信息的列表。
- 仅包含 `'file_name'``'image_id'``'area'``'category_name'``'category_id'``'bbox'``'is_crowd'``'segmentation'``'id'`,其中 `'is_crowd'``'segmentation'` 默认设置为 `0``[]`
Lyft 数据集中不包含属性标注信息。
- info\['images'\]:包含所有图像信息的列表。
- 仅包含 `'file_name'`, `'id'`, `'width'`, `'height'`
- info\['annotations'\]:包含所有标注信息的列表。
- 仅包含 `'file_name'``'image_id'``'area'``'category_name'``'category_id'``'bbox'``'is_crowd'``'segmentation'``'id'`,其中 `'is_crowd'``'segmentation'` 默认设置为 `0``[]`
Lyft 数据集中不包含属性标注信息。
这里仅介绍存储在训练数据文件的数据记录信息,在测试数据集也采用上述的数据记录方式。
......
......@@ -64,60 +64,60 @@ mmdetection3d
- `nuscenes_database/xxxxx.bin`:训练数据集的每个 3D 包围框中包含的点云数据。
- `nuscenes_infos_train.pkl`:训练数据集信息,每帧信息有两个键值: `metadata``infos``metadata` 包含数据集本身的基本信息,例如 `{'version': 'v1.0-trainval'}`,而 `infos` 包含详细信息如下:
- info['lidar_path']:激光雷达点云数据的文件路径。
- info['token']:样本数据标记。
- info['sweeps']:扫描信息(nuScenes 中的 `sweeps` 是指没有标注的中间帧,而 `samples` 是指那些带有标注的关键帧)。
- info['sweeps'][i]['data_path']:第 i 次扫描的数据路径。
- info['sweeps'][i]['type']:扫描数据类型,例如“激光雷达”。
- info['sweeps'][i]['sample_data_token']:扫描样本数据标记。
- info['sweeps'][i]['sensor2ego_translation']:从当前传感器(用于收集扫描数据)到自车(包含感知周围环境传感器的车辆,车辆坐标系固连在自车上)的转换(1x3 列表)。
- info['sweeps'][i]['sensor2ego_rotation']:从当前传感器(用于收集扫描数据)到自车的旋转(四元数格式的 1x4 列表)。
- info['sweeps'][i]['ego2global_translation']:从自车到全局坐标的转换(1x3 列表)。
- info['sweeps'][i]['ego2global_rotation']:从自车到全局坐标的旋转(四元数格式的 1x4 列表)。
- info['sweeps'][i]['timestamp']:扫描数据的时间戳。
- info['sweeps'][i]['sensor2lidar_translation']:从当前传感器(用于收集扫描数据)到激光雷达的转换(1x3 列表)。
- info['sweeps'][i]['sensor2lidar_rotation']:从当前传感器(用于收集扫描数据)到激光雷达的旋转(四元数格式的 1x4 列表)。
- info['cams']:相机校准信息。它包含与每个摄像头对应的六个键值: `'CAM_FRONT'`, `'CAM_FRONT_RIGHT'`, `'CAM_FRONT_LEFT'`, `'CAM_BACK'`, `'CAM_BACK_LEFT'`, `'CAM_BACK_RIGHT'`
- info\['lidar_path'\]:激光雷达点云数据的文件路径。
- info\['token'\]:样本数据标记。
- info\['sweeps'\]:扫描信息(nuScenes 中的 `sweeps` 是指没有标注的中间帧,而 `samples` 是指那些带有标注的关键帧)。
- info\['sweeps'\]\[i\]\['data_path'\]:第 i 次扫描的数据路径。
- info\['sweeps'\]\[i\]\['type'\]:扫描数据类型,例如“激光雷达”。
- info\['sweeps'\]\[i\]\['sample_data_token'\]:扫描样本数据标记。
- info\['sweeps'\]\[i\]\['sensor2ego_translation'\]:从当前传感器(用于收集扫描数据)到自车(包含感知周围环境传感器的车辆,车辆坐标系固连在自车上)的转换(1x3 列表)。
- info\['sweeps'\]\[i\]\['sensor2ego_rotation'\]:从当前传感器(用于收集扫描数据)到自车的旋转(四元数格式的 1x4 列表)。
- info\['sweeps'\]\[i\]\['ego2global_translation'\]:从自车到全局坐标的转换(1x3 列表)。
- info\['sweeps'\]\[i\]\['ego2global_rotation'\]:从自车到全局坐标的旋转(四元数格式的 1x4 列表)。
- info\['sweeps'\]\[i\]\['timestamp'\]:扫描数据的时间戳。
- info\['sweeps'\]\[i\]\['sensor2lidar_translation'\]:从当前传感器(用于收集扫描数据)到激光雷达的转换(1x3 列表)。
- info\['sweeps'\]\[i\]\['sensor2lidar_rotation'\]:从当前传感器(用于收集扫描数据)到激光雷达的旋转(四元数格式的 1x4 列表)。
- info\['cams'\]:相机校准信息。它包含与每个摄像头对应的六个键值: `'CAM_FRONT'`, `'CAM_FRONT_RIGHT'`, `'CAM_FRONT_LEFT'`, `'CAM_BACK'`, `'CAM_BACK_LEFT'`, `'CAM_BACK_RIGHT'`
每个字典包含每个扫描数据按照上述方式的详细信息(每个信息的关键字与上述相同)。除此之外,每个相机还包含了一个键值 `'cam_intrinsic'` 用来保存 3D 点投影到图像平面上需要的内参信息。
- info['lidar2ego_translation']:从激光雷达到自车的转换(1x3 列表)。
- info['lidar2ego_rotation']:从激光雷达到自车的旋转(四元数格式的 1x4 列表)。
- info['ego2global_translation']:从自车到全局坐标的转换(1x3 列表)。
- info['ego2global_rotation']:从自我车辆到全局坐标的旋转(四元数格式的 1x4 列表)。
- info['timestamp']:样本数据的时间戳。
- info['gt_boxes']:7 个自由度的 3D 包围框,一个 Nx7 数组。
- info['gt_names']:3D 包围框的类别,一个 1xN 数组。
- info['gt_velocity']:3D 包围框的速度(由于不准确,没有垂直测量),一个 Nx2 数组。
- info['num_lidar_pts']:每个 3D 包围框中包含的激光雷达点数。
- info['num_radar_pts']:每个 3D 包围框中包含的雷达点数。
- info['valid_flag']:每个包围框是否有效。一般情况下,我们只将包含至少一个激光雷达或雷达点的 3D 框作为有效框。
- info\['lidar2ego_translation'\]:从激光雷达到自车的转换(1x3 列表)。
- info\['lidar2ego_rotation'\]:从激光雷达到自车的旋转(四元数格式的 1x4 列表)。
- info\['ego2global_translation'\]:从自车到全局坐标的转换(1x3 列表)。
- info\['ego2global_rotation'\]:从自我车辆到全局坐标的旋转(四元数格式的 1x4 列表)。
- info\['timestamp'\]:样本数据的时间戳。
- info\['gt_boxes'\]:7 个自由度的 3D 包围框,一个 Nx7 数组。
- info\['gt_names'\]:3D 包围框的类别,一个 1xN 数组。
- info\['gt_velocity'\]:3D 包围框的速度(由于不准确,没有垂直测量),一个 Nx2 数组。
- info\['num_lidar_pts'\]:每个 3D 包围框中包含的激光雷达点数。
- info\['num_radar_pts'\]:每个 3D 包围框中包含的雷达点数。
- info\['valid_flag'\]:每个包围框是否有效。一般情况下,我们只将包含至少一个激光雷达或雷达点的 3D 框作为有效框。
- `nuscenes_infos_train_mono3d.coco.json`:训练数据集 coco 风格的信息。该文件将基于图像的数据组织为三类(键值):`'categories'`, `'images'`, `'annotations'`
- info['categories']:包含所有类别名称的列表。每个元素都遵循字典格式并由两个键值组成:`'id'``'name'`
- info['images']:包含所有图像信息的列表。
- info['images'][i]['file_name']:第 i 张图像的文件名。
- info['images'][i]['id']:第 i 张图像的样本数据标记。
- info['images'][i]['token']:与该帧对应的样本标记。
- info['images'][i]['cam2ego_rotation']:从相机到自车的旋转(四元数格式的 1x4 列表)。
- info['images'][i]['cam2ego_translation']:从相机到自车的转换(1x3 列表)。
- info['images'][i]['ego2global_rotation'']:从自车到全局坐标的旋转(四元数格式的 1x4 列表)。
- info['images'][i]['ego2global_translation']:从自车到全局坐标的转换(1x3 列表)。
- info['images'][i]['cam_intrinsic']: 相机内参矩阵(3x3 列表)。
- info['images'][i]['width']:图片宽度, nuScenes 中默认为 1600。
- info['images'][i]['height']:图像高度, nuScenes 中默认为 900。
- info['annotations']: 包含所有标注信息的列表。
- info['annotations'][i]['file_name']:对应图像的文件名。
- info['annotations'][i]['image_id']:对应图像的图像 ID (标记)。
- info['annotations'][i]['area']:2D 包围框的面积。
- info['annotations'][i]['category_name']:类别名称。
- info['annotations'][i]['category_id']:类别 id。
- info['annotations'][i]['bbox']:2D 包围框标注(3D 投影框的外部矩形),1x4 列表跟随 [x1, y1, x2-x1, y2-y1]。x1/y1 是沿图像水平/垂直方向的最小坐标。
- info['annotations'][i]['iscrowd']:该区域是否拥挤。默认为 0。
- info['annotations'][i]['bbox_cam3d']:3D 包围框(重力)中心位置(3)、大小(3)、(全局)偏航角(1)、1x7 列表。
- info['annotations'][i]['velo_cam3d']:3D 包围框的速度(由于不准确,没有垂直测量),一个 Nx2 数组。
- info['annotations'][i]['center2d']:包含 2.5D 信息的投影 3D 中心:图像上的投影中心位置(2)和深度(1),1x3 列表。
- info['annotations'][i]['attribute_name']:属性名称。
- info['annotations'][i]['attribute_id']:属性 ID。
我们为属性分类维护了一个属性集合和映射。更多的细节请参考[这里](https://github.com/open-mmlab/mmdetection3d/blob/master/mmdet3d/datasets/nuscenes_mono_dataset.py#L53)
- info['annotations'][i]['id']:标注 ID。默认为 `i`
- info\['categories'\]:包含所有类别名称的列表。每个元素都遵循字典格式并由两个键值组成:`'id'``'name'`
- info\['images'\]:包含所有图像信息的列表。
- info\['images'\]\[i\]\['file_name'\]:第 i 张图像的文件名。
- info\['images'\]\[i\]\['id'\]:第 i 张图像的样本数据标记。
- info\['images'\]\[i\]\['token'\]:与该帧对应的样本标记。
- info\['images'\]\[i\]\['cam2ego_rotation'\]:从相机到自车的旋转(四元数格式的 1x4 列表)。
- info\['images'\]\[i\]\['cam2ego_translation'\]:从相机到自车的转换(1x3 列表)。
- info\['images'\]\[i\]\['ego2global_rotation''\]:从自车到全局坐标的旋转(四元数格式的 1x4 列表)。
- info\['images'\]\[i\]\['ego2global_translation'\]:从自车到全局坐标的转换(1x3 列表)。
- info\['images'\]\[i\]\['cam_intrinsic'\]: 相机内参矩阵(3x3 列表)。
- info\['images'\]\[i\]\['width'\]:图片宽度, nuScenes 中默认为 1600。
- info\['images'\]\[i\]\['height'\]:图像高度, nuScenes 中默认为 900。
- info\['annotations'\]: 包含所有标注信息的列表。
- info\['annotations'\]\[i\]\['file_name'\]:对应图像的文件名。
- info\['annotations'\]\[i\]\['image_id'\]:对应图像的图像 ID (标记)。
- info\['annotations'\]\[i\]\['area'\]:2D 包围框的面积。
- info\['annotations'\]\[i\]\['category_name'\]:类别名称。
- info\['annotations'\]\[i\]\['category_id'\]:类别 id。
- info\['annotations'\]\[i\]\['bbox'\]:2D 包围框标注(3D 投影框的外部矩形),1x4 列表跟随 \[x1, y1, x2-x1, y2-y1\]。x1/y1 是沿图像水平/垂直方向的最小坐标。
- info\['annotations'\]\[i\]\['iscrowd'\]:该区域是否拥挤。默认为 0。
- info\['annotations'\]\[i\]\['bbox_cam3d'\]:3D 包围框(重力)中心位置(3)、大小(3)、(全局)偏航角(1)、1x7 列表。
- info\['annotations'\]\[i\]\['velo_cam3d'\]:3D 包围框的速度(由于不准确,没有垂直测量),一个 Nx2 数组。
- info\['annotations'\]\[i\]\['center2d'\]:包含 2.5D 信息的投影 3D 中心:图像上的投影中心位置(2)和深度(1),1x3 列表。
- info\['annotations'\]\[i\]\['attribute_name'\]:属性名称。
- info\['annotations'\]\[i\]\['attribute_id'\]:属性 ID。
我们为属性分类维护了一个属性集合和映射。更多的细节请参考[这里](https://github.com/open-mmlab/mmdetection3d/blob/master/mmdet3d/datasets/nuscenes_mono_dataset.py#L53)
- info\['annotations'\]\[i\]\['id'\]:标注 ID。默认为 `i`
这里我们只解释训练信息文件中记录的数据。这同样适用于验证和测试集。
获取 `nuscenes_infos_xxx.pkl``nuscenes_infos_xxx_mono3d.coco.json` 的核心函数分别为 [\_fill_trainval_infos](https://github.com/open-mmlab/mmdetection3d/blob/master/tools/data_converter/nuscenes_converter.py#L143)[get_2d_boxes](https://github.com/open-mmlab/mmdetection3d/blob/master/tools/data_converter/nuscenes_converter.py#L397)。更多细节请参考 [nuscenes_converter.py](https://github.com/open-mmlab/mmdetection3d/blob/master/tools/data_converter/nuscenes_converter.py)
......@@ -191,10 +191,11 @@ train_pipeline = [
```
它遵循 2D 检测的一般流水线,但在一些细节上有所不同:
- 它使用单目流水线加载图像,其中包括额外的必需信息,如相机内参矩阵。
- 它需要加载 3D 标注。
- 一些数据增强技术需要调整,例如`RandomFlip3D`
目前我们不支持更多的增强方法,因为如何迁移和应用其他技术仍在探索中。
目前我们不支持更多的增强方法,因为如何迁移和应用其他技术仍在探索中。
## 评估
......
......@@ -39,10 +39,12 @@ mmdetection3d
例如,在 `Area_1/office_1` 目录下的文件如下所示:
- `office_1.txt`:一个 txt 文件存储着原始点云数据每个点的坐标和颜色信息。
- `Annotations/`:这个文件夹里包含有此房间中实例物体的信息 (以 txt 文件的形式存储)。每个 txt 文件表示一个实例,例如:
- `chair_1.txt`:存储有该房间中一把椅子的点云数据。
如果我们将 `Annotations/` 下的所有 txt 文件合并起来,得到的点云就和 `office_1.txt` 中的点云是一致的。
- `chair_1.txt`:存储有该房间中一把椅子的点云数据。
如果我们将 `Annotations/` 下的所有 txt 文件合并起来,得到的点云就和 `office_1.txt` 中的点云是一致的。
你可以通过 `python collect_indoor3d_data.py` 指令进行 S3DIS 数据的提取。
主要步骤包括:
......@@ -143,16 +145,16 @@ s3dis
```
- `points/xxxxx.bin`:提取的点云数据。
- `instance_mask/xxxxx.bin`:每个点云的实例标签,取值范围为 [0, ${实例个数}],其中 0 代表未标注的点。
- `semantic_mask/xxxxx.bin`:每个点云的语义标签,取值范围为 [0, 12]。
- `instance_mask/xxxxx.bin`:每个点云的实例标签,取值范围为 \[0, ${实例个数}\],其中 0 代表未标注的点。
- `semantic_mask/xxxxx.bin`:每个点云的语义标签,取值范围为 \[0, 12\]
- `s3dis_infos_Area_1.pkl`:区域 1 的数据信息,每个房间的详细信息如下:
- info['point_cloud']: {'num_features': 6, 'lidar_idx': sample_idx}.
- info['pts_path']: `points/xxxxx.bin` 点云的路径。
- info['pts_instance_mask_path']: `instance_mask/xxxxx.bin` 实例标签的路径。
- info['pts_semantic_mask_path']: `semantic_mask/xxxxx.bin` 语义标签的路径。
- info\['point_cloud'\]: {'num_features': 6, 'lidar_idx': sample_idx}.
- info\['pts_path'\]: `points/xxxxx.bin` 点云的路径。
- info\['pts_instance_mask_path'\]: `instance_mask/xxxxx.bin` 实例标签的路径。
- info\['pts_semantic_mask_path'\]: `semantic_mask/xxxxx.bin` 语义标签的路径。
- `seg_info`:为支持语义分割任务所生成的信息文件。
- `Area_1_label_weight.npy`:每一语义类别的权重系数。因为 S3DIS 中属于不同类的点的数量相差很大,一个常见的操作是在计算损失时对不同类别进行加权 (label re-weighting) 以得到更好的分割性能。
- `Area_1_resampled_scene_idxs.npy`:每一个场景 (房间) 的重采样标签。在训练过程中,我们依据每个场景的点的数量,会对其进行不同次数的重采样,以保证训练数据均衡。
- `Area_1_label_weight.npy`:每一语义类别的权重系数。因为 S3DIS 中属于不同类的点的数量相差很大,一个常见的操作是在计算损失时对不同类别进行加权 (label re-weighting) 以得到更好的分割性能。
- `Area_1_resampled_scene_idxs.npy`:每一个场景 (房间) 的重采样标签。在训练过程中,我们依据每个场景的点的数量,会对其进行不同次数的重采样,以保证训练数据均衡。
## 训练流程
......@@ -205,13 +207,13 @@ train_pipeline = [
]
```
- `PointSegClassMapping`:在训练过程中,只有被使用的类别的序号会被映射到类似 [0, 13) 范围内的类别标签。其余的类别序号会被转换为 `ignore_index` 所制定的忽略标签,在本例中是 `13`。
- `PointSegClassMapping`:在训练过程中,只有被使用的类别的序号会被映射到类似 \[0, 13) 范围内的类别标签。其余的类别序号会被转换为 `ignore_index` 所制定的忽略标签,在本例中是 `13`
- `IndoorPatchPointSample`:从输入点云中裁剪一个含有固定数量点的小块 (patch)。`block_size` 指定了裁剪块的边长,在 S3DIS 上这个数值一般设置为 `1.0`
- `NormalizePointsColor`:将输入点的颜色信息归一化,通过将 RGB 值除以 `255` 来实现。
- 数据增广:
- `GlobalRotScaleTrans`:对输入点云进行随机旋转和放缩变换。
- `RandomJitterPoints`:通过对每一个点施加不同的噪声向量以实现对点云的随机扰动。
- `RandomDropPointsColor`:以 `drop_ratio` 的概率随机将点云的颜色值全部置零。
- `GlobalRotScaleTrans`:对输入点云进行随机旋转和放缩变换。
- `RandomJitterPoints`:通过对每一个点施加不同的噪声向量以实现对点云的随机扰动。
- `RandomDropPointsColor`:以 `drop_ratio` 的概率随机将点云的颜色值全部置零。
## 度量指标
......
......@@ -223,25 +223,25 @@ scannet
```
- `points/xxxxx.bin`:下采样后,未与坐标轴平行(即没有对齐)的点云。因为 ScanNet 3D 检测任务将与坐标轴平行的点云作为输入,而 ScanNet 3D 语义分割任务将对齐前的点云作为输入,我们选择存储对齐前的点云和它们的对齐矩阵。请注意:在 3D 检测的预处理流程 [`GlobalAlignment`](https://github.com/open-mmlab/mmdetection3d/blob/9f0b01caf6aefed861ef4c3eb197c09362d26b32/mmdet3d/datasets/pipelines/transforms_3d.py#L423) 后,点云就都是与坐标轴平行的了。
- `instance_mask/xxxxx.bin`:每个点的实例标签,值的范围为:[0, NUM_INSTANCES],其中 0 表示没有标注。
- `semantic_mask/xxxxx.bin`:每个点的语义标签,值的范围为:[1, 40], 也就是 `nyu40id` 的标准。请注意:在训练流程 `PointSegClassMapping` 中,`nyu40id` 的 ID 会被映射到训练 ID。
- `instance_mask/xxxxx.bin`:每个点的实例标签,值的范围为:\[0, NUM_INSTANCES\],其中 0 表示没有标注。
- `semantic_mask/xxxxx.bin`:每个点的语义标签,值的范围为:\[1, 40\], 也就是 `nyu40id` 的标准。请注意:在训练流程 `PointSegClassMapping` 中,`nyu40id` 的 ID 会被映射到训练 ID。
- `posed_images/scenexxxx_xx``.jpg` 图像的集合,还包含 `.txt` 格式的 4x4 相机姿态和单个 `.txt` 格式的相机内参矩阵文件。
- `scannet_infos_train.pkl`:训练集的数据信息,每个场景的具体信息如下:
- info['point_cloud']:`{'num_features': 6, 'lidar_idx': sample_idx}`,其中 `sample_idx` 为该场景的索引。
- info['pts_path']:`points/xxxxx.bin` 的路径。
- info['pts_instance_mask_path']:`instance_mask/xxxxx.bin` 的路径。
- info['pts_semantic_mask_path']:`semantic_mask/xxxxx.bin` 的路径。
- info['annos']:每个场景的标注。
- annotations['gt_num']:真实物体 (ground truth) 的数量。
- annotations['name']:所有真实物体的语义类别名称,比如 `chair`(椅子)。
- annotations['location']:depth 坐标系下与坐标轴平行的三维包围框的重力中心 (gravity center),形状为 [K, 3],其中 K 是真实物体的数量。
- annotations['dimensions']:depth 坐标系下与坐标轴平行的三维包围框的大小,形状为 [K, 3]。
- annotations['gt_boxes_upright_depth']:depth 坐标系下与坐标轴平行的三维包围框 `(x, y, z, x_size, y_size, z_size, yaw)`,形状为 [K, 6]。
- annotations['unaligned_location']:depth 坐标系下与坐标轴不平行(对齐前)的三维包围框的重力中心。
- annotations['unaligned_dimensions']:depth 坐标系下与坐标轴不平行的三维包围框的大小。
- annotations['unaligned_gt_boxes_upright_depth']:depth 坐标系下与坐标轴不平行的三维包围框。
- annotations['index']:所有真实物体的索引,范围为 [0, K)。
- annotations['class']:所有真实物体类别的标号,范围为 [0, 18),形状为 [K, ]。
- info\['point_cloud'\]`{'num_features': 6, 'lidar_idx': sample_idx}`,其中 `sample_idx` 为该场景的索引。
- info\['pts_path'\]`points/xxxxx.bin` 的路径。
- info\['pts_instance_mask_path'\]`instance_mask/xxxxx.bin` 的路径。
- info\['pts_semantic_mask_path'\]`semantic_mask/xxxxx.bin` 的路径。
- info\['annos'\]:每个场景的标注。
- annotations\['gt_num'\]:真实物体 (ground truth) 的数量。
- annotations\['name'\]:所有真实物体的语义类别名称,比如 `chair`(椅子)。
- annotations\['location'\]:depth 坐标系下与坐标轴平行的三维包围框的重力中心 (gravity center),形状为 \[K, 3\],其中 K 是真实物体的数量。
- annotations\['dimensions'\]:depth 坐标系下与坐标轴平行的三维包围框的大小,形状为 \[K, 3\]
- annotations\['gt_boxes_upright_depth'\]:depth 坐标系下与坐标轴平行的三维包围框 `(x, y, z, x_size, y_size, z_size, yaw)`,形状为 \[K, 6\]
- annotations\['unaligned_location'\]:depth 坐标系下与坐标轴不平行(对齐前)的三维包围框的重力中心。
- annotations\['unaligned_dimensions'\]:depth 坐标系下与坐标轴不平行的三维包围框的大小。
- annotations\['unaligned_gt_boxes_upright_depth'\]:depth 坐标系下与坐标轴不平行的三维包围框。
- annotations\['index'\]:所有真实物体的索引,范围为 \[0, K)。
- annotations\['class'\]:所有真实物体类别的标号,范围为 \[0, 18),形状为 \[K, \]
- `scannet_infos_val.pkl`:验证集上的数据信息,与 `scannet_infos_train.pkl` 格式完全一致。
- `scannet_infos_test.pkl`:测试集上的数据信息,与 `scannet_infos_train.pkl` 格式几乎完全一致,除了缺少标注。
......@@ -291,11 +291,11 @@ train_pipeline = [
```
- `GlobalAlignment`:输入的点云在施加了坐标轴平行的矩阵后应被转换为与坐标轴平行的形式。
- `PointSegClassMapping`:训练中,只有合法的类别 ID 才会被映射到类别标签,比如 [0, 18)。
- `PointSegClassMapping`:训练中,只有合法的类别 ID 才会被映射到类别标签,比如 \[0, 18)。
- 数据增强:
- `PointSample`:下采样输入点云。
- `RandomFlip3D`:随机左右或前后翻转点云。
- `GlobalRotScaleTrans`: 旋转输入点云,对于 ScanNet 角度通常落入 [-5, 5] (度)的范围;并放缩输入点云,对于 ScanNet 比例通常为 1.0(即不做缩放);最后平移输入点云,对于 ScanNet 通常位移量为 0(即不做位移)。
- `PointSample`:下采样输入点云。
- `RandomFlip3D`:随机左右或前后翻转点云。
- `GlobalRotScaleTrans`: 旋转输入点云,对于 ScanNet 角度通常落入 \[-5, 5\] (度)的范围;并放缩输入点云,对于 ScanNet 比例通常为 1.0(即不做缩放);最后平移输入点云,对于 ScanNet 通常位移量为 0(即不做位移)。
## 评估指标
......
......@@ -10,7 +10,6 @@ ScanNet 3D 语义分割数据集的准备和 3D 检测任务的准备很相似
因为 ScanNet 测试集对 3D 语义分割任务提供在线评测的基准,我们也需要下载其测试集并置于 `scannet` 目录下。
数据预处理前的文件目录结构应如下所示:
```
mmdetection3d
├── mmdet3d
......@@ -70,8 +69,8 @@ scannet
```
- `seg_info`:为支持语义分割任务所生成的信息文件。
- `train_label_weight.npy`:每一语义类别的权重系数。因为 ScanNet 中属于不同类的点的数量相差很大,一个常见的操作是在计算损失时对不同类别进行加权 (label re-weighting) 以得到更好的分割性能。
- `train_resampled_scene_idxs.npy`:每一个场景 (房间) 的重采样标签。在训练过程中,我们依据每个场景的点的数量,会对其进行不同次数的重采样,以保证训练数据均衡。
- `train_label_weight.npy`:每一语义类别的权重系数。因为 ScanNet 中属于不同类的点的数量相差很大,一个常见的操作是在计算损失时对不同类别进行加权 (label re-weighting) 以得到更好的分割性能。
- `train_resampled_scene_idxs.npy`:每一个场景 (房间) 的重采样标签。在训练过程中,我们依据每个场景的点的数量,会对其进行不同次数的重采样,以保证训练数据均衡。
## 训练流程
......@@ -111,7 +110,7 @@ train_pipeline = [
]
```
- `PointSegClassMapping`:在训练过程中,只有被使用的类别的序号会被映射到类似 [0, 20) 范围内的类别标签。其余的类别序号会被转换为 `ignore_index` 所制定的忽略标签,在本例中是 `20`。
- `PointSegClassMapping`:在训练过程中,只有被使用的类别的序号会被映射到类似 \[0, 20) 范围内的类别标签。其余的类别序号会被转换为 `ignore_index` 所制定的忽略标签,在本例中是 `20`
- `IndoorPatchPointSample`:从输入点云中裁剪一个含有固定数量点的小块 (patch)。`block_size` 指定了裁剪块的边长,在 ScanNet 上这个数值一般设置为 `1.5`
- `NormalizePointsColor`:将输入点的颜色信息归一化,通过将 RGB 值除以 `255` 来实现。
......
......@@ -239,25 +239,24 @@ sunrgbd
- `points/0xxxxx.bin`:降采样后的点云数据。
- `sunrgbd_infos_train.pkl`:训练集数据信息(标注与元信息),每个场景所含数据信息具体如下:
- info['point_cloud']:`{'num_features': 6, 'lidar_idx': sample_idx}`,其中 `sample_idx` 为该场景的索引。
- info['pts_path']:`points/0xxxxx.bin` 的路径。
- info['image']:图像路径与元信息:
- image['image_idx']:图像索引。
- image['image_shape']:图像张量的形状(即其尺寸)。
- image['image_path']:图像路径。
- info['annos']:每个场景的标注:
- annotations['gt_num']:真实物体 (ground truth) 的数量。
- annotations['name']:所有真实物体的语义类别名称,比如 `chair`(椅子)。
- annotations['location']:depth 坐标系下三维包围框的重力中心 (gravity center),形状为 [K, 3],其中 K 是真实物体的数量。
- annotations['dimensions']:depth 坐标系下三维包围框的大小,形状为 [K, 3]。
- annotations['rotation_y']:depth 坐标系下三维包围框的旋转角,形状为 [K, ]。
- annotations['gt_boxes_upright_depth']:depth 坐标系下三维包围框 `(x, y, z, x_size, y_size, z_size, yaw)`,形状为 [K, 7]。
- annotations['bbox']:二维包围框 `(x, y, x_size, y_size)`,形状为 [K, 4]。
- annotations['index']:所有真实物体的索引,范围为 [0, K)。
- annotations['class']:所有真实物体类别的标号,范围为 [0, 10),形状为 [K, ]。
- info\['point_cloud'\]`{'num_features': 6, 'lidar_idx': sample_idx}`,其中 `sample_idx` 为该场景的索引。
- info\['pts_path'\]`points/0xxxxx.bin` 的路径。
- info\['image'\]:图像路径与元信息:
- image\['image_idx'\]:图像索引。
- image\['image_shape'\]:图像张量的形状(即其尺寸)。
- image\['image_path'\]:图像路径。
- info\['annos'\]:每个场景的标注:
- annotations\['gt_num'\]:真实物体 (ground truth) 的数量。
- annotations\['name'\]:所有真实物体的语义类别名称,比如 `chair`(椅子)。
- annotations\['location'\]:depth 坐标系下三维包围框的重力中心 (gravity center),形状为 \[K, 3\],其中 K 是真实物体的数量。
- annotations\['dimensions'\]:depth 坐标系下三维包围框的大小,形状为 \[K, 3\]
- annotations\['rotation_y'\]:depth 坐标系下三维包围框的旋转角,形状为 \[K, \]
- annotations\['gt_boxes_upright_depth'\]:depth 坐标系下三维包围框 `(x, y, z, x_size, y_size, z_size, yaw)`,形状为 \[K, 7\]
- annotations\['bbox'\]:二维包围框 `(x, y, x_size, y_size)`,形状为 \[K, 4\]
- annotations\['index'\]:所有真实物体的索引,范围为 \[0, K)。
- annotations\['class'\]:所有真实物体类别的标号,范围为 \[0, 10),形状为 \[K, \]
- `sunrgbd_infos_val.pkl`:验证集上的数据信息,与 `sunrgbd_infos_train.pkl` 格式完全一致。
## 训练流程
SUN RGB-D 上纯点云 3D 物体检测的典型流程如下:
......@@ -288,8 +287,9 @@ train_pipeline = [
```
点云上的数据增强
- `RandomFlip3D`:随机左右或前后翻转输入点云。
- `GlobalRotScaleTrans`:旋转输入点云,对于 SUN RGB-D 角度通常落入 [-30, 30] (度)的范围;并放缩输入点云,对于 SUN RGB-D 比例通常落入 [0.85, 1.15] 的范围;最后平移输入点云,对于 SUN RGB-D 通常位移量为 0(即不做位移)。
- `GlobalRotScaleTrans`:旋转输入点云,对于 SUN RGB-D 角度通常落入 \[-30, 30\] (度)的范围;并放缩输入点云,对于 SUN RGB-D 比例通常落入 \[0.85, 1.15\] 的范围;最后平移输入点云,对于 SUN RGB-D 通常位移量为 0(即不做位移)。
- `PointSample`:降采样输入点云。
SUN RGB-D 上多模态(点云和图像)3D 物体检测的典型流程如下:
......@@ -331,6 +331,7 @@ train_pipeline = [
```
图像上的数据增强/归一化
- `Resize`: 改变输入图像的大小, `keep_ratio=True` 意味着图像的比例不改变。
- `Normalize`: 归一化图像的 RGB 通道。
- `RandomFlip`: 随机地翻折图像。
......
......@@ -103,36 +103,36 @@ mmdetection3d
为了在 Waymo 数据集上进行检测性能评估,请按照[此处指示](https://github.com/waymo-research/waymo-open-dataset/blob/master/docs/quick_start.md/)构建用于计算评估指标的二进制文件 `compute_detection_metrics_main`,并将它置于 `mmdet3d/core/evaluation/waymo_utils/` 下。您基本上可以按照下方命令安装 `bazel`,然后构建二进制文件:
```shell
# download the code and enter the base directory
git clone https://github.com/waymo-research/waymo-open-dataset.git waymo-od
cd waymo-od
git checkout remotes/origin/master
# use the Bazel build system
sudo apt-get install --assume-yes pkg-config zip g++ zlib1g-dev unzip python3 python3-pip
BAZEL_VERSION=3.1.0
wget https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh
sudo bash bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh
sudo apt install build-essential
# configure .bazelrc
./configure.sh
# delete previous bazel outputs and reset internal caches
bazel clean
bazel build waymo_open_dataset/metrics/tools/compute_detection_metrics_main
cp bazel-bin/waymo_open_dataset/metrics/tools/compute_detection_metrics_main ../mmdetection3d/mmdet3d/core/evaluation/waymo_utils/
```
```shell
# download the code and enter the base directory
git clone https://github.com/waymo-research/waymo-open-dataset.git waymo-od
cd waymo-od
git checkout remotes/origin/master
# use the Bazel build system
sudo apt-get install --assume-yes pkg-config zip g++ zlib1g-dev unzip python3 python3-pip
BAZEL_VERSION=3.1.0
wget https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh
sudo bash bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh
sudo apt install build-essential
# configure .bazelrc
./configure.sh
# delete previous bazel outputs and reset internal caches
bazel clean
bazel build waymo_open_dataset/metrics/tools/compute_detection_metrics_main
cp bazel-bin/waymo_open_dataset/metrics/tools/compute_detection_metrics_main ../mmdetection3d/mmdet3d/core/evaluation/waymo_utils/
```
接下来,您就可以在 Waymo 上评估您的模型了。如下示例是使用 8 个图形处理器 (GPU) 在 Waymo 上用 Waymo 评价指标评估 PointPillars 模型的情景:
```shell
./tools/slurm_test.sh ${PARTITION} ${JOB_NAME} configs/pointpillars/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car.py \
checkpoints/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car_latest.pth --out results/waymo-car/results_eval.pkl \
--eval waymo --eval-options 'pklfile_prefix=results/waymo-car/kitti_results' \
'submission_prefix=results/waymo-car/kitti_results'
```
```shell
./tools/slurm_test.sh ${PARTITION} ${JOB_NAME} configs/pointpillars/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car.py \
checkpoints/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car_latest.pth --out results/waymo-car/results_eval.pkl \
--eval waymo --eval-options 'pklfile_prefix=results/waymo-car/kitti_results' \
'submission_prefix=results/waymo-car/kitti_results'
```
如果需要生成 bin 文件,应在 `--eval-options` 中给出 `pklfile_prefix`。对于评价指标, `waymo` 是我们推荐的官方评估原型。目前,`kitti` 这一评估选项是从 KITTI 迁移而来的,且每个难度下的评估结果和 KITTI 数据集中定义得到的不尽相同——目前大多数物体被标记为难度 0(日后会修复)。`kitti` 评估选项的不稳定来源于很大的计算量,转换的数据中遮挡 (occlusion) 和截断 (truncation) 的缺失,难度的不同定义方式,以及不同的平均精度 (Average Precision) 计算方式。
......@@ -148,28 +148,28 @@ mmdetection3d
如下是一个使用 8 个图形处理器在 Waymo 上测试 PointPillars,生成 bin 文件并提交结果到官方榜单的例子:
```shell
./tools/slurm_test.sh ${PARTITION} ${JOB_NAME} configs/pointpillars/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car.py \
checkpoints/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car_latest.pth --out results/waymo-car/results_eval.pkl \
--format-only --eval-options 'pklfile_prefix=results/waymo-car/kitti_results' \
'submission_prefix=results/waymo-car/kitti_results'
```
```shell
./tools/slurm_test.sh ${PARTITION} ${JOB_NAME} configs/pointpillars/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car.py \
checkpoints/hv_pointpillars_secfpn_sbn-2x16_2x_waymo-3d-car_latest.pth --out results/waymo-car/results_eval.pkl \
--format-only --eval-options 'pklfile_prefix=results/waymo-car/kitti_results' \
'submission_prefix=results/waymo-car/kitti_results'
```
在生成 bin 文件后,您可以简单地构建二进制文件 `create_submission`,并按照[指示](https://github.com/waymo-research/waymo-open-dataset/blob/master/docs/quick_start.md/) 创建一个提交文件。下面是一些示例:
```shell
cd ../waymo-od/
bazel build waymo_open_dataset/metrics/tools/create_submission
cp bazel-bin/waymo_open_dataset/metrics/tools/create_submission ../mmdetection3d/mmdet3d/core/evaluation/waymo_utils/
vim waymo_open_dataset/metrics/tools/submission.txtpb # set the metadata information
cp waymo_open_dataset/metrics/tools/submission.txtpb ../mmdetection3d/mmdet3d/core/evaluation/waymo_utils/
```shell
cd ../waymo-od/
bazel build waymo_open_dataset/metrics/tools/create_submission
cp bazel-bin/waymo_open_dataset/metrics/tools/create_submission ../mmdetection3d/mmdet3d/core/evaluation/waymo_utils/
vim waymo_open_dataset/metrics/tools/submission.txtpb # set the metadata information
cp waymo_open_dataset/metrics/tools/submission.txtpb ../mmdetection3d/mmdet3d/core/evaluation/waymo_utils/
cd ../mmdetection3d
# suppose the result bin is in `results/waymo-car/submission`
mmdet3d/core/evaluation/waymo_utils/create_submission --input_filenames='results/waymo-car/kitti_results_test.bin' --output_filename='results/waymo-car/submission/model' --submission_filename='mmdet3d/core/evaluation/waymo_utils/submission.txtpb'
cd ../mmdetection3d
# suppose the result bin is in `results/waymo-car/submission`
mmdet3d/core/evaluation/waymo_utils/create_submission --input_filenames='results/waymo-car/kitti_results_test.bin' --output_filename='results/waymo-car/submission/model' --submission_filename='mmdet3d/core/evaluation/waymo_utils/submission.txtpb'
tar cvf results/waymo-car/submission/my_model.tar results/waymo-car/submission/my_model/
gzip results/waymo-car/submission/my_model.tar
```
tar cvf results/waymo-car/submission/my_model.tar results/waymo-car/submission/my_model/
gzip results/waymo-car/submission/my_model.tar
```
如果想用官方评估服务器评估您在验证集上的结果,您可以使用同样的方法生成提交文件,只需确保您在运行如上指令前更改 `submission.txtpb` 中的字段值即可。
......@@ -6,7 +6,7 @@
- 如果您在 `import open3d` 时遇到下面的问题:
``OSError: /lib/x86_64-linux-gnu/libm.so.6: version 'GLIBC_2.27' not found``
`OSError: /lib/x86_64-linux-gnu/libm.so.6: version 'GLIBC_2.27' not found`
请将 open3d 的版本降级至 0.9.0.0,因为最新版 open3d 需要 'GLIBC_2.27' 文件的支持, Ubuntu 16.04 系统中缺失该文件,且该文件仅存在于 Ubuntu 18.04 及之后的系统中。
......@@ -21,15 +21,15 @@
- 如果您在导入 pycocotools 相关包时遇到下面的问题:
``ValueError: numpy.ndarray size changed, may indicate binary incompatibility. Expected 88 from C header, got 80 from PyObject``
`ValueError: numpy.ndarray size changed, may indicate binary incompatibility. Expected 88 from C header, got 80 from PyObject`
请将 pycocotools 的版本降级至 2.0.1,这是由于最新版本的 pycocotools 与 numpy < 1.20.0 不兼容。或者通过下面的方式从源码进行编译来安装最新版本的 pycocotools :
请将 pycocotools 的版本降级至 2.0.1,这是由于最新版本的 pycocotools 与 numpy \< 1.20.0 不兼容。或者通过下面的方式从源码进行编译来安装最新版本的 pycocotools :
``pip install -e "git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI"``
`pip install -e "git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI"`
或者
``pip install -e "git+https://github.com/ppwwyyxx/cocoapi#egg=pycocotools&subdirectory=PythonAPI"``
`pip install -e "git+https://github.com/ppwwyyxx/cocoapi#egg=pycocotools&subdirectory=PythonAPI"`
## 如何标注点云?
......
......@@ -7,30 +7,30 @@
- GCC 5+
- [MMCV](https://mmcv.readthedocs.io/en/latest/#installation)
| MMDetection3D 版本 | MMDetection 版本 | MMSegmentation 版本 | MMCV 版本 |
|:-------------------:|:-------------------:|:-------------------:|:-------------------:|
| master | mmdet>=2.19.0, <=3.0.0| mmseg>=0.20.0, <=1.0.0 | mmcv-full>=1.4.8, <=1.7.0|
| v1.0.0rc2 | mmdet>=2.19.0, <=3.0.0| mmseg>=0.20.0, <=1.0.0 | mmcv-full>=1.4.8, <=1.7.0|
| v1.0.0rc1 | mmdet>=2.19.0, <=3.0.0| mmseg>=0.20.0, <=1.0.0 | mmcv-full>=1.4.8, <=1.5.0|
| v1.0.0rc0 | mmdet>=2.19.0, <=3.0.0| mmseg>=0.20.0, <=1.0.0 | mmcv-full>=1.3.17, <=1.5.0|
| 0.18.1 | mmdet>=2.19.0, <=3.0.0| mmseg>=0.20.0, <=1.0.0 | mmcv-full>=1.3.17, <=1.5.0|
| 0.18.0 | mmdet>=2.19.0, <=3.0.0| mmseg>=0.20.0, <=1.0.0 | mmcv-full>=1.3.17, <=1.5.0|
| 0.17.3 | mmdet>=2.14.0, <=3.0.0| mmseg>=0.14.1, <=1.0.0 | mmcv-full>=1.3.8, <=1.4.0|
| 0.17.2 | mmdet>=2.14.0, <=3.0.0| mmseg>=0.14.1, <=1.0.0 | mmcv-full>=1.3.8, <=1.4.0|
| 0.17.1 | mmdet>=2.14.0, <=3.0.0| mmseg>=0.14.1, <=1.0.0 | mmcv-full>=1.3.8, <=1.4.0|
| 0.17.0 | mmdet>=2.14.0, <=3.0.0| mmseg>=0.14.1, <=1.0.0 | mmcv-full>=1.3.8, <=1.4.0|
| 0.16.0 | mmdet>=2.14.0, <=3.0.0| mmseg>=0.14.1, <=1.0.0 | mmcv-full>=1.3.8, <=1.4.0|
| 0.15.0 | mmdet>=2.14.0, <=3.0.0| mmseg>=0.14.1, <=1.0.0 | mmcv-full>=1.3.8, <=1.4.0|
| 0.14.0 | mmdet>=2.10.0, <=2.11.0| mmseg==0.14.0 | mmcv-full>=1.3.1, <=1.4.0|
| 0.13.0 | mmdet>=2.10.0, <=2.11.0| Not required | mmcv-full>=1.2.4, <=1.4.0|
| 0.12.0 | mmdet>=2.5.0, <=2.11.0 | Not required | mmcv-full>=1.2.4, <=1.4.0|
| 0.11.0 | mmdet>=2.5.0, <=2.11.0 | Not required | mmcv-full>=1.2.4, <=1.3.0|
| 0.10.0 | mmdet>=2.5.0, <=2.11.0 | Not required | mmcv-full>=1.2.4, <=1.3.0|
| 0.9.0 | mmdet>=2.5.0, <=2.11.0 | Not required | mmcv-full>=1.2.4, <=1.3.0|
| 0.8.0 | mmdet>=2.5.0, <=2.11.0 | Not required | mmcv-full>=1.1.5, <=1.3.0|
| 0.7.0 | mmdet>=2.5.0, <=2.11.0 | Not required | mmcv-full>=1.1.5, <=1.3.0|
| 0.6.0 | mmdet>=2.4.0, <=2.11.0 | Not required | mmcv-full>=1.1.3, <=1.2.0|
| 0.5.0 | 2.3.0 | Not required | mmcv-full==1.0.5|
| MMDetection3D 版本 | MMDetection 版本 | MMSegmentation 版本 | MMCV 版本 |
| :--------------: | :----------------------: | :---------------------: | :-------------------------: |
| master | mmdet>=2.19.0, \<=3.0.0 | mmseg>=0.20.0, \<=1.0.0 | mmcv-full>=1.4.8, \<=1.7.0 |
| v1.0.0rc2 | mmdet>=2.19.0, \<=3.0.0 | mmseg>=0.20.0, \<=1.0.0 | mmcv-full>=1.4.8, \<=1.7.0 |
| v1.0.0rc1 | mmdet>=2.19.0, \<=3.0.0 | mmseg>=0.20.0, \<=1.0.0 | mmcv-full>=1.4.8, \<=1.5.0 |
| v1.0.0rc0 | mmdet>=2.19.0, \<=3.0.0 | mmseg>=0.20.0, \<=1.0.0 | mmcv-full>=1.3.17, \<=1.5.0 |
| 0.18.1 | mmdet>=2.19.0, \<=3.0.0 | mmseg>=0.20.0, \<=1.0.0 | mmcv-full>=1.3.17, \<=1.5.0 |
| 0.18.0 | mmdet>=2.19.0, \<=3.0.0 | mmseg>=0.20.0, \<=1.0.0 | mmcv-full>=1.3.17, \<=1.5.0 |
| 0.17.3 | mmdet>=2.14.0, \<=3.0.0 | mmseg>=0.14.1, \<=1.0.0 | mmcv-full>=1.3.8, \<=1.4.0 |
| 0.17.2 | mmdet>=2.14.0, \<=3.0.0 | mmseg>=0.14.1, \<=1.0.0 | mmcv-full>=1.3.8, \<=1.4.0 |
| 0.17.1 | mmdet>=2.14.0, \<=3.0.0 | mmseg>=0.14.1, \<=1.0.0 | mmcv-full>=1.3.8, \<=1.4.0 |
| 0.17.0 | mmdet>=2.14.0, \<=3.0.0 | mmseg>=0.14.1, \<=1.0.0 | mmcv-full>=1.3.8, \<=1.4.0 |
| 0.16.0 | mmdet>=2.14.0, \<=3.0.0 | mmseg>=0.14.1, \<=1.0.0 | mmcv-full>=1.3.8, \<=1.4.0 |
| 0.15.0 | mmdet>=2.14.0, \<=3.0.0 | mmseg>=0.14.1, \<=1.0.0 | mmcv-full>=1.3.8, \<=1.4.0 |
| 0.14.0 | mmdet>=2.10.0, \<=2.11.0 | mmseg==0.14.0 | mmcv-full>=1.3.1, \<=1.4.0 |
| 0.13.0 | mmdet>=2.10.0, \<=2.11.0 | Not required | mmcv-full>=1.2.4, \<=1.4.0 |
| 0.12.0 | mmdet>=2.5.0, \<=2.11.0 | Not required | mmcv-full>=1.2.4, \<=1.4.0 |
| 0.11.0 | mmdet>=2.5.0, \<=2.11.0 | Not required | mmcv-full>=1.2.4, \<=1.3.0 |
| 0.10.0 | mmdet>=2.5.0, \<=2.11.0 | Not required | mmcv-full>=1.2.4, \<=1.3.0 |
| 0.9.0 | mmdet>=2.5.0, \<=2.11.0 | Not required | mmcv-full>=1.2.4, \<=1.3.0 |
| 0.8.0 | mmdet>=2.5.0, \<=2.11.0 | Not required | mmcv-full>=1.1.5, \<=1.3.0 |
| 0.7.0 | mmdet>=2.5.0, \<=2.11.0 | Not required | mmcv-full>=1.1.5, \<=1.3.0 |
| 0.6.0 | mmdet>=2.4.0, \<=2.11.0 | Not required | mmcv-full>=1.1.3, \<=1.2.0 |
| 0.5.0 | 2.3.0 | Not required | mmcv-full==1.0.5 |
# 安装
......@@ -91,6 +91,7 @@ conda install pytorch=1.3.1 cudatoolkit=9.2 torchvision=0.4.2 -c pytorch
```shell
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/{cu_version}/{torch_version}/index.html
```
需要把命令行中的 `{cu_version}``{torch_version}` 替换成对应的版本。例如:在 CUDA 11 和 PyTorch 1.7.0 的环境下,可以使用下面命令安装最新版本的 MMCV:
```shell
......@@ -140,6 +141,7 @@ pip install -v -e . # or "python setup.py develop"
```shell
pip install mmsegmentation
```
同时,如果你想修改这部分的代码,也可以通过以下命令从源码编译 MMSegmentation:
```shell
......@@ -156,8 +158,6 @@ git clone https://github.com/open-mmlab/mmdetection3d.git
cd mmdetection3d
```
**g. 安装依赖包和 MMDetection3D.**
```shell
......@@ -168,19 +168,19 @@ pip install -v -e . # or "python setup.py develop"
1. Git 的 commit id 在步骤 d 将会被写入到版本号当中,例 0.6.0+2e7045c 。版本号将保存在训练的模型里。推荐在每一次执行步骤 d 时,从 github 上获取最新的更新。如果基于 C++/CUDA 的代码被修改了,请执行以下步骤;
> 重要: 如果你重装了不同版本的 CUDA 或者 PyTorch 的 mmdet,请务必移除 `./build` 文件。
> 重要: 如果你重装了不同版本的 CUDA 或者 PyTorch 的 mmdet,请务必移除 `./build` 文件。
```shell
pip uninstall mmdet3d
rm -rf ./build
find . -name "*.so" | xargs rm
```
```shell
pip uninstall mmdet3d
rm -rf ./build
find . -name "*.so" | xargs rm
```
2. 按照上述说明,MMDetection3D 安装在 `dev` 模式下,因此在本地对代码做的任何修改都会生效,无需重新安装;
3. 如果希望使用 `opencv-python-headless` 而不是 `opencv-python`, 可以在安装 MMCV 之前安装;
4. 一些安装依赖是可以选择的。例如只需要安装最低运行要求的版本,则可以使用 `pip install -v -e .` 命令。如果希望使用可选择的像 `albumentations``imagecorruptions` 这种依赖项,可以使用 `pip install -r requirements/optional.txt ` 进行手动安装,或者在使用 `pip` 时指定所需的附加功能(例如 `pip install -v -e .[optional]`),支持附加功能的有效键值包括 `all``tests``build` 以及 `optional`
4. 一些安装依赖是可以选择的。例如只需要安装最低运行要求的版本,则可以使用 `pip install -v -e .` 命令。如果希望使用可选择的像 `albumentations``imagecorruptions` 这种依赖项,可以使用 `pip install -r requirements/optional.txt ` 进行手动安装,或者在使用 `pip` 时指定所需的附加功能(例如 `pip install -v -e .[optional]`),支持附加功能的有效键值包括 `all``tests``build` 以及 `optional`
5. 我们的代码目前不能在只有 CPU 的环境(CUDA 不可用)下编译运行。
......@@ -253,7 +253,7 @@ python demo/pcd_demo.py demo/data/kitti/kitti_000008.bin configs/second/hv_secon
如果你想输入一个 `ply` 格式的文件,你可以使用如下函数将它转换为 `bin` 的文件格式。然后就可以使用转化成 `bin` 格式的文件去运行样例程序。
请注意在使用此脚本前,你需要先安装 `pandas``plyfile`。 这个函数也可使用在数据预处理当中,为了能够直接训练 ```ply data```
请注意在使用此脚本前,你需要先安装 `pandas``plyfile`。 这个函数也可使用在数据预处理当中,为了能够直接训练 `ply data`
```python
import numpy as np
......
# 教程 7: 后端支持
我们支持不同的文件客户端后端:磁盘、Ceph 和 LMDB 等。下面是修改配置使之从 Ceph 加载和保存数据的示例。
## 从 Ceph 读取数据和标注文件
......@@ -93,9 +94,8 @@ data = dict(
test=dict(pipeline=test_pipeline, classes=class_names, file_client_args=file_client_args))
```
## 从 Ceph 读取预训练模型
```python
model = dict(
pts_backbone=dict(
......@@ -108,6 +108,7 @@ model = dict(
```
## 从 Ceph 读取模型权重文件
```python
# replace the path with your checkpoint path on Ceph
load_from = 's3://openmmlab/checkpoints/mmdetection3d/v0.1.0_models/pointpillars/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car_20200620_230614-77663cd6.pth.pth'
......@@ -131,6 +132,7 @@ evaluation = dict(interval=1, save_best='bbox', out_dir='s3://openmmlab/mmdetect
```
## 训练日志保存至 Ceph
训练后的训练日志会备份到指定的 Ceph 路径。
```python
......@@ -140,6 +142,7 @@ log_config = dict(
dict(type='TextLoggerHook', out_dir='s3://openmmlab/mmdetection3d'),
])
```
您还可以通过设置 `keep_local = False` 备份到指定的 Ceph 路径后删除本地训练日志。
```python
......
......@@ -34,15 +34,15 @@
- `{backbone}`: 主干网络种类例如 `regnet-400mf``regnet-1.6gf` 等。
- `{neck}`:模型颈部的种类包括 `fpn``secfpn` 等。
- `[norm_setting]`:如无特殊声明,默认使用 `bn` (Batch Normalization),其他类型可以有 `gn` (Group Normalization)、`sbn` (Synchronized Batch Normalization) 等。
`gn-head`/`gn-neck` 表示 GN 仅应用于网络的头部或颈部,而 `gn-all` 表示 GN 用于整个模型,例如主干网络、颈部和头部。
`gn-head`/`gn-neck` 表示 GN 仅应用于网络的头部或颈部,而 `gn-all` 表示 GN 用于整个模型,例如主干网络、颈部和头部。
- `[misc]`:模型中各式各样的设置/插件,例如 `strong-aug` 意味着在训练过程中使用更强的数据增广策略。
- `[batch_per_gpu x gpu]`:每个 GPU 的样本数和 GPU 数量,默认使用 `4x8`
- `{schedule}`:训练方案,选项是 `1x``2x``20e` 等。
`1x``2x` 分别代表训练 12 和 24 轮。
`20e` 在级联模型中使用,表示训练 20 轮。
对于 `1x`/`2x`,初始学习率在第 8/16 和第 11/22 轮衰减 10 倍;对于 `20e`,初始学习率在第 16 和第 19 轮衰减 10 倍。
`1x``2x` 分别代表训练 12 和 24 轮。
`20e` 在级联模型中使用,表示训练 20 轮。
对于 `1x`/`2x`,初始学习率在第 8/16 和第 11/22 轮衰减 10 倍;对于 `20e`,初始学习率在第 16 和第 19 轮衰减 10 倍。
- `{dataset}`:数据集,例如 `nus-3d``kitti-3d``lyft-3d``scannet-3d``sunrgbd-3d` 等。
当某一数据集存在多种设定时,我们也标记下所使用的类别数量,例如 `kitti-3d-3class``kitti-3d-car` 分别意味着在 KITTI 的所有三类上和单独车这一类上进行训练。
当某一数据集存在多种设定时,我们也标记下所使用的类别数量,例如 `kitti-3d-3class``kitti-3d-car` 分别意味着在 KITTI 的所有三类上和单独车这一类上进行训练。
## 弃用的 train_cfg/test_cfg
......
......@@ -7,43 +7,43 @@ MMDetection3D 使用 3 种不同的坐标系。3D 目标检测领域中不同坐
尽管数据集和采集设备多种多样,但是通过总结 3D 目标检测的工作线,我们可以将坐标系大致分为三类:
- 相机坐标系 -- 大多数相机的坐标系,在该坐标系中 y 轴正方向指向地面,x 轴正方向指向右侧,z 轴正方向指向前方。
```
上 z 前
| ^
| /
| /
| /
|/
左 ------ 0 ------> x 右
|
|
|
|
v
y 下
```
```
上 z 前
| ^
| /
| /
| /
|/
左 ------ 0 ------> x 右
|
|
|
|
v
y 下
```
- 激光雷达坐标系 -- 众多激光雷达的坐标系,在该坐标系中 z 轴负方向指向地面,x 轴正方向指向前方,y 轴正方向指向左侧。
```
z 上 x 前
^ ^
| /
| /
| /
|/
y 左 <------ 0 ------ 右
```
```
z 上 x 前
^ ^
| /
| /
| /
|/
y 左 <------ 0 ------ 右
```
- 深度坐标系 -- VoteNet、H3DNet 等模型使用的坐标系,在该坐标系中 z 轴负方向指向地面,x 轴正方向指向右侧,y 轴正方向指向前方。
```
z 上 y 前
^ ^
| /
| /
| /
|/
左 ------ 0 ------> x 右
```
该教程中的坐标系定义实际上**不仅仅是定义三个轴**。对于形如 ``$$`(x, y, z, dx, dy, dz, r)`$$`` 的框来说,我们的坐标系也定义了如何解释框的尺寸 ``$$`(dx, dy, dz)`$$`` 和转向角 (yaw) 角度 ``$$`r`$$``
```
z 上 y 前
^ ^
| /
| /
| /
|/
左 ------ 0 ------> x 右
```
该教程中的坐标系定义实际上**不仅仅是定义三个轴**。对于形如 `` $$`(x, y, z, dx, dy, dz, r)`$$ `` 的框来说,我们的坐标系也定义了如何解释框的尺寸 `` $$`(dx, dy, dz)`$$ `` 和转向角 (yaw) 角度 `` $$`r`$$ ``
三个坐标系的图示如下:
......@@ -55,13 +55,13 @@ MMDetection3D 使用 3 种不同的坐标系。3D 目标检测领域中不同坐
## 转向角 (yaw) 的定义
请参考[维基百科](https://en.wikipedia.org/wiki/Euler_angles#Tait%E2%80%93Bryan_angles)了解转向角的标准定义。在目标检测中,我们选择一个轴作为重力轴,并在垂直于重力轴的平面 ``$$`\Pi`$$`` 上选取一个参考方向,那么参考方向的转向角为 0,在 ``$$`\Pi`$$`` 上的其他方向有非零的转向角,其角度取决于其与参考方向的角度。
请参考[维基百科](https://en.wikipedia.org/wiki/Euler_angles#Tait%E2%80%93Bryan_angles)了解转向角的标准定义。在目标检测中,我们选择一个轴作为重力轴,并在垂直于重力轴的平面 `` $$`\Pi`$$ `` 上选取一个参考方向,那么参考方向的转向角为 0,在 `` $$`\Pi`$$ `` 上的其他方向有非零的转向角,其角度取决于其与参考方向的角度。
目前,对于所有支持的数据集,标注不包括俯仰角 (pitch) 和滚动角 (roll),这意味着我们在预测框和计算框之间的重叠时只需考虑转向角 (yaw)。
在 MMDetection3D 中,所有坐标系都是右手坐标系,这意味着如果从重力轴的负方向(轴的正方向指向人眼)看,转向角 (yaw) 沿着逆时针方向增加。
下图显示,在右手坐标系中,如果我们设定 x 轴正方向为参考方向,那么 y 轴正方向的转向角 (yaw) 为 ``$$`\frac{\pi}{2}`$$``
下图显示,在右手坐标系中,如果我们设定 x 轴正方向为参考方向,那么 y 轴正方向的转向角 (yaw) 为 `` $$`\frac{\pi}{2}`$$ ``
```
z 上 y 前 (yaw=0.5*pi)
......@@ -92,9 +92,9 @@ __|____|____|____|______\ x 右
## 框尺寸的定义
框尺寸的定义与转向角 (yaw) 的定义是分不开的。在上一节中,我们提到如果一个框的转向角 (yaw) 为 0,它的方向就被定义为与 x 轴平行。那么自然地,一个框对应于 x 轴的尺寸应该是 ``$$`dx`$$``。但是,这在某些数据集中并非总是如此(我们稍后会解决这个问题)。
框尺寸的定义与转向角 (yaw) 的定义是分不开的。在上一节中,我们提到如果一个框的转向角 (yaw) 为 0,它的方向就被定义为与 x 轴平行。那么自然地,一个框对应于 x 轴的尺寸应该是 `` $$`dx`$$ ``。但是,这在某些数据集中并非总是如此(我们稍后会解决这个问题)。
下图展示了 x 轴和 ``$$`dx`$$``,y 轴和 ``$$`dy`$$`` 对应的含义。
下图展示了 x 轴和 `` $$`dx`$$ ``,y 轴和 `` $$`dy`$$ `` 对应的含义。
```
y 前
......@@ -111,7 +111,7 @@ __|____|____|____|______\ x 右
| dy
```
注意框的方向总是和 ``$$`dx`$$`` 边平行。
注意框的方向总是和 `` $$`dx`$$ `` 边平行。
```
y 前
......@@ -138,12 +138,12 @@ KITTI 数据集的原始标注是在相机坐标系下的,详见 [get_label_an
![](https://raw.githubusercontent.com/traveller59/second.pytorch/master/images/kittibox.png)
对于每个框来说,尺寸为 ``$$`(w, l, h)`$$``,转向角 (yaw) 的参考方向为 y 轴正方向。更多细节请参考[代码库](https://github.com/traveller59/second.pytorch#concepts)
对于每个框来说,尺寸为 `` $$`(w, l, h)`$$ ``,转向角 (yaw) 的参考方向为 y 轴正方向。更多细节请参考[代码库](https://github.com/traveller59/second.pytorch#concepts)
我们的激光雷达坐标系有两处改变:
- 转向角 (yaw) 被定义为右手而非左手,从而保持一致性;
- 框的尺寸为 ``$$`(l, w, h)`$$`` 而非 ``$$`(w, l, h)`$$``,由于在 KITTI 数据集中 ``$$`w`$$`` 对应 ``$$`dy`$$````$$`l`$$`` 对应 ``$$`dx`$$``
- 框的尺寸为 `` $$`(l, w, h)`$$ `` 而非 `` $$`(w, l, h)`$$ ``,由于在 KITTI 数据集中 `` $$`w`$$ `` 对应 `` $$`dy`$$ ```` $$`l`$$ `` 对应 `` $$`dx`$$ ``
### Waymo
......@@ -151,7 +151,7 @@ KITTI 数据集的原始标注是在相机坐标系下的,详见 [get_label_an
### NuScenes
NuScenes 提供了一个评估工具包,其中每个框都被包装成一个 `Box` 实例。`Box` 的坐标系不同于我们的激光雷达坐标系,在 `Box` 坐标系中,前两个表示框尺寸的元素分别对应 ``$$`(dy, dx)`$$`` 或者 ``$$`(w, l)`$$``,和我们的表示方法相反。更多细节请参考 NuScenes [教程](https://github.com/open-mmlab/mmdetection3d/blob/master/docs/zh_cn/datasets/nuscenes_det.md#notes)
NuScenes 提供了一个评估工具包,其中每个框都被包装成一个 `Box` 实例。`Box` 的坐标系不同于我们的激光雷达坐标系,在 `Box` 坐标系中,前两个表示框尺寸的元素分别对应 `` $$`(dy, dx)`$$ `` 或者 `` $$`(w, l)`$$ ``,和我们的表示方法相反。更多细节请参考 NuScenes [教程](https://github.com/open-mmlab/mmdetection3d/blob/master/docs/zh_cn/datasets/nuscenes_det.md#notes)
读者可以参考 [NuScenes 开发工具](https://github.com/nutonomy/nuscenes-devkit/tree/master/python-sdk/nuscenes/eval/detection),了解 [NuScenes 框](https://github.com/nutonomy/nuscenes-devkit/blob/2c6a752319f23910d5f55cc995abc547a9e54142/python-sdk/nuscenes/utils/data_classes.py#L457) 的定义和 [NuScenes 评估](https://github.com/nutonomy/nuscenes-devkit/blob/master/python-sdk/nuscenes/eval/detection/evaluate.py)的过程。
......@@ -183,25 +183,25 @@ SUN RGB-D 的原始数据不是点云而是 RGB-D 图像。我们通过反投影
首先,对于点和框的中心点,坐标转换前后满足下列关系:
- ``$$`x_{LiDAR}=z_{camera}`$$``
- ``$$`y_{LiDAR}=-x_{camera}`$$``
- ``$$`z_{LiDAR}=-y_{camera}`$$``
- `` $$`x_{LiDAR}=z_{camera}`$$ ``
- `` $$`y_{LiDAR}=-x_{camera}`$$ ``
- `` $$`z_{LiDAR}=-y_{camera}`$$ ``
然后,框的尺寸转换前后满足下列关系:
- ``$$`dx_{LiDAR}=dx_{camera}`$$``
- ``$$`dy_{LiDAR}=dz_{camera}`$$``
- ``$$`dz_{LiDAR}=dy_{camera}`$$``
- `` $$`dx_{LiDAR}=dx_{camera}`$$ ``
- `` $$`dy_{LiDAR}=dz_{camera}`$$ ``
- `` $$`dz_{LiDAR}=dy_{camera}`$$ ``
最后,转向角 (yaw) 也应该被转换:
- ``$$`r_{LiDAR}=-\frac{\pi}{2}-r_{camera}`$$``
- `` $$`r_{LiDAR}=-\frac{\pi}{2}-r_{camera}`$$ ``
详见[此处](https://github.com/open-mmlab/mmdetection3d/blob/master/mmdet3d/core/bbox/structures/box_3d_mode.py)代码了解更多细节。
### 鸟瞰图
如果 3D 框是 ``$$`(x, y, z, dx, dy, dz, r)`$$``,相机坐标系下框的鸟瞰图是 ``$$`(x, z, dx, dz, -r)`$$``。转向角 (yaw) 符号取反是因为相机坐标系重力轴的正方向指向地面。
如果 3D 框是 `` $$`(x, y, z, dx, dy, dz, r)`$$ ``,相机坐标系下框的鸟瞰图是 `` $$`(x, z, dx, dz, -r)`$$ ``。转向角 (yaw) 符号取反是因为相机坐标系重力轴的正方向指向地面。
详见[此处](https://github.com/open-mmlab/mmdetection3d/blob/master/mmdet3d/core/bbox/structures/cam_box3d.py)代码了解更多细节。
......@@ -223,18 +223,18 @@ SUN RGB-D 的原始数据不是点云而是 RGB-D 图像。我们通过反投影
否。例如在 KITTI 中,从相机坐标系转换为激光雷达坐标系时,我们需要一个校准矩阵。
#### Q3: 框中转向角 (yaw) ``$$`2\pi`$$`` 的相位差如何影响评估?
#### Q3: 框中转向角 (yaw) `` $$`2\pi`$$ `` 的相位差如何影响评估?
对于交并比 (IoU) 计算,转向角 (yaw) 有 ``$$`2\pi`$$`` 的相位差的两个框是相同的,所以不会影响评估。
对于交并比 (IoU) 计算,转向角 (yaw) 有 `` $$`2\pi`$$ `` 的相位差的两个框是相同的,所以不会影响评估。
对于角度预测评估,例如 NuScenes 中的 NDS 指标和 KITTI 中的 AOS 指标,会先对预测框的角度进行标准化,因此 ``$$`2\pi`$$`` 的相位差不会改变结果。
对于角度预测评估,例如 NuScenes 中的 NDS 指标和 KITTI 中的 AOS 指标,会先对预测框的角度进行标准化,因此 `` $$`2\pi`$$ `` 的相位差不会改变结果。
#### Q4: 框中转向角 (yaw) ``$$`\pi`$$`` 的相位差如何影响评估?
#### Q4: 框中转向角 (yaw) `` $$`\pi`$$ `` 的相位差如何影响评估?
对于交并比 (IoU) 计算,转向角 (yaw) 有 ``$$`\pi`$$`` 的相位差的两个框是相同的,所以不会影响评估。
对于交并比 (IoU) 计算,转向角 (yaw) 有 `` $$`\pi`$$ `` 的相位差的两个框是相同的,所以不会影响评估。
然而,对于角度预测评估,这会导致完全相反的方向。
考虑一辆汽车,转向角 (yaw) 是汽车前部方向与 x 轴正方向之间的夹角。如果我们将该角度增加 ``$$`\pi`$$``,车前部将变成车后部。
考虑一辆汽车,转向角 (yaw) 是汽车前部方向与 x 轴正方向之间的夹角。如果我们将该角度增加 `` $$`\pi`$$ ``,车前部将变成车后部。
对于某些类别,例如障碍物,前后没有区别,因此 ``$$`\pi`$$`` 的相位差不会对角度预测分数产生影响。
对于某些类别,例如障碍物,前后没有区别,因此 `` $$`\pi`$$ `` 的相位差不会对角度预测分数产生影响。
......@@ -215,62 +215,62 @@ dataset_A_train = dict(
1. 如果待拼接的数据集的类别相同,标注文件的不同,此时可通过下面的方式来实现数据集的拼接:
```python
dataset_A_train = dict(
type='Dataset_A',
ann_file = ['anno_file_1', 'anno_file_2'],
pipeline=train_pipeline
)
```
如果拼接数据集用于测试或者评估,那么这种拼接方式能够对每个数据集进行分开地测试或者评估,若希望对拼接数据集进行整体的测试或者评估,此时需要设置 `separate_eval=False`,如下所示:
```python
dataset_A_train = dict(
type='Dataset_A',
ann_file = ['anno_file_1', 'anno_file_2'],
separate_eval=False,
pipeline=train_pipeline
)
```
```python
dataset_A_train = dict(
type='Dataset_A',
ann_file = ['anno_file_1', 'anno_file_2'],
pipeline=train_pipeline
)
```
如果拼接数据集用于测试或者评估,那么这种拼接方式能够对每个数据集进行分开地测试或者评估,若希望对拼接数据集进行整体的测试或者评估,此时需要设置 `separate_eval=False`,如下所示:
```python
dataset_A_train = dict(
type='Dataset_A',
ann_file = ['anno_file_1', 'anno_file_2'],
separate_eval=False,
pipeline=train_pipeline
)
```
2. 如果待拼接的数据集完全不相同,此时可通过拼接不同数据集的配置的方式实现数据集的拼接,如下所示:
```python
dataset_A_train = dict()
dataset_B_train = dict()
data = dict(
imgs_per_gpu=2,
workers_per_gpu=2,
train = [
dataset_A_train,
dataset_B_train
],
val = dataset_A_val,
test = dataset_A_test
)
```
```python
dataset_A_train = dict()
dataset_B_train = dict()
data = dict(
imgs_per_gpu=2,
workers_per_gpu=2,
train = [
dataset_A_train,
dataset_B_train
],
val = dataset_A_val,
test = dataset_A_test
)
```
如果拼接数据集用于测试或者评估,那么这种拼接方式能够对每个数据集进行分开地测试或者评估。
如果拼接数据集用于测试或者评估,那么这种拼接方式能够对每个数据集进行分开地测试或者评估。
3. 可以通过显示地定义 `ConcatDataset` 来实现数据集的拼接,如下所示:
```python
dataset_A_val = dict()
dataset_B_val = dict()
data = dict(
imgs_per_gpu=2,
workers_per_gpu=2,
train=dataset_A_train,
val=dict(
type='ConcatDataset',
datasets=[dataset_A_val, dataset_B_val],
separate_eval=False))
```
其中,`separate_eval=False` 表示将所有的数据集作为一个整体进行评估。
```python
dataset_A_val = dict()
dataset_B_val = dict()
data = dict(
imgs_per_gpu=2,
workers_per_gpu=2,
train=dataset_A_train,
val=dict(
type='ConcatDataset',
datasets=[dataset_A_val, dataset_B_val],
separate_eval=False))
```
其中,`separate_eval=False` 表示将所有的数据集作为一个整体进行评估。
**注意:**
......
......@@ -40,7 +40,7 @@ class MyOptimizer(Optimizer):
- 新建 `mmdet3d/core/optimizer/__init__.py` 文件用于引入。
新定义的模块应该在 `mmdet3d/core/optimizer/__init__.py` 中被引入,使得注册器可以找到新模块并注册之:
新定义的模块应该在 `mmdet3d/core/optimizer/__init__.py` 中被引入,使得注册器可以找到新模块并注册之:
```python
from .my_optimizer import MyOptimizer
......@@ -114,35 +114,35 @@ class MyOptimizerConstructor(object):
- __使用梯度裁剪 (gradient clip) 来稳定训练过程__:
一些模型依赖梯度裁剪技术来裁剪训练中的梯度,以稳定训练过程。举例如下:
一些模型依赖梯度裁剪技术来裁剪训练中的梯度,以稳定训练过程。举例如下:
```python
optimizer_config = dict(
_delete_=True, grad_clip=dict(max_norm=35, norm_type=2))
```
```python
optimizer_config = dict(
_delete_=True, grad_clip=dict(max_norm=35, norm_type=2))
```
如果您的配置继承了一个已经设置了 `optimizer_config` 的基础配置,那么您可能需要 `_delete_=True` 字段来覆盖基础配置中无用的设置。详见配置文件的[说明文档](https://mmdetection.readthedocs.io/zh_CN/latest/tutorials/config.html)。
如果您的配置继承了一个已经设置了 `optimizer_config` 的基础配置,那么您可能需要 `_delete_=True` 字段来覆盖基础配置中无用的设置。详见配置文件的[说明文档](https://mmdetection.readthedocs.io/zh_CN/latest/tutorials/config.html)
- __使用动量规划器 (momentum scheduler) 来加速模型收敛__:
我们支持用动量规划器来根据学习率更改模型的动量,这样可以使模型更快地收敛。
动量规划器通常和学习率规划器一起使用,比如说,如下配置文件在 3D 检测中被用于加速模型收敛。
更多细节详见 [CyclicLrUpdater](https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/hooks/lr_updater.py#L358) 和 [CyclicMomentumUpdater](https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/hooks/momentum_updater.py#L225) 的实现。
```python
lr_config = dict(
policy='cyclic',
target_ratio=(10, 1e-4),
cyclic_times=1,
step_ratio_up=0.4,
)
momentum_config = dict(
policy='cyclic',
target_ratio=(0.85 / 0.95, 1),
cyclic_times=1,
step_ratio_up=0.4,
)
```
我们支持用动量规划器来根据学习率更改模型的动量,这样可以使模型更快地收敛。
动量规划器通常和学习率规划器一起使用,比如说,如下配置文件在 3D 检测中被用于加速模型收敛。
更多细节详见 [CyclicLrUpdater](https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/hooks/lr_updater.py#L358)[CyclicMomentumUpdater](https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/hooks/momentum_updater.py#L225) 的实现。
```python
lr_config = dict(
policy='cyclic',
target_ratio=(10, 1e-4),
cyclic_times=1,
step_ratio_up=0.4,
)
momentum_config = dict(
policy='cyclic',
target_ratio=(0.85 / 0.95, 1),
cyclic_times=1,
step_ratio_up=0.4,
)
```
## 自定义训练规程
......@@ -151,20 +151,20 @@ class MyOptimizerConstructor(object):
- 多项式衰减规程:
```python
lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)
```
```python
lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)
```
- 余弦退火规程:
```python
lr_config = dict(
policy='CosineAnnealing',
warmup='linear',
warmup_iters=1000,
warmup_ratio=1.0 / 10,
min_lr_ratio=1e-5)
```
```python
lr_config = dict(
policy='CosineAnnealing',
warmup='linear',
warmup_iters=1000,
warmup_ratio=1.0 / 10,
min_lr_ratio=1e-5)
```
## 自定义工作流
......@@ -238,7 +238,7 @@ class MyHook(Hook):
- 更改 `mmdet3d/core/utils/__init__.py` 来引入之:
新定义的模块应在 `mmdet3d/core/utils/__init__.py` 中引入,以使得注册器可以找到新模块并注册之:
新定义的模块应在 `mmdet3d/core/utils/__init__.py` 中引入,以使得注册器可以找到新模块并注册之:
```python
from .my_hook import MyHook
......
This diff is collapsed.
......@@ -37,17 +37,17 @@ python ./tools/deploy.py \
### 参数描述
* `deploy_cfg` : MMDeploy 代码库中用于部署的配置文件路径。
* `model_cfg` : OpenMMLab 系列代码库中使用的模型配置文件路径。
* `checkpoint` : OpenMMLab 系列代码库的模型文件路径。
* `img` : 用于模型转换时使用的点云文件或图像文件路径。
* `--test-img` : 用于测试模型的图像文件路径。如果没有指定,将设置成 `None`
* `--work-dir` : 工作目录,用来保存日志和模型文件。
* `--calib-dataset-cfg` : 此参数只在 int8 模式下生效,用于校准数据集配置文件。如果没有指定,将被设置成 `None`,并使用模型配置文件中的 'val' 数据集进行校准。
* `--device` : 用于模型转换的设备。如果没有指定,将被设置成 cpu。
* `--log-level` : 设置日记的等级,选项包括 `'CRITICAL','FATAL','ERROR','WARN','WARNING','INFO','DEBUG','NOTSET'`。如果没有指定,将被设置成 INFO。
* `--show` : 是否显示检测的结果。
* `--dump-info` : 是否输出 SDK 信息。
- `deploy_cfg` : MMDeploy 代码库中用于部署的配置文件路径。
- `model_cfg` : OpenMMLab 系列代码库中使用的模型配置文件路径。
- `checkpoint` : OpenMMLab 系列代码库的模型文件路径。
- `img` : 用于模型转换时使用的点云文件或图像文件路径。
- `--test-img` : 用于测试模型的图像文件路径。如果没有指定,将设置成 `None`
- `--work-dir` : 工作目录,用来保存日志和模型文件。
- `--calib-dataset-cfg` : 此参数只在 int8 模式下生效,用于校准数据集配置文件。如果没有指定,将被设置成 `None`,并使用模型配置文件中的 'val' 数据集进行校准。
- `--device` : 用于模型转换的设备。如果没有指定,将被设置成 cpu。
- `--log-level` : 设置日记的等级,选项包括 `'CRITICAL','FATAL','ERROR','WARN','WARNING','INFO','DEBUG','NOTSET'`。如果没有指定,将被设置成 INFO。
- `--show` : 是否显示检测的结果。
- `--dump-info` : 是否输出 SDK 信息。
### 示例
......@@ -110,12 +110,12 @@ python tools/test.py \
## 支持模型列表
| Model | TorchScript | OnnxRuntime | TensorRT | NCNN | PPLNN | OpenVINO | Model config |
| -------------------- | :---------: | :---------: | :------: | :---: | :---: | :------: | -------------------------------------------------------------------------------------- |
| PointPillars | ? | Y | Y | N | N | Y | [config](https://github.com/open-mmlab/mmdetection3d/blob/master/configs/pointpillars) |
| CenterPoint (pillar) | ? | Y | Y | N | N | Y | [config](https://github.com/open-mmlab/mmdetection3d/blob/master/configs/centerpoint) |
| Model | TorchScript | OnnxRuntime | TensorRT | NCNN | PPLNN | OpenVINO | Model config |
| -------------------- | :---------: | :---------: | :------: | :--: | :---: | :------: | -------------------------------------------------------------------------------------- |
| PointPillars | ? | Y | Y | N | N | Y | [config](https://github.com/open-mmlab/mmdetection3d/blob/master/configs/pointpillars) |
| CenterPoint (pillar) | ? | Y | Y | N | N | Y | [config](https://github.com/open-mmlab/mmdetection3d/blob/master/configs/centerpoint) |
## 注意
* MMDeploy 的版本需要 >= 0.4.0。
* 目前 CenterPoint 仅支持了 pillar 版本的。
- MMDeploy 的版本需要 >= 0.4.0。
- 目前 CenterPoint 仅支持了 pillar 版本的。
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment