Commit cb1ecefa authored by jihanyang's avatar jihanyang
Browse files

Modify the custom dataset support

parent daa27fd8
# Custom Dataset Tutorial
For the custom dataset template, we only consider the basic scenario: raw point clouds and
their corresponding annotations. Point clouds are supposed to be stored in `.npy` format.
## Label format
We only consider the most basic information -- category and bounding box in the label template.
Annotations are stored in the `.txt`. Each line represents a box in a given scene as below:
```
[x y z dx dy dz heading_angle category_id]
1.50 1.46 0.10 5.12 1.85 4.13 1.56 0
5.54 0.57 0.41 1.08 0.74 1.95 1.57 1
```
The box should in the unified 3D box definition (see [README](../README.md))
The correspondence between `category_id` and `category_name` need to be pre-defined.
## Files structure
Files should be placed as the following folder structure:
```
OpenPCDet
├── data
│ ├── custom
│ │ │── ImageSets
│ │ │ │── train.txt
│ │ │ │── val.txt
│ │ │── points
│ │ │ │── 000000.npy
│ │ │ │── 999999.npy
│ │ │── labels
│ │ │ │── 000000.txt
│ │ │ │── 999999.txt
├── pcdet
├── tools
```
Dataset splits need to be pre-defined and placed in `ImageSets`
## Hyper-parameters Configurations
### Point cloud features
Modify following configurations to in `custom_dataset.yaml` to
suit your own point clouds.
```yaml
POINT_FEATURE_ENCODING: {
encoding_type: absolute_coordinates_encoding,
used_feature_list: ['x', 'y', 'z', 'intensity'],
src_feature_list: ['x', 'y', 'z', 'intensity'],
}
...
# In gt_sampling data augmentation
NUM_POINT_FEATURES: 4
```
#### Point cloud range and voxel sizes
For voxel based detectors such as SECOND, PV-RCNN and CenterPoint, the point cloud range and voxel size should follow:
1. Point cloud range along z-axis / voxel_size is 40
2. Point cloud range along x&y-axis / voxel_size is the multiple of 16.
Notice that the second rule also suit pillar based detectors such as PointPillar and CenterPoint-Pillar.
### Category names and anchor sizes
Category names and anchor size are need to be adapted to custom datasets.
```yaml
CLASS_NAMES: ['Vehicle', 'Pedestrian', 'Cyclist']
...
MAP_CLASS_TO_KITTI: {
'Vehicle': 'Car',
'Pedestrian': 'Pedestrian',
'Cyclist': 'Cyclist',
}
...
'anchor_sizes': [[3.9, 1.6, 1.56]],
...
# In gt sampling data augmentation
PREPARE: {
filter_by_min_points: ['Vehicle:5', 'Pedestrian:5', 'Cyclist:5'],
filter_by_difficulty: [-1],
}
SAMPLE_GROUPS: ['Vehicle:20','Pedestrian:15', 'Cyclist:15']
...
```
In addition, please also modify the default category names for creating infos in `custom_dataset.py`
```
create_custom_infos(
dataset_cfg=dataset_cfg,
class_names=['Vehicle', 'Pedestrian', 'Cyclist'],
data_path=ROOT_DIR / 'data' / 'custom',
save_path=ROOT_DIR / 'data' / 'custom',
)
```
## Create data info
Generate the data infos by running the following command:
```shell
python -m pcdet.datasets.custom.custom_dataset create_custom_infos tools/cfgs/dataset_configs/custom_dataset.yaml
```
## Evaluation
Here, we only provide an implementation for KITTI stype evaluation.
The category mapping between custom dataset and KITTI need to be defined
in the `custom_dataset.yaml`
```yaml
MAP_CLASS_TO_KITTI: {
'Vehicle': 'Car',
'Pedestrian': 'Pedestrian',
'Cyclist': 'Cyclist',
}
```
...@@ -5,7 +5,7 @@ and the model configs are located within [tools/cfgs](../tools/cfgs) for differe ...@@ -5,7 +5,7 @@ and the model configs are located within [tools/cfgs](../tools/cfgs) for differe
## Dataset Preparation ## Dataset Preparation
Currently we provide the dataloader of KITTI dataset and NuScenes dataset, and the supporting of more datasets are on the way. Currently we provide the dataloader of KITTI, NuScenes, Waymo, Lyft and Pandaset. If you want to use a custom dataset, Please refer to our [custom dataset template](CUSTOM_DATASET_TUTORIAL.md).
### KITTI Dataset ### KITTI Dataset
* Please download the official [KITTI 3D object detection](http://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d) dataset and organize the downloaded files as follows (the road planes could be downloaded from [[road plane]](https://drive.google.com/file/d/1d5mq0RXRnvHPVeKx6Q612z0YRO1t2wAp/view?usp=sharing), which are optional for data augmentation in the training): * Please download the official [KITTI 3D object detection](http://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d) dataset and organize the downloaded files as follows (the road planes could be downloaded from [[road plane]](https://drive.google.com/file/d/1d5mq0RXRnvHPVeKx6Q612z0YRO1t2wAp/view?usp=sharing), which are optional for data augmentation in the training):
......
For Custom Dataset using
## Custom Dataset
For pure point cloud dataset, which means you don't have images generated when got point cloud data from a self-defined scene. Label those raw data and make sure label files to be kitti-like:
```
Car 0 0 0 0 0 0 0 1.50 1.46 3.70 -5.12 1.85 4.13 1.56
Pedestrian 0 0 0 0 0 0 0 1.54 0.57 0.41 -7.92 1.94 15.95 1.57
DontCare 0 0 0 0 0 0 0 -1 -1 -1 -1000 -1000 -1000 -10
```
Some items (which is shown from the first zero to the seventh zero above) are not necessary because they are meaningless if no cameras. And the `image` folder, `calib` folder are both needless, which will be much more convenient for not using just official dataset. The point cloud dataset should be `.bin` format.
Place the custom dataset:
```
OpenPCDet
├── data
│ ├── custom
│ │ │── ImageSets
│ │ │── training
│ │ │ ├──velodyne & label_2
│ │ │── testing
│ │ │ ├──velodyne
├── pcdet
├── tools
```
## Calibration
Calibration rules for cameras are not need. But you need to define how to transform from KITTI coordinates to lidar coordinates. The lidar coordinates are the custom coordinates. The raw data are in lidar coordinates and the labels are in KITTI coordinates. This self-defined transform is written in `custom_dataset->get_calib (188)` which is used to get gt_boxes from labels.
## Other configurations
Possible other parameters or names that need to be check to adapt the custom scene.
- config files
```
CLASS_NAMES: ['Car', 'Pedestrian', 'Cyclist'] # pv_rcnn.yaml
...
'anchor_sizes': [[3.9, 1.6, 1.56]], # pv_rcnn.yaml
...
POINT_CLOUD_RANGE: [-70.4, -40, -3, 70.4, 40, 1] # custom_dataset.yaml
...
```
The train, test and pred are all the same as others.
\ No newline at end of file
This diff is collapsed.
...@@ -9,6 +9,7 @@ from .augmentor.data_augmentor import DataAugmentor ...@@ -9,6 +9,7 @@ from .augmentor.data_augmentor import DataAugmentor
from .processor.data_processor import DataProcessor from .processor.data_processor import DataProcessor
from .processor.point_feature_encoder import PointFeatureEncoder from .processor.point_feature_encoder import PointFeatureEncoder
class DatasetTemplate(torch_data.Dataset): class DatasetTemplate(torch_data.Dataset):
def __init__(self, dataset_cfg=None, class_names=None, training=True, root_path=None, logger=None): def __init__(self, dataset_cfg=None, class_names=None, training=True, root_path=None, logger=None):
super().__init__() super().__init__()
...@@ -59,21 +60,52 @@ class DatasetTemplate(torch_data.Dataset): ...@@ -59,21 +60,52 @@ class DatasetTemplate(torch_data.Dataset):
@staticmethod @staticmethod
def generate_prediction_dicts(batch_dict, pred_dicts, class_names, output_path=None): def generate_prediction_dicts(batch_dict, pred_dicts, class_names, output_path=None):
""" """
To support a custom dataset, implement this function to receive the predicted results from the model, and then
transform the unified normative coordinate to your required coordinate, and optionally save them to disk.
Args: Args:
batch_dict: dict of original data from the dataloader batch_dict:
pred_dicts: dict of predicted results from the model frame_id:
pred_dicts: list of pred_dicts
pred_boxes: (N, 7), Tensor pred_boxes: (N, 7), Tensor
pred_scores: (N), Tensor pred_scores: (N), Tensor
pred_labels: (N), Tensor pred_labels: (N), Tensor
class_names: class_names:
output_path: if it is not None, save the results to this path output_path:
Returns: Returns:
""" """
def get_template_prediction(num_samples):
ret_dict = {
'name': np.zeros(num_samples), 'score': np.zeros(num_samples),
'boxes_lidar': np.zeros([num_samples, 7]), 'pred_labels': np.zeros(num_samples)
}
return ret_dict
def generate_single_sample_dict(box_dict):
pred_scores = box_dict['pred_scores'].cpu().numpy()
pred_boxes = box_dict['pred_boxes'].cpu().numpy()
pred_labels = box_dict['pred_labels'].cpu().numpy()
pred_dict = get_template_prediction(pred_scores.shape[0])
if pred_scores.shape[0] == 0:
return pred_dict
pred_dict['name'] = np.array(class_names)[pred_labels - 1]
pred_dict['score'] = pred_scores
pred_dict['boxes_lidar'] = pred_boxes
pred_dict['pred_labels'] = pred_labels
return pred_dict
annos = []
for index, box_dict in enumerate(pred_dicts):
single_pred_dict = generate_single_sample_dict(box_dict)
single_pred_dict['frame_id'] = batch_dict['frame_id'][index]
if 'metadata' in batch_dict:
single_pred_dict['metadata'] = batch_dict['metadata'][index]
annos.append(single_pred_dict)
return annos
def merge_all_iters_to_one_epoch(self, merge=True, epochs=None): def merge_all_iters_to_one_epoch(self, merge=True, epochs=None):
if merge: if merge:
self._merge_all_iters_to_one_epoch = True self._merge_all_iters_to_one_epoch = True
......
...@@ -106,50 +106,6 @@ class LyftDataset(DatasetTemplate): ...@@ -106,50 +106,6 @@ class LyftDataset(DatasetTemplate):
return data_dict return data_dict
def generate_prediction_dicts(self, batch_dict, pred_dicts, class_names, output_path=None):
"""
Args:
batch_dict:
frame_id:
pred_dicts: list of pred_dicts
pred_boxes: (N, 7), Tensor
pred_scores: (N), Tensor
pred_labels: (N), Tensor
class_names:
output_path:
Returns:
"""
def get_template_prediction(num_samples):
ret_dict = {
'name': np.zeros(num_samples), 'score': np.zeros(num_samples),
'boxes_lidar': np.zeros([num_samples, 7]), 'pred_labels': np.zeros(num_samples)
}
return ret_dict
def generate_single_sample_dict(box_dict):
pred_scores = box_dict['pred_scores'].cpu().numpy()
pred_boxes = box_dict['pred_boxes'].cpu().numpy()
pred_labels = box_dict['pred_labels'].cpu().numpy()
pred_dict = get_template_prediction(pred_scores.shape[0])
if pred_scores.shape[0] == 0:
return pred_dict
pred_dict['name'] = np.array(class_names)[pred_labels - 1]
pred_dict['score'] = pred_scores
pred_dict['boxes_lidar'] = pred_boxes
pred_dict['pred_labels'] = pred_labels
return pred_dict
annos = []
for index, box_dict in enumerate(pred_dicts):
single_pred_dict = generate_single_sample_dict(box_dict)
single_pred_dict['frame_id'] = batch_dict['frame_id'][index]
single_pred_dict['metadata'] = batch_dict['metadata'][index]
annos.append(single_pred_dict)
return annos
def kitti_eval(self, eval_det_annos, eval_gt_annos, class_names): def kitti_eval(self, eval_det_annos, eval_gt_annos, class_names):
from ..kitti.kitti_object_eval_python import eval as kitti_eval from ..kitti.kitti_object_eval_python import eval as kitti_eval
from ..kitti import kitti_utils from ..kitti import kitti_utils
......
...@@ -150,51 +150,6 @@ class NuScenesDataset(DatasetTemplate): ...@@ -150,51 +150,6 @@ class NuScenesDataset(DatasetTemplate):
return data_dict return data_dict
@staticmethod
def generate_prediction_dicts(batch_dict, pred_dicts, class_names, output_path=None):
"""
Args:
batch_dict:
frame_id:
pred_dicts: list of pred_dicts
pred_boxes: (N, 7), Tensor
pred_scores: (N), Tensor
pred_labels: (N), Tensor
class_names:
output_path:
Returns:
"""
def get_template_prediction(num_samples):
ret_dict = {
'name': np.zeros(num_samples), 'score': np.zeros(num_samples),
'boxes_lidar': np.zeros([num_samples, 7]), 'pred_labels': np.zeros(num_samples)
}
return ret_dict
def generate_single_sample_dict(box_dict):
pred_scores = box_dict['pred_scores'].cpu().numpy()
pred_boxes = box_dict['pred_boxes'].cpu().numpy()
pred_labels = box_dict['pred_labels'].cpu().numpy()
pred_dict = get_template_prediction(pred_scores.shape[0])
if pred_scores.shape[0] == 0:
return pred_dict
pred_dict['name'] = np.array(class_names)[pred_labels - 1]
pred_dict['score'] = pred_scores
pred_dict['boxes_lidar'] = pred_boxes
pred_dict['pred_labels'] = pred_labels
return pred_dict
annos = []
for index, box_dict in enumerate(pred_dicts):
single_pred_dict = generate_single_sample_dict(box_dict)
single_pred_dict['frame_id'] = batch_dict['frame_id'][index]
single_pred_dict['metadata'] = batch_dict['metadata'][index]
annos.append(single_pred_dict)
return annos
def evaluation(self, det_annos, class_names, **kwargs): def evaluation(self, det_annos, class_names, **kwargs):
import json import json
from nuscenes.nuscenes import NuScenes from nuscenes.nuscenes import NuScenes
......
...@@ -218,53 +218,6 @@ class WaymoDataset(DatasetTemplate): ...@@ -218,53 +218,6 @@ class WaymoDataset(DatasetTemplate):
data_dict.pop('num_points_in_gt', None) data_dict.pop('num_points_in_gt', None)
return data_dict return data_dict
@staticmethod
def generate_prediction_dicts(batch_dict, pred_dicts, class_names, output_path=None):
"""
Args:
batch_dict:
frame_id:
pred_dicts: list of pred_dicts
pred_boxes: (N, 7), Tensor
pred_scores: (N), Tensor
pred_labels: (N), Tensor
class_names:
output_path:
Returns:
"""
def get_template_prediction(num_samples):
ret_dict = {
'name': np.zeros(num_samples), 'score': np.zeros(num_samples),
'boxes_lidar': np.zeros([num_samples, 7])
}
return ret_dict
def generate_single_sample_dict(box_dict):
pred_scores = box_dict['pred_scores'].cpu().numpy()
pred_boxes = box_dict['pred_boxes'].cpu().numpy()
pred_labels = box_dict['pred_labels'].cpu().numpy()
pred_dict = get_template_prediction(pred_scores.shape[0])
if pred_scores.shape[0] == 0:
return pred_dict
pred_dict['name'] = np.array(class_names)[pred_labels - 1]
pred_dict['score'] = pred_scores
pred_dict['boxes_lidar'] = pred_boxes
return pred_dict
annos = []
for index, box_dict in enumerate(pred_dicts):
single_pred_dict = generate_single_sample_dict(box_dict)
single_pred_dict['frame_id'] = batch_dict['frame_id'][index]
single_pred_dict['metadata'] = batch_dict['metadata'][index]
annos.append(single_pred_dict)
return annos
def evaluation(self, det_annos, class_names, **kwargs): def evaluation(self, det_annos, class_names, **kwargs):
if 'annos' not in self.infos[0].keys(): if 'annos' not in self.infos[0].keys():
return 'No ground-truth boxes for evaluation', {} return 'No ground-truth boxes for evaluation', {}
......
CLASS_NAMES: ['Car']
# CLASS_NAMES: ['Car', 'Pedestrian', 'Cyclist']
DATA_CONFIG:
_BASE_CONFIG_: ../dataset_configs/custom_dataset.yaml
DATA_PROCESSOR:
- NAME: mask_points_and_boxes_outside_range
REMOVE_OUTSIDE_BOXES: True
- NAME: sample_points
NUM_POINTS: {
'train': 16384,
'test': 16384
}
- NAME: shuffle_points
SHUFFLE_ENABLED: {
'train': True,
'test': False
}
MODEL:
NAME: PointRCNN
BACKBONE_3D:
NAME: PointNet2MSG
SA_CONFIG:
NPOINTS: [4096, 1024, 256, 64]
RADIUS: [[0.1, 0.5], [0.5, 1.0], [1.0, 2.0], [2.0, 4.0]]
NSAMPLE: [[16, 32], [16, 32], [16, 32], [16, 32]]
MLPS: [[[16, 16, 32], [32, 32, 64]],
[[64, 64, 128], [64, 96, 128]],
[[128, 196, 256], [128, 196, 256]],
[[256, 256, 512], [256, 384, 512]]]
FP_MLPS: [[128, 128], [256, 256], [512, 512], [512, 512]]
POINT_HEAD:
NAME: PointHeadBox
CLS_FC: [256, 256]
REG_FC: [256, 256]
CLASS_AGNOSTIC: False
USE_POINT_FEATURES_BEFORE_FUSION: False
TARGET_CONFIG:
GT_EXTRA_WIDTH: [0.2, 0.2, 0.2]
BOX_CODER: PointResidualCoder
BOX_CODER_CONFIG: {
'use_mean_size': True,
'mean_size': [
[3.9, 1.6, 1.56],
[0.8, 0.6, 1.73],
[1.76, 0.6, 1.73]
]
}
LOSS_CONFIG:
LOSS_REG: WeightedSmoothL1Loss
LOSS_WEIGHTS: {
'point_cls_weight': 1.0,
'point_box_weight': 1.0,
'code_weights': [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
}
ROI_HEAD:
NAME: PointRCNNHead
CLASS_AGNOSTIC: True
ROI_POINT_POOL:
POOL_EXTRA_WIDTH: [0.0, 0.0, 0.0]
NUM_SAMPLED_POINTS: 512
DEPTH_NORMALIZER: 70.0
XYZ_UP_LAYER: [128, 128]
CLS_FC: [256, 256]
REG_FC: [256, 256]
DP_RATIO: 0.0
USE_BN: False
SA_CONFIG:
NPOINTS: [128, 32, -1]
RADIUS: [0.2, 0.4, 100]
NSAMPLE: [16, 16, 16]
MLPS: [[128, 128, 128],
[128, 128, 256],
[256, 256, 512]]
NMS_CONFIG:
TRAIN:
NMS_TYPE: nms_gpu
MULTI_CLASSES_NMS: False
NMS_PRE_MAXSIZE: 9000
NMS_POST_MAXSIZE: 512
NMS_THRESH: 0.8
TEST:
NMS_TYPE: nms_gpu
MULTI_CLASSES_NMS: False
NMS_PRE_MAXSIZE: 9000
NMS_POST_MAXSIZE: 100
NMS_THRESH: 0.85
TARGET_CONFIG:
BOX_CODER: ResidualCoder
ROI_PER_IMAGE: 128
FG_RATIO: 0.5
SAMPLE_ROI_BY_EACH_CLASS: True
CLS_SCORE_TYPE: cls
CLS_FG_THRESH: 0.6
CLS_BG_THRESH: 0.45
CLS_BG_THRESH_LO: 0.1
HARD_BG_RATIO: 0.8
REG_FG_THRESH: 0.55
LOSS_CONFIG:
CLS_LOSS: BinaryCrossEntropy
REG_LOSS: smooth-l1
CORNER_LOSS_REGULARIZATION: True
LOSS_WEIGHTS: {
'rcnn_cls_weight': 1.0,
'rcnn_reg_weight': 1.0,
'rcnn_corner_weight': 1.0,
'code_weights': [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
}
POST_PROCESSING:
RECALL_THRESH_LIST: [0.3, 0.5, 0.7]
SCORE_THRESH: 0.1
OUTPUT_RAW_SCORE: False
EVAL_METRIC: kitti
NMS_CONFIG:
MULTI_CLASSES_NMS: False
NMS_TYPE: nms_gpu
NMS_THRESH: 0.1
NMS_PRE_MAXSIZE: 4096
NMS_POST_MAXSIZE: 500
OPTIMIZATION:
BATCH_SIZE_PER_GPU: 2
NUM_EPOCHS: 80
OPTIMIZER: adam_onecycle
LR: 0.01
WEIGHT_DECAY: 0.01
MOMENTUM: 0.9
MOMS: [0.95, 0.85]
PCT_START: 0.4
DIV_FACTOR: 10
DECAY_STEP_LIST: [35, 45]
LR_DECAY: 0.1
LR_CLIP: 0.0000001
LR_WARMUP: False
WARMUP_EPOCH: 1
GRAD_NORM_CLIP: 10
CLASS_NAMES: ['Car', 'Pedestrian', 'Cyclist'] CLASS_NAMES: ['Vehicle', 'Pedestrian', 'Cyclist']
DATA_CONFIG: DATA_CONFIG:
_BASE_CONFIG_: ../dataset_configs/custom_dataset.yaml _BASE_CONFIG_: ../dataset_configs/custom_dataset.yaml
DATA_AUGMENTOR:
DISABLE_AUG_LIST: ['placeholder']
AUG_CONFIG_LIST:
- NAME: gt_sampling
USE_ROAD_PLANE: False
DB_INFO_PATH:
- custom_dbinfos_train.pkl
PREPARE: {
filter_by_min_points: ['Car:5', 'Pedestrian:5', 'Cyclist:5'],
filter_by_difficulty: [-1],
}
SAMPLE_GROUPS: ['Car:15','Pedestrian:10', 'Cyclist:10']
NUM_POINT_FEATURES: 4
DATABASE_WITH_FAKELIDAR: False
REMOVE_EXTRA_WIDTH: [0.0, 0.0, 0.0]
LIMIT_WHOLE_SCENE: False
- NAME: random_world_flip
ALONG_AXIS_LIST: ['x']
- NAME: random_world_rotation
WORLD_ROT_ANGLE: [-0.78539816, 0.78539816]
- NAME: random_world_scaling
WORLD_SCALE_RANGE: [0.95, 1.05]
MODEL: MODEL:
NAME: PVRCNN NAME: PVRCNN
...@@ -62,20 +36,20 @@ MODEL: ...@@ -62,20 +36,20 @@ MODEL:
ANCHOR_GENERATOR_CONFIG: [ ANCHOR_GENERATOR_CONFIG: [
{ {
'class_name': 'Car', 'class_name': 'Vehicle',
'anchor_sizes': [[3.9, 1.6, 1.56]], 'anchor_sizes': [[3.9, 1.6, 1.56]],
'anchor_rotations': [0, 1.57], 'anchor_rotations': [0, 1.57],
'anchor_bottom_heights': [-0.1], 'anchor_bottom_heights': [0],
'align_center': False, 'align_center': False,
'feature_map_stride': 8, 'feature_map_stride': 8,
'matched_threshold': 0.6, 'matched_threshold': 0.55,
'unmatched_threshold': 0.45 'unmatched_threshold': 0.4
}, },
{ {
'class_name': 'Pedestrian', 'class_name': 'Pedestrian',
'anchor_sizes': [[0.05, 0.03, 0.1]], 'anchor_sizes': [[0.8, 0.6, 1.73]],
'anchor_rotations': [0, 1.57], 'anchor_rotations': [0, 1.57],
'anchor_bottom_heights': [-0.03], 'anchor_bottom_heights': [0],
'align_center': False, 'align_center': False,
'feature_map_stride': 8, 'feature_map_stride': 8,
'matched_threshold': 0.5, 'matched_threshold': 0.5,
...@@ -83,9 +57,9 @@ MODEL: ...@@ -83,9 +57,9 @@ MODEL:
}, },
{ {
'class_name': 'Cyclist', 'class_name': 'Cyclist',
'anchor_sizes': [[0.1, 0.03, 0.1]], 'anchor_sizes': [[1.76, 0.6, 1.73]],
'anchor_rotations': [0, 1.57], 'anchor_rotations': [0, 1.57],
'anchor_bottom_heights': [-0.03], 'anchor_bottom_heights': [0],
'align_center': False, 'align_center': False,
'feature_map_stride': 8, 'feature_map_stride': 8,
'matched_threshold': 0.5, 'matched_threshold': 0.5,
...@@ -112,11 +86,11 @@ MODEL: ...@@ -112,11 +86,11 @@ MODEL:
PFE: PFE:
NAME: VoxelSetAbstraction NAME: VoxelSetAbstraction
POINT_SOURCE: raw_points POINT_SOURCE: raw_points
NUM_KEYPOINTS: 2048 NUM_KEYPOINTS: 4096
NUM_OUTPUT_FEATURES: 128 NUM_OUTPUT_FEATURES: 128
SAMPLE_METHOD: FPS SAMPLE_METHOD: FPS
FEATURES_SOURCE: ['bev', 'x_conv1', 'x_conv2', 'x_conv3', 'x_conv4', 'raw_points'] FEATURES_SOURCE: ['bev', 'x_conv3', 'x_conv4', 'raw_points']
SA_LAYER: SA_LAYER:
raw_points: raw_points:
MLPS: [[16, 16], [16, 16]] MLPS: [[16, 16], [16, 16]]
...@@ -175,9 +149,13 @@ MODEL: ...@@ -175,9 +149,13 @@ MODEL:
TEST: TEST:
NMS_TYPE: nms_gpu NMS_TYPE: nms_gpu
MULTI_CLASSES_NMS: False MULTI_CLASSES_NMS: False
NMS_PRE_MAXSIZE: 1024 # NMS_PRE_MAXSIZE: 1024
NMS_POST_MAXSIZE: 100 # NMS_POST_MAXSIZE: 100
NMS_THRESH: 0.7 # NMS_THRESH: 0.7
NMS_PRE_MAXSIZE: 4096
NMS_POST_MAXSIZE: 300
NMS_THRESH: 0.85
ROI_GRID_POOL: ROI_GRID_POOL:
GRID_SIZE: 6 GRID_SIZE: 6
......
DATASET: 'CustomDataset' DATASET: 'CustomDataset'
DATA_PATH: '../data/custom' DATA_PATH: '../data/custom'
# If this config file is modified then pcdet/models/detectors/detector3d_template.py: POINT_CLOUD_RANGE: [-75.2, -75.2, -2, 75.2, 75.2, 4]
# Detector3DTemplate::build_networks:model_info_dict needs to be modified.
POINT_CLOUD_RANGE: [-70.4, -40, -3, 70.4, 40, 1] # x=[-70.4, 70.4], y=[-40,40], z=[-3,1] MAP_CLASS_TO_KITTI: {
'Vehicle': 'Car',
'Pedestrian': 'Pedestrian',
'Cyclist': 'Cyclist',
}
DATA_SPLIT: { DATA_SPLIT: {
'train': train, 'train': train,
...@@ -15,16 +19,12 @@ INFO_PATH: { ...@@ -15,16 +19,12 @@ INFO_PATH: {
'test': [custom_infos_val.pkl], 'test': [custom_infos_val.pkl],
} }
GET_ITEM_LIST: ["points"]
FOV_POINTS_ONLY: True
POINT_FEATURE_ENCODING: { POINT_FEATURE_ENCODING: {
encoding_type: absolute_coordinates_encoding, encoding_type: absolute_coordinates_encoding,
used_feature_list: ['x', 'y', 'z', 'intensity'], used_feature_list: ['x', 'y', 'z', 'intensity'],
src_feature_list: ['x', 'y', 'z', 'intensity'], src_feature_list: ['x', 'y', 'z', 'intensity'],
} }
# Same to pv_rcnn[DATA_AUGMENTOR]
DATA_AUGMENTOR: DATA_AUGMENTOR:
DISABLE_AUG_LIST: ['placeholder'] DISABLE_AUG_LIST: ['placeholder']
AUG_CONFIG_LIST: AUG_CONFIG_LIST:
...@@ -33,18 +33,17 @@ DATA_AUGMENTOR: ...@@ -33,18 +33,17 @@ DATA_AUGMENTOR:
DB_INFO_PATH: DB_INFO_PATH:
- custom_dbinfos_train.pkl - custom_dbinfos_train.pkl
PREPARE: { PREPARE: {
filter_by_min_points: ['Car:5', 'Pedestrian:5', 'Cyclist:5'], filter_by_min_points: ['Vehicle:5', 'Pedestrian:5', 'Cyclist:5'],
filter_by_difficulty: [-1],
} }
SAMPLE_GROUPS: ['Car:20','Pedestrian:15', 'Cyclist:15'] SAMPLE_GROUPS: ['Vehicle:20', 'Pedestrian:15', 'Cyclist:15']
NUM_POINT_FEATURES: 4 NUM_POINT_FEATURES: 4
DATABASE_WITH_FAKELIDAR: False DATABASE_WITH_FAKELIDAR: False
REMOVE_EXTRA_WIDTH: [0.0, 0.0, 0.0] REMOVE_EXTRA_WIDTH: [0.0, 0.0, 0.0]
LIMIT_WHOLE_SCENE: True LIMIT_WHOLE_SCENE: True
- NAME: random_world_flip - NAME: random_world_flip
ALONG_AXIS_LIST: ['x'] ALONG_AXIS_LIST: ['x', 'y']
- NAME: random_world_rotation - NAME: random_world_rotation
WORLD_ROT_ANGLE: [-0.78539816, 0.78539816] WORLD_ROT_ANGLE: [-0.78539816, 0.78539816]
...@@ -63,9 +62,9 @@ DATA_PROCESSOR: ...@@ -63,9 +62,9 @@ DATA_PROCESSOR:
} }
- NAME: transform_points_to_voxels - NAME: transform_points_to_voxels
VOXEL_SIZE: [0.05, 0.05, 0.1] VOXEL_SIZE: [0.1, 0.1, 0.15]
MAX_POINTS_PER_VOXEL: 5 MAX_POINTS_PER_VOXEL: 5
MAX_NUMBER_OF_VOXELS: { MAX_NUMBER_OF_VOXELS: {
'train': 16000, 'train': 150000,
'test': 40000 'test': 150000
} }
\ No newline at end of file
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