- You can use the following script to read the `.pcd` file and convert it to `.bin` format and save it:
- You can use the following script to read the `.pcd` file and convert it to `.bin` format for saving:
```python
```python
importnumpyasnp
importnumpyasnp
...
@@ -42,11 +42,11 @@ Currently, we only support `.bin` format point cloud for training and inference.
...
@@ -42,11 +42,11 @@ Currently, we only support `.bin` format point cloud for training and inference.
f.write(points.tobytes())
f.write(points.tobytes())
```
```
2. Convert `.las` to `.bin`: The common conversion path is `.las -> .pcd -> .bin`, and the conversion from`.las -> .pcd` can be achieved through [this tool](https://github.com/Hitachi-Automotive-And-Industry-Lab/semantic-segmentation-editor).
2. Convert `.las` to `.bin`: The common conversion path is `.las -> .pcd -> .bin`, and the conversion path`.las -> .pcd` can be achieved through [this tool](https://github.com/Hitachi-Automotive-And-Industry-Lab/semantic-segmentation-editor).
#### Label Format
#### Label Format
The most basic information: 3D bounding box and category label of each scene need to be contained in the annotation `.txt`file. Each line represents a 3D box in a certain scene as follow:
The most basic information: 3D bounding box and category label of each scene need to be contained in the `.txt`annotation file. Each line represents a 3D box in a certain scene as follow:
```
```
# format: [x, y, z, dx, dy, dz, yaw, category_name]
# format: [x, y, z, dx, dy, dz, yaw, category_name]
...
@@ -61,7 +61,7 @@ The 3D Box should be stored in unified 3D coordinates.
...
@@ -61,7 +61,7 @@ The 3D Box should be stored in unified 3D coordinates.
#### Calibration Format
#### Calibration Format
For the point cloud data collected by each lidar, they are usually fused and converted to a certain LiDAR coordinate. So typically the calibration information file should contain the intrinsic matrix of each camera and the transformation extrinsic matrix from the lidar to each camera in calibration `.txt`file, while `Px` represents the intrinsic matrix of `camera_x` and `lidar2camx` represents the transformation extrinsic matrix from the `lidar` to `camera_x`.
For the point cloud data collected by each LiDAR, they are usually fused and converted to a certain LiDAR coordinate. So typically the calibration information file should contain the intrinsic matrix of each camera and the transformation extrinsic matrix from the LiDAR to each camera in `.txt`calibration file, while `Px` represents the intrinsic matrix of `camera_x` and `lidar2camx` represents the transformation extrinsic matrix from the `lidar` to `camera_x`.
```
```
P0
P0
...
@@ -106,7 +106,7 @@ mmdetection3d
...
@@ -106,7 +106,7 @@ mmdetection3d
#### Vision-Based 3D Detection
#### Vision-Based 3D Detection
The raw data for vision-based 3D object detection are typically organized as follows, where `ImageSets` contains split files indicating which files belong to training/validation set, `images` contains the images from different cameras, for example, images from `camera_x` need to be placed in `images/images_x`.`calibs` contains calibration information files which store the camera intrinsic matrix of each camera, and `labels` includes label files for 3D detection.
The raw data for vision-based 3D object detection are typically organized as follows, where `ImageSets` contains split files indicating which files belong to training/validation set, `images` contains the images from different cameras, for example, images from `camera_x` need to be placed in `images/images_x`,`calibs` contains calibration information files which store the camera intrinsic matrix of each camera, and `labels` includes label files for 3D detection.
```
```
mmdetection3d
mmdetection3d
...
@@ -138,7 +138,7 @@ mmdetection3d
...
@@ -138,7 +138,7 @@ mmdetection3d
#### Multi-Modality 3D Detection
#### Multi-Modality 3D Detection
The raw data for multi-modality 3D object detection are typically organized as follows. Different from vision-based 3D Object detection, calibration information files in `calibs` store the camera intrinsic matrix of each camera and extrinsic matrix.
The raw data for multi-modality 3D object detection are typically organized as follows. Different from vision-based 3D object detection, calibration information files in `calibs` store the camera intrinsic matrix of each camera and extrinsic matrix.
```
```
mmdetection3d
mmdetection3d
...
@@ -174,7 +174,7 @@ mmdetection3d
...
@@ -174,7 +174,7 @@ mmdetection3d
#### LiDAR-Based 3D Semantic Segmentation
#### LiDAR-Based 3D Semantic Segmentation
The raw data for LiDAR-Based 3D semantic segmentation are typically organized as follows, where `ImageSets` contains split files indicating which files belong to training/validation set, `points` includes point cloud data, and `semantic_mask` includes point-level label.
The raw data for LiDAR-based 3D semantic segmentation are typically organized as follows, where `ImageSets` contains split files indicating which files belong to training/validation set, `points` includes point cloud data, and `semantic_mask` includes point-level label.
```
```
mmdetection3d
mmdetection3d
...
@@ -200,8 +200,8 @@ mmdetection3d
...
@@ -200,8 +200,8 @@ mmdetection3d
Once you prepared the raw data following our instruction, you can directly use the following command to generate training/validation information files.
Once you prepared the raw data following our instruction, you can directly use the following command to generate training/validation information files.
```
```bash
python tools/create_data.py base --root-path ./data/custom --out-dir ./data/custom
@@ -211,8 +211,8 @@ Once we finish data preparation, we can create a new dataset in `mmdet3d/dataset
...
@@ -211,8 +211,8 @@ Once we finish data preparation, we can create a new dataset in `mmdet3d/dataset
```python
```python
importmmengine
importmmengine
frommmdet3d.det3d_datasetimportDet3DDataset
frommmdet3d.registryimportDATASETS
frommmdet3d.registryimportDATASETS
from.det3d_datasetimportDet3DDataset
@DATASETS.register_module()
@DATASETS.register_module()
...
@@ -220,17 +220,21 @@ class MyDataset(Det3DDataset):
...
@@ -220,17 +220,21 @@ class MyDataset(Det3DDataset):
# replace with all the classes in customized pkl info file
# replace with all the classes in customized pkl info file
METAINFO={
METAINFO={
'classes':('Pedestrian','Cyclist','Car')
'classes':('Pedestrian','Cyclist','Car')
}
}
defparse_ann_info(self,info):
defparse_ann_info(self,info):
"""Process the `instances` in data info to `ann_info`
"""Process the `instances` in data info to `ann_info`.
Args:
Args:
info (dict): Info dict.
info (dict): Data information of single data sample.
Returns:
Returns:
dict | None: Processed `ann_info`
dict: Annotation information consists of the following keys:
- gt_bboxes_3d (:obj:`LiDARInstance3DBoxes`):
3D ground truth bboxes.
- gt_labels_3d (np.ndarray): Labels of ground truths.
"""
"""
ann_info=super().parse_ann_info(info)
ann_info=super().parse_ann_info(info)
ifann_infoisNone:
ifann_infoisNone:
...
@@ -255,7 +259,7 @@ Here we take training PointPillars on customized dataset as an example:
...
@@ -255,7 +259,7 @@ Here we take training PointPillars on customized dataset as an example:
### Prepare a config
### Prepare a config
Here we demonstrate a config sample for pure point cloud training:
Here we demonstrate a config sample for pure point cloud training.
#### Prepare dataset config
#### Prepare dataset config
...
@@ -322,7 +326,7 @@ train_dataloader = dict(
...
@@ -322,7 +326,7 @@ train_dataloader = dict(
dataset=dict(
dataset=dict(
type=dataset_type,
type=dataset_type,
data_root=data_root,
data_root=data_root,
ann_file='custom_infos_train.pkl',# specify your training pkl info
ann_file='custom_infos_train.pkl',# specify your training pkl info
data_prefix=dict(pts='points'),
data_prefix=dict(pts='points'),
pipeline=train_pipeline,
pipeline=train_pipeline,
modality=input_modality,
modality=input_modality,
...
@@ -339,7 +343,7 @@ val_dataloader = dict(
...
@@ -339,7 +343,7 @@ val_dataloader = dict(
type=dataset_type,
type=dataset_type,
data_root=data_root,
data_root=data_root,
data_prefix=dict(pts='points'),
data_prefix=dict(pts='points'),
ann_file='custom_infos_val.pkl',# specify your validation pkl info
ann_file='custom_infos_val.pkl',# specify your validation pkl info
pipeline=test_pipeline,
pipeline=test_pipeline,
modality=input_modality,
modality=input_modality,
test_mode=True,
test_mode=True,
...
@@ -347,7 +351,7 @@ val_dataloader = dict(
...
@@ -347,7 +351,7 @@ val_dataloader = dict(
box_type_3d='LiDAR'))
box_type_3d='LiDAR'))
val_evaluator=dict(
val_evaluator=dict(
type='KittiMetric',
type='KittiMetric',
ann_file=data_root+'custom_infos_val.pkl',# specify your validation pkl info
ann_file=data_root+'custom_infos_val.pkl',# specify your validation pkl info
metric='bbox')
metric='bbox')
```
```
...
@@ -356,7 +360,7 @@ val_evaluator = dict(
...
@@ -356,7 +360,7 @@ val_evaluator = dict(
For voxel-based detectors such as SECOND, PointPillars and CenterPoint, the point cloud range and voxel size should be adjusted according to your dataset.
For voxel-based detectors such as SECOND, PointPillars and CenterPoint, the point cloud range and voxel size should be adjusted according to your dataset.
Theoretically, `voxel_size` is linked to the setting of `point_cloud_range`. Setting a smaller `voxel_size` will increase the voxel num and the corresponding memory consumption. In addition, the following issues need to be noted:
Theoretically, `voxel_size` is linked to the setting of `point_cloud_range`. Setting a smaller `voxel_size` will increase the voxel num and the corresponding memory consumption. In addition, the following issues need to be noted:
If the `point_cloud_range` and `voxel_size` are set to be `[0, -40, -3, 70.4, 40, 1]` and `[0.05, 0.05, 0.1]` respectively, then the shape of intermediate feature map should be `[(1-(-3))/0.1+1, (40-(-40))/0.05, (70.4-0)/0.05]=[41, 1600, 1408]`. When changing `point_cloud_range`, remember to change the shape of intermediate feature map in `middel_encoder` according to the `voxel_size`.
If the `point_cloud_range` and `voxel_size` are set to be `[0, -40, -3, 70.4, 40, 1]` and `[0.05, 0.05, 0.1]` respectively, then the shape of intermediate feature map should be `[(1-(-3))/0.1+1, (40-(-40))/0.05, (70.4-0)/0.05]=[41, 1600, 1408]`. When changing `point_cloud_range`, remember to change the shape of intermediate feature map in `middle_encoder` according to the `voxel_size`.
Regarding the setting of `anchor_range`, it is generally adjusted according to dataset. Note that `z` value needs to be adjusted accordingly to the position of the point cloud, please refer to this [issue](https://github.com/open-mmlab/mmdetection3d/issues/986).
Regarding the setting of `anchor_range`, it is generally adjusted according to dataset. Note that `z` value needs to be adjusted accordingly to the position of the point cloud, please refer to this [issue](https://github.com/open-mmlab/mmdetection3d/issues/986).
To valiate whether your prepared data and config are correct, it's highly recommended to use `tools/misc/browse_dataest.py` script
To validate whether your prepared data and config are correct, it's highly recommended to use `tools/misc/browse_dataset.py` script
to visualize your dataset and annotations before training and validation, more details refer to the [visualization](https://github.com/open-mmlab/mmdetection3d/blob/dev-1.x/docs/en/user_guides/visualization.md) doc.
to visualize your dataset and annotations before training and validation. Please refer to [visualization doc](https://mmdetection3d.readthedocs.io/en/dev-1.x/user_guides/visualization.html) for more details.
## Evaluation
## Evaluation
Once the data and config have been prepared, you can directly run the training/testing script following our doc.
Once the data and config have been prepared, you can directly run the training/testing script following our doc.
**Note**: we only provide an implementation for KITTI style evaluation for the customized dataset. It should be included in the dataset config:
**Note**: We only provide an implementation for KITTI style evaluation for the customized dataset. It should be included in the dataset config:
```python
```python
val_evaluator=dict(
val_evaluator=dict(
type='KittiMetric',
type='KittiMetric',
ann_file=data_root+'custom_infos_val.pkl',# specify your validation pkl info
ann_file=data_root+'custom_infos_val.pkl',# specify your validation pkl info