Commit 41b18fd8 authored by zhe chen's avatar zhe chen
Browse files

Use pre-commit to reformat code


Use pre-commit to reformat code
parent ff20ea39
......@@ -3,13 +3,13 @@
# ---------------------------------------------
# Modified by Xiaoyu Tian
# ---------------------------------------------
from data_converter.create_gt_database import create_groundtruth_database
import argparse
import sys
from os import path as osp
from data_converter import nuscenes_converter as nuscenes_converter
from data_converter import nuscenes_occ_converter as occ_converter
import argparse
from os import path as osp
import sys
sys.path.append('.')
......@@ -55,13 +55,13 @@ def nuscenes_data_prep(root_path,
def occ_nuscenes_data_prep(root_path,
occ_path,
can_bus_root_path,
info_prefix,
version,
dataset_name,
out_dir,
max_sweeps=10):
occ_path,
can_bus_root_path,
info_prefix,
version,
dataset_name,
out_dir,
max_sweeps=10):
"""Prepare occ data related to nuScenes dataset.
Related data consists of '.pkl' files recording basic infos,
......@@ -76,28 +76,7 @@ def occ_nuscenes_data_prep(root_path,
max_sweeps (int): Number of input consecutive frames. Default: 10
"""
occ_converter.create_nuscenes_occ_infos(
root_path, occ_path,out_dir, can_bus_root_path, info_prefix, version=version, max_sweeps=max_sweeps)
# if version == 'v1.0-test':
# info_test_path = osp.join(
# out_dir, f'{info_prefix}_infos_temporal_test.pkl')
# nuscenes_converter.export_2d_annotation(
# root_path, info_test_path, version=version)
# else:
# info_train_path = osp.join(
# out_dir, f'{info_prefix}_infos_temporal_train.pkl')
# info_val_path = osp.join(
# out_dir, f'{info_prefix}_infos_temporal_val.pkl')
# nuscenes_converter.export_2d_annotation(
# root_path, info_train_path, version=version)
# nuscenes_converter.export_2d_annotation(
# root_path, info_val_path, version=version)
# create_groundtruth_database(dataset_name, root_path, info_prefix,
# f'{out_dir}/{info_prefix}_infos_train.pkl')
root_path, occ_path, out_dir, can_bus_root_path, info_prefix, version=version, max_sweeps=max_sweeps)
parser = argparse.ArgumentParser(description='Data converter arg parser')
......@@ -161,7 +140,6 @@ if __name__ == '__main__':
out_dir=args.out_dir,
max_sweeps=args.max_sweeps)
elif args.dataset == 'nuscenes' and args.version == 'v1.0-mini':
train_version = f'{args.version}'
nuscenes_data_prep(
......@@ -203,4 +181,3 @@ if __name__ == '__main__':
dataset_name='NuScenesDataset',
out_dir=args.out_dir,
max_sweeps=args.max_sweeps)
# Copyright (c) OpenMMLab. All rights reserved.
import pickle
from os import path as osp
import mmcv
import numpy as np
import pickle
from mmcv import track_iter_progress
from mmcv.ops import roi_align
from os import path as osp
from pycocotools import mask as maskUtils
from pycocotools.coco import COCO
from mmdet3d.core.bbox import box_np_ops as box_np_ops
from mmdet3d.datasets import build_dataset
from mmdet.core.evaluation.bbox_overlaps import bbox_overlaps
from pycocotools import mask as maskUtils
from pycocotools.coco import COCO
def _poly2mask(mask_ann, img_h, img_w):
......
......@@ -3,19 +3,19 @@
# ---------------------------------------------
# Modified by Xiaoyu Tian
# ---------------------------------------------
import mmcv
import numpy as np
import os
from collections import OrderedDict
from nuscenes.nuscenes import NuScenes
from nuscenes.utils.geometry_utils import view_points
from os import path as osp
from pyquaternion import Quaternion
from shapely.geometry import MultiPoint, box
from typing import List, Tuple, Union
import mmcv
import numpy as np
from mmdet3d.core.bbox.box_np_ops import points_cam2img
from mmdet3d.datasets import NuScenesDataset
from nuscenes.nuscenes import NuScenes
from nuscenes.utils.geometry_utils import view_points
from pyquaternion import Quaternion
from shapely.geometry import MultiPoint, box
nus_categories = ('car', 'truck', 'trailer', 'bus', 'construction_vehicle',
'bicycle', 'motorcycle', 'pedestrian', 'traffic_cone',
......@@ -45,8 +45,8 @@ def create_nuscenes_infos(root_path,
max_sweeps (int): Max number of sweeps.
Default: 10
"""
from nuscenes.nuscenes import NuScenes
from nuscenes.can_bus.can_bus_api import NuScenesCanBus
from nuscenes.nuscenes import NuScenes
print(version, root_path)
nusc = NuScenes(version=version, dataroot=root_path, verbose=True)
nusc_can_bus = NuScenesCanBus(dataroot=can_bus_root_path)
......@@ -369,9 +369,9 @@ def obtain_sensor2top(nusc,
l2e_r_s_mat = Quaternion(l2e_r_s).rotation_matrix
e2g_r_s_mat = Quaternion(e2g_r_s).rotation_matrix
R = (l2e_r_s_mat.T @ e2g_r_s_mat.T) @ (
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
T = (l2e_t_s @ e2g_r_s_mat.T + e2g_t_s) @ (
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
T -= e2g_t @ (np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T
) + l2e_t @ np.linalg.inv(l2e_r_mat).T
sweep['sensor2lidar_rotation'] = R.T # points @ R.T + T
......@@ -464,8 +464,8 @@ def get_2d_boxes(nusc,
sd_rec = nusc.get('sample_data', sample_data_token)
assert sd_rec[
'sensor_modality'] == 'camera', 'Error: get_2d_boxes only works' \
' for camera sample_data!'
'sensor_modality'] == 'camera', 'Error: get_2d_boxes only works' \
' for camera sample_data!'
if not sd_rec['is_key_frame']:
raise ValueError(
'The 2D re-projections are available only for keyframes.')
......@@ -576,7 +576,7 @@ def get_2d_boxes(nusc,
def post_process_coords(
corner_coords: List, imsize: Tuple[int, int] = (1600, 900)
corner_coords: List, imsize: Tuple[int, int] = (1600, 900)
) -> Union[Tuple[float, float, float, float], None]:
"""Get the intersection of the convex hull of the reprojected bbox corners
and the image canvas, return None if no intersection.
......
......@@ -3,20 +3,20 @@
# ---------------------------------------------
# Modified by Xiaoyu Tian
# ---------------------------------------------
import mmcv
import numpy as np
import os
from collections import OrderedDict
from nuscenes.nuscenes import NuScenes
from nuscenes.utils.geometry_utils import view_points
from os import path as osp
from pyquaternion import Quaternion
from shapely.geometry import MultiPoint, box
from typing import List, Tuple, Union
import mmcv
import numpy as np
import simplejson as json
from mmdet3d.core.bbox.box_np_ops import points_cam2img
from mmdet3d.datasets import NuScenesDataset
import simplejson as json
from nuscenes.nuscenes import NuScenes
from nuscenes.utils.geometry_utils import view_points
from pyquaternion import Quaternion
from shapely.geometry import MultiPoint, box
nus_categories = ('car', 'truck', 'trailer', 'bus', 'construction_vehicle',
'bicycle', 'motorcycle', 'pedestrian', 'traffic_cone',
......@@ -29,12 +29,12 @@ nus_attributes = ('cycle.with_rider', 'cycle.without_rider',
def create_nuscenes_occ_infos(root_path,
occ_path,
out_path,
can_bus_root_path,
info_prefix,
version='v1.0-trainval',
max_sweeps=10):
occ_path,
out_path,
can_bus_root_path,
info_prefix,
version='v1.0-trainval',
max_sweeps=10):
"""Create info file of nuscene dataset.
Given the raw data, generate its related info file in pkl format.
......@@ -48,8 +48,8 @@ def create_nuscenes_occ_infos(root_path,
Default: 10
"""
from nuscenes.nuscenes import NuScenes
from nuscenes.can_bus.can_bus_api import NuScenesCanBus
from nuscenes.nuscenes import NuScenes
print(version, root_path)
nusc = NuScenes(version=version, dataroot=root_path, verbose=True)
nusc_can_bus = NuScenesCanBus(dataroot=can_bus_root_path)
......@@ -58,7 +58,7 @@ def create_nuscenes_occ_infos(root_path,
available_vers = ['v1.0-trainval', 'v1.0-test', 'v1.0-mini']
assert version in available_vers
with open(os.path.join(occ_path,'annotations.json'),'r') as f:
with open(os.path.join(occ_path, 'annotations.json'), 'r') as f:
occ_anno = json.load(f)
if version == 'v1.0-trainval':
......@@ -89,8 +89,7 @@ def create_nuscenes_occ_infos(root_path,
])
token2name = dict()
for scene in nusc.scene:
token2name[scene['token']]=scene['name']
token2name[scene['token']] = scene['name']
test = 'test' in version
if test:
......@@ -100,7 +99,7 @@ def create_nuscenes_occ_infos(root_path,
len(train_scenes), len(val_scenes)))
train_nusc_infos, val_nusc_infos = _fill_occ_trainval_infos(
nusc,occ_anno,token2name, nusc_can_bus, train_scenes, val_scenes, test, max_sweeps=max_sweeps)
nusc, occ_anno, token2name, nusc_can_bus, train_scenes, val_scenes, test, max_sweeps=max_sweeps)
metadata = dict(version=version)
if test:
......@@ -189,13 +188,13 @@ def _get_can_bus_info(nusc, nusc_can_bus, sample):
def _fill_occ_trainval_infos(nusc,
occ_anno,
token2name,
nusc_can_bus,
train_scenes,
val_scenes,
test=False,
max_sweeps=10):
occ_anno,
token2name,
nusc_can_bus,
train_scenes,
val_scenes,
test=False,
max_sweeps=10):
"""Generate the train/val infos from the raw data.
Args:
......@@ -213,20 +212,18 @@ def _fill_occ_trainval_infos(nusc,
train_nusc_infos = []
val_nusc_infos = []
frame_idx = 0
scene_infos=occ_anno['scene_infos']
scene_infos = occ_anno['scene_infos']
for sample in mmcv.track_iter_progress(nusc.sample):
lidar_token = sample['data']['LIDAR_TOP']
sd_rec = nusc.get('sample_data', sample['data']['LIDAR_TOP'])
scene_token = sample['scene_token']
scene_name = token2name[scene_token]
sample_token=sd_rec['sample_token']
sample_token = sd_rec['sample_token']
if sample_token in scene_infos[scene_name].keys():
occ_sample=scene_infos[scene_name][sample_token]
occ_sample = scene_infos[scene_name][sample_token]
else:
continue
......@@ -397,9 +394,9 @@ def obtain_sensor2top(nusc,
l2e_r_s_mat = Quaternion(l2e_r_s).rotation_matrix
e2g_r_s_mat = Quaternion(e2g_r_s).rotation_matrix
R = (l2e_r_s_mat.T @ e2g_r_s_mat.T) @ (
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
T = (l2e_t_s @ e2g_r_s_mat.T + e2g_t_s) @ (
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T)
T -= e2g_t @ (np.linalg.inv(e2g_r_mat).T @ np.linalg.inv(l2e_r_mat).T
) + l2e_t @ np.linalg.inv(l2e_r_mat).T
sweep['sensor2lidar_rotation'] = R.T # points @ R.T + T
......@@ -492,8 +489,8 @@ def get_2d_boxes(nusc,
sd_rec = nusc.get('sample_data', sample_data_token)
assert sd_rec[
'sensor_modality'] == 'camera', 'Error: get_2d_boxes only works' \
' for camera sample_data!'
'sensor_modality'] == 'camera', 'Error: get_2d_boxes only works' \
' for camera sample_data!'
if not sd_rec['is_key_frame']:
raise ValueError(
'The 2D re-projections are available only for keyframes.')
......@@ -604,7 +601,7 @@ def get_2d_boxes(nusc,
def post_process_coords(
corner_coords: List, imsize: Tuple[int, int] = (1600, 900)
corner_coords: List, imsize: Tuple[int, int] = (1600, 900)
) -> Union[Tuple[float, float, float, float], None]:
"""Get the intersection of the convex hull of the reprojected bbox corners
and the image canvas, return None if no intersection.
......
......@@ -17,4 +17,4 @@ python -m torch.distributed.launch \
$(dirname "$0")/train.py \
$CONFIG \
--deterministic \
--launcher pytorch ${@:3}
\ No newline at end of file
--launcher pytorch ${@:3}
# Copyright (c) OpenMMLab. All rights reserved.
from __future__ import division
import argparse
import copy
import mmcv
import os
import time
import torch
import warnings
from mmcv import Config, DictAction
from mmcv.runner import get_dist_info, init_dist, wrap_fp16_model
from os import path as osp
from mmdet import __version__ as mmdet_version
from mmdet3d import __version__ as mmdet3d_version
#from mmdet3d.apis import train_model
from mmdet3d.datasets import build_dataset
from mmdet3d.models import build_model
from mmdet3d.utils import collect_env, get_root_logger
from mmdet.apis import set_random_seed
from mmseg import __version__ as mmseg_version
from mmcv.utils import TORCH_VERSION, digit_version
def parse_args():
parser = argparse.ArgumentParser(description='Train a detector')
parser.add_argument('config', help='train config file path')
parser.add_argument('--work-dir', help='the dir to save logs and models')
parser.add_argument(
'--resume-from', help='the checkpoint file to resume from')
parser.add_argument(
'--no-validate',
action='store_true',
help='whether not to evaluate the checkpoint during training')
group_gpus = parser.add_mutually_exclusive_group()
group_gpus.add_argument(
'--gpus',
type=int,
help='number of gpus to use '
'(only applicable to non-distributed training)')
group_gpus.add_argument(
'--gpu-ids',
type=int,
nargs='+',
help='ids of gpus to use '
'(only applicable to non-distributed training)')
parser.add_argument('--seed', type=int, default=0, help='random seed')
parser.add_argument(
'--deterministic',
action='store_true',
help='whether to set deterministic options for CUDNN backend.')
parser.add_argument(
'--options',
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file (deprecate), '
'change to --cfg-options instead.')
parser.add_argument(
'--cfg-options',
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
parser.add_argument(
'--launcher',
choices=['none', 'pytorch', 'slurm', 'mpi'],
default='none',
help='job launcher')
parser.add_argument('--local_rank', type=int, default=0)
parser.add_argument(
'--autoscale-lr',
action='store_true',
help='automatically scale lr with the number of gpus')
args = parser.parse_args()
if 'LOCAL_RANK' not in os.environ:
os.environ['LOCAL_RANK'] = str(args.local_rank)
if args.options and args.cfg_options:
raise ValueError(
'--options and --cfg-options cannot be both specified, '
'--options is deprecated in favor of --cfg-options')
if args.options:
warnings.warn('--options is deprecated in favor of --cfg-options')
args.cfg_options = args.options
return args
def main():
args = parse_args()
cfg = Config.fromfile(args.config)
if args.cfg_options is not None:
cfg.merge_from_dict(args.cfg_options)
# import modules from string list.
if cfg.get('custom_imports', None):
from mmcv.utils import import_modules_from_strings
import_modules_from_strings(**cfg['custom_imports'])
# import modules from plguin/xx, registry will be updated
if hasattr(cfg, 'plugin'):
if cfg.plugin:
import importlib
if hasattr(cfg, 'plugin_dir'):
plugin_dir = cfg.plugin_dir
_module_dir = os.path.dirname(plugin_dir)
_module_dir = _module_dir.split('/')
_module_path = _module_dir[0]
for m in _module_dir[1:]:
_module_path = _module_path + '.' + m
print(_module_path)
plg_lib = importlib.import_module(_module_path)
else:
# import dir is the dirpath for the config file
_module_dir = os.path.dirname(args.config)
_module_dir = _module_dir.split('/')
_module_path = _module_dir[0]
for m in _module_dir[1:]:
_module_path = _module_path + '.' + m
print(_module_path)
plg_lib = importlib.import_module(_module_path)
from projects.mmdet3d_plugin.bevformer.apis import custom_train_model
# set cudnn_benchmark
if cfg.get('cudnn_benchmark', False):
torch.backends.cudnn.benchmark = True
# work_dir is determined in this priority: CLI > segment in file > filename
if args.work_dir is not None:
# update configs according to CLI args if args.work_dir is not None
cfg.work_dir = args.work_dir
elif cfg.get('work_dir', None) is None:
# use config filename as default work_dir if cfg.work_dir is None
cfg.work_dir = osp.join('./work_dirs',
osp.splitext(osp.basename(args.config))[0])
#if args.resume_from is not None:
if args.resume_from is not None and osp.isfile(args.resume_from):
cfg.resume_from = args.resume_from
if args.gpu_ids is not None:
cfg.gpu_ids = args.gpu_ids
else:
cfg.gpu_ids = range(1) if args.gpus is None else range(args.gpus)
if digit_version(TORCH_VERSION) != digit_version('1.8.1'):
cfg.optimizer['type'] = 'AdamW'
if args.autoscale_lr:
# apply the linear scaling rule (https://arxiv.org/abs/1706.02677)
cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 8
# init distributed env first, since logger depends on the dist info.
if args.launcher == 'none':
assert False, 'DOT NOT SUPPORT!!!'
distributed = False
else:
distributed = True
init_dist(args.launcher, **cfg.dist_params)
# re-set gpu_ids with distributed training mode
_, world_size = get_dist_info()
cfg.gpu_ids = range(world_size)
# create work_dir
mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))
# dump config
cfg.dump(osp.join(cfg.work_dir, osp.basename(args.config)))
# init the logger before other steps
timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())
log_file = osp.join(cfg.work_dir, f'{timestamp}.log')
# specify logger name, if we still use 'mmdet', the output info will be
# filtered and won't be saved in the log_file
# TODO: ugly workaround to judge whether we are training det or seg model
if cfg.model.type in ['EncoderDecoder3D']:
logger_name = 'mmseg'
else:
logger_name = 'mmdet'
logger = get_root_logger(
log_file=log_file, log_level=cfg.log_level, name=logger_name)
# init the meta dict to record some important information such as
# environment info and seed, which will be logged
meta = dict()
# log env info
env_info_dict = collect_env()
env_info = '\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()])
dash_line = '-' * 60 + '\n'
logger.info('Environment info:\n' + dash_line + env_info + '\n' +
dash_line)
meta['env_info'] = env_info
meta['config'] = cfg.pretty_text
# log some basic info
logger.info(f'Distributed training: {distributed}')
logger.info(f'Config:\n{cfg.pretty_text}')
# set random seeds
if args.seed is not None:
logger.info(f'Set random seed to {args.seed}, '
f'deterministic: {args.deterministic}')
set_random_seed(args.seed, deterministic=args.deterministic)
cfg.seed = args.seed
meta['seed'] = args.seed
meta['exp_name'] = osp.basename(args.config)
model = build_model(
cfg.model,
train_cfg=cfg.get('train_cfg'),
test_cfg=cfg.get('test_cfg'))
model.init_weights()
eval_model_config = copy.deepcopy(cfg.model)
eval_model = build_model(
eval_model_config,
train_cfg=cfg.get('train_cfg'),
test_cfg=cfg.get('test_cfg'))
fp16_cfg = cfg.get('fp16', None)
if fp16_cfg is not None:
wrap_fp16_model(eval_model)
#eval_model.init_weights()
eval_model.load_state_dict(model.state_dict())
logger.info(f'Model:\n{model}')
from projects.mmdet3d_plugin.datasets import custom_build_dataset
datasets = [custom_build_dataset(cfg.data.train)]
if len(cfg.workflow) == 2:
val_dataset = copy.deepcopy(cfg.data.val)
# in case we use a dataset wrapper
if 'dataset' in cfg.data.train:
val_dataset.pipeline = cfg.data.train.dataset.pipeline
else:
val_dataset.pipeline = cfg.data.train.pipeline
# set test_mode=False here in deep copied config
# which do not affect AP/AR calculation later
# refer to https://mmdetection3d.readthedocs.io/en/latest/tutorials/customize_runtime.html#customize-workflow # noqa
val_dataset.test_mode = False
datasets.append(custom_build_dataset(val_dataset))
if cfg.checkpoint_config is not None:
# save mmdet version, config file content and class names in
# checkpoints as meta data
cfg.checkpoint_config.meta = dict(
mmdet_version=mmdet_version,
mmseg_version=mmseg_version,
mmdet3d_version=mmdet3d_version,
config=cfg.pretty_text,
CLASSES=datasets[0].CLASSES,
PALETTE=datasets[0].PALETTE # for segmentors
if hasattr(datasets[0], 'PALETTE') else None)
# add an attribute for visualization convenience
model.CLASSES = datasets[0].CLASSES
custom_train_model(
model,
datasets,
cfg,
eval_model=eval_model,
distributed=distributed,
validate=(not args.no_validate),
timestamp=timestamp,
meta=meta)
if __name__ == '__main__':
main()
# Copyright (c) OpenMMLab. All rights reserved.
from __future__ import division
import argparse
import copy
import os
import time
import warnings
from os import path as osp
import mmcv
import torch
from mmcv import Config, DictAction
from mmcv.runner import get_dist_info, init_dist, wrap_fp16_model
from mmcv.utils import TORCH_VERSION, digit_version
from mmdet import __version__ as mmdet_version
from mmdet3d import __version__ as mmdet3d_version
from mmdet3d.models import build_model
from mmdet3d.utils import collect_env, get_root_logger
from mmdet.apis import set_random_seed
from mmseg import __version__ as mmseg_version
# from mmdet3d.apis import train_model
def parse_args():
parser = argparse.ArgumentParser(description='Train a detector')
parser.add_argument('config', help='train config file path')
parser.add_argument('--work-dir', help='the dir to save logs and models')
parser.add_argument(
'--resume-from', help='the checkpoint file to resume from')
parser.add_argument(
'--no-validate',
action='store_true',
help='whether not to evaluate the checkpoint during training')
group_gpus = parser.add_mutually_exclusive_group()
group_gpus.add_argument(
'--gpus',
type=int,
help='number of gpus to use '
'(only applicable to non-distributed training)')
group_gpus.add_argument(
'--gpu-ids',
type=int,
nargs='+',
help='ids of gpus to use '
'(only applicable to non-distributed training)')
parser.add_argument('--seed', type=int, default=0, help='random seed')
parser.add_argument(
'--deterministic',
action='store_true',
help='whether to set deterministic options for CUDNN backend.')
parser.add_argument(
'--options',
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file (deprecate), '
'change to --cfg-options instead.')
parser.add_argument(
'--cfg-options',
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
parser.add_argument(
'--launcher',
choices=['none', 'pytorch', 'slurm', 'mpi'],
default='none',
help='job launcher')
parser.add_argument('--local_rank', type=int, default=0)
parser.add_argument(
'--autoscale-lr',
action='store_true',
help='automatically scale lr with the number of gpus')
args = parser.parse_args()
if 'LOCAL_RANK' not in os.environ:
os.environ['LOCAL_RANK'] = str(args.local_rank)
if args.options and args.cfg_options:
raise ValueError(
'--options and --cfg-options cannot be both specified, '
'--options is deprecated in favor of --cfg-options')
if args.options:
warnings.warn('--options is deprecated in favor of --cfg-options')
args.cfg_options = args.options
return args
def main():
args = parse_args()
cfg = Config.fromfile(args.config)
if args.cfg_options is not None:
cfg.merge_from_dict(args.cfg_options)
# import modules from string list.
if cfg.get('custom_imports', None):
from mmcv.utils import import_modules_from_strings
import_modules_from_strings(**cfg['custom_imports'])
# import modules from plguin/xx, registry will be updated
if hasattr(cfg, 'plugin'):
if cfg.plugin:
import importlib
if hasattr(cfg, 'plugin_dir'):
plugin_dir = cfg.plugin_dir
_module_dir = os.path.dirname(plugin_dir)
_module_dir = _module_dir.split('/')
_module_path = _module_dir[0]
for m in _module_dir[1:]:
_module_path = _module_path + '.' + m
print(_module_path)
plg_lib = importlib.import_module(_module_path)
else:
# import dir is the dirpath for the config file
_module_dir = os.path.dirname(args.config)
_module_dir = _module_dir.split('/')
_module_path = _module_dir[0]
for m in _module_dir[1:]:
_module_path = _module_path + '.' + m
print(_module_path)
plg_lib = importlib.import_module(_module_path)
from projects.mmdet3d_plugin.bevformer.apis import \
custom_train_model
# set cudnn_benchmark
if cfg.get('cudnn_benchmark', False):
torch.backends.cudnn.benchmark = True
# work_dir is determined in this priority: CLI > segment in file > filename
if args.work_dir is not None:
# update configs according to CLI args if args.work_dir is not None
cfg.work_dir = args.work_dir
elif cfg.get('work_dir', None) is None:
# use config filename as default work_dir if cfg.work_dir is None
cfg.work_dir = osp.join('./work_dirs',
osp.splitext(osp.basename(args.config))[0])
# if args.resume_from is not None:
if args.resume_from is not None and osp.isfile(args.resume_from):
cfg.resume_from = args.resume_from
if args.gpu_ids is not None:
cfg.gpu_ids = args.gpu_ids
else:
cfg.gpu_ids = range(1) if args.gpus is None else range(args.gpus)
if digit_version(TORCH_VERSION) != digit_version('1.8.1'):
cfg.optimizer['type'] = 'AdamW'
if args.autoscale_lr:
# apply the linear scaling rule (https://arxiv.org/abs/1706.02677)
cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 8
# init distributed env first, since logger depends on the dist info.
if args.launcher == 'none':
assert False, 'DOT NOT SUPPORT!!!'
distributed = False
else:
distributed = True
init_dist(args.launcher, **cfg.dist_params)
# re-set gpu_ids with distributed training mode
_, world_size = get_dist_info()
cfg.gpu_ids = range(world_size)
# create work_dir
mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))
# dump config
cfg.dump(osp.join(cfg.work_dir, osp.basename(args.config)))
# init the logger before other steps
timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())
log_file = osp.join(cfg.work_dir, f'{timestamp}.log')
# specify logger name, if we still use 'mmdet', the output info will be
# filtered and won't be saved in the log_file
# TODO: ugly workaround to judge whether we are training det or seg model
if cfg.model.type in ['EncoderDecoder3D']:
logger_name = 'mmseg'
else:
logger_name = 'mmdet'
logger = get_root_logger(
log_file=log_file, log_level=cfg.log_level, name=logger_name)
# init the meta dict to record some important information such as
# environment info and seed, which will be logged
meta = dict()
# log env info
env_info_dict = collect_env()
env_info = '\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()])
dash_line = '-' * 60 + '\n'
logger.info('Environment info:\n' + dash_line + env_info + '\n' +
dash_line)
meta['env_info'] = env_info
meta['config'] = cfg.pretty_text
# log some basic info
logger.info(f'Distributed training: {distributed}')
logger.info(f'Config:\n{cfg.pretty_text}')
# set random seeds
if args.seed is not None:
logger.info(f'Set random seed to {args.seed}, '
f'deterministic: {args.deterministic}')
set_random_seed(args.seed, deterministic=args.deterministic)
cfg.seed = args.seed
meta['seed'] = args.seed
meta['exp_name'] = osp.basename(args.config)
model = build_model(
cfg.model,
train_cfg=cfg.get('train_cfg'),
test_cfg=cfg.get('test_cfg'))
model.init_weights()
eval_model_config = copy.deepcopy(cfg.model)
eval_model = build_model(
eval_model_config,
train_cfg=cfg.get('train_cfg'),
test_cfg=cfg.get('test_cfg'))
fp16_cfg = cfg.get('fp16', None)
if fp16_cfg is not None:
wrap_fp16_model(eval_model)
# eval_model.init_weights()
eval_model.load_state_dict(model.state_dict())
logger.info(f'Model:\n{model}')
from projects.mmdet3d_plugin.datasets import custom_build_dataset
datasets = [custom_build_dataset(cfg.data.train)]
if len(cfg.workflow) == 2:
val_dataset = copy.deepcopy(cfg.data.val)
# in case we use a dataset wrapper
if 'dataset' in cfg.data.train:
val_dataset.pipeline = cfg.data.train.dataset.pipeline
else:
val_dataset.pipeline = cfg.data.train.pipeline
# set test_mode=False here in deep copied config
# which do not affect AP/AR calculation later
# refer to https://mmdetection3d.readthedocs.io/en/latest/tutorials/customize_runtime.html#customize-workflow # noqa
val_dataset.test_mode = False
datasets.append(custom_build_dataset(val_dataset))
if cfg.checkpoint_config is not None:
# save mmdet version, config file content and class names in
# checkpoints as meta data
cfg.checkpoint_config.meta = dict(
mmdet_version=mmdet_version,
mmseg_version=mmseg_version,
mmdet3d_version=mmdet3d_version,
config=cfg.pretty_text,
CLASSES=datasets[0].CLASSES,
PALETTE=datasets[0].PALETTE # for segmentors
if hasattr(datasets[0], 'PALETTE') else None)
# add an attribute for visualization convenience
model.CLASSES = datasets[0].CLASSES
custom_train_model(
model,
datasets,
cfg,
eval_model=eval_model,
distributed=distributed,
validate=(not args.no_validate),
timestamp=timestamp,
meta=meta)
if __name__ == '__main__':
main()
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import numpy as np
import warnings
from mmcv import Config, DictAction, mkdir_or_exist, track_iter_progress
from os import path as osp
import numpy as np
from mmcv import Config, DictAction, mkdir_or_exist, track_iter_progress
from mmdet3d.core.bbox import (Box3DMode, CameraInstance3DBoxes, Coord3DMode,
DepthInstance3DBoxes, LiDARInstance3DBoxes)
from mmdet3d.core.visualizer import (show_multi_modality_result, show_result,
......@@ -35,17 +35,17 @@ def parse_args():
'--online',
action='store_true',
help='Whether to perform online visualization. Note that you often '
'need a monitor to do so.')
'need a monitor to do so.')
parser.add_argument(
'--cfg-options',
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
args = parser.parse_args()
return args
......@@ -203,8 +203,8 @@ def main():
if dataset_type in ['KittiDataset', 'WaymoDataset']:
data_path = data_info['point_cloud']['velodyne_path']
elif dataset_type in [
'ScanNetDataset', 'SUNRGBDDataset', 'ScanNetSegDataset',
'S3DISSegDataset', 'S3DISDataset'
'ScanNetDataset', 'SUNRGBDDataset', 'ScanNetSegDataset',
'S3DISSegDataset', 'S3DISDataset'
]:
data_path = data_info['pts_path']
elif dataset_type in ['NuScenesDataset', 'LyftDataset']:
......
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import torch
from mmcv.runner import save_checkpoint
from torch import nn as nn
from mmdet.apis import init_model
from torch import nn as nn
def fuse_conv_bn(conv, bn):
......
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
from mmcv import Config, DictAction
......
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import mmcv
from mmcv import Config
from mmdet3d.datasets import build_dataset
......
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import tempfile
import torch
from mmcv import Config
from mmcv.runner import load_state_dict
from mmdet3d.models import build_detector
......@@ -104,13 +104,13 @@ def main():
EXTRACT_KEYS = {
'bbox_head.conv_pred.conv_cls.weight':
('bbox_head.conv_pred.conv_out.weight', [(0, 2), (-NUM_CLASSES, -1)]),
('bbox_head.conv_pred.conv_out.weight', [(0, 2), (-NUM_CLASSES, -1)]),
'bbox_head.conv_pred.conv_cls.bias':
('bbox_head.conv_pred.conv_out.bias', [(0, 2), (-NUM_CLASSES, -1)]),
('bbox_head.conv_pred.conv_out.bias', [(0, 2), (-NUM_CLASSES, -1)]),
'bbox_head.conv_pred.conv_reg.weight':
('bbox_head.conv_pred.conv_out.weight', [(2, -NUM_CLASSES)]),
('bbox_head.conv_pred.conv_out.weight', [(2, -NUM_CLASSES)]),
'bbox_head.conv_pred.conv_reg.bias':
('bbox_head.conv_pred.conv_out.bias', [(2, -NUM_CLASSES)])
('bbox_head.conv_pred.conv_out.bias', [(2, -NUM_CLASSES)])
}
# Delete some useless keys
......
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import subprocess
import torch
......
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import torch
from collections import OrderedDict
import torch
def convert_stem(model_key, model_weight, state_dict, converted_names):
new_key = model_key.replace('stem.conv', 'conv1')
......
......@@ -4,24 +4,23 @@
# Modified by Xiaoyu Tian
# ---------------------------------------------
import argparse
import mmcv
import os
import sys
import torch
import os.path as osp
import time
import warnings
import torch
from mmcv import Config, DictAction
from mmcv.cnn import fuse_conv_bn
from mmcv.parallel import MMDataParallel, MMDistributedDataParallel
from mmcv.parallel import MMDistributedDataParallel
from mmcv.runner import (get_dist_info, init_dist, load_checkpoint,
wrap_fp16_model)
from mmdet3d.datasets import build_dataset
from projects.mmdet3d_plugin.datasets.builder import build_dataloader
from mmdet3d.models import build_model
from mmdet.apis import set_random_seed
from projects.mmdet3d_plugin.bevformer.apis.test import custom_multi_gpu_test
from mmdet.datasets import replace_ImageToTensor
import time
import os.path as osp
from projects.mmdet3d_plugin.bevformer.apis.test import custom_multi_gpu_test
from projects.mmdet3d_plugin.datasets.builder import build_dataloader
def parse_args():
......@@ -38,19 +37,19 @@ def parse_args():
'--fuse-conv-bn',
action='store_true',
help='Whether to fuse conv and bn, this will slightly increase'
'the inference speed')
'the inference speed')
parser.add_argument(
'--format-only',
action='store_true',
help='Format the output results without perform evaluation. It is'
'useful when you want to format the result to a specific format and '
'submit it to the test server')
'useful when you want to format the result to a specific format and '
'submit it to the test server')
parser.add_argument(
'--eval',
type=str,
nargs='+',
help='evaluation metrics, which depends on the dataset, e.g., "bbox",'
' "segm", "proposal" for COCO, and "mAP", "recall" for PASCAL VOC')
' "segm", "proposal" for COCO, and "mAP", "recall" for PASCAL VOC')
parser.add_argument('--show', action='store_true', help='show results')
parser.add_argument(
'--show-dir', help='directory where results will be saved')
......@@ -61,7 +60,7 @@ def parse_args():
parser.add_argument(
'--tmpdir',
help='tmp directory used for collecting results from multiple '
'workers, available when gpu-collect is not specified')
'workers, available when gpu-collect is not specified')
parser.add_argument('--seed', type=int, default=0, help='random seed')
parser.add_argument(
'--deterministic',
......@@ -72,24 +71,24 @@ def parse_args():
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
parser.add_argument(
'--options',
nargs='+',
action=DictAction,
help='custom options for evaluation, the key-value pair in xxx=yyy '
'format will be kwargs for dataset.evaluate() function (deprecate), '
'change to --eval-options instead.')
'format will be kwargs for dataset.evaluate() function (deprecate), '
'change to --eval-options instead.')
parser.add_argument(
'--eval-options',
nargs='+',
action=DictAction,
help='custom options for evaluation, the key-value pair in xxx=yyy '
'format will be kwargs for dataset.evaluate() function')
'format will be kwargs for dataset.evaluate() function')
parser.add_argument(
'--launcher',
choices=['none', 'pytorch', 'slurm', 'mpi'],
......@@ -193,7 +192,7 @@ def main():
# build the dataloader
dataset = build_dataset(cfg.data.test)
if args.eval_fscore:
dataset.eval_fscore=True
dataset.eval_fscore = True
data_loader = build_dataloader(
dataset,
samples_per_gpu=samples_per_gpu,
......@@ -242,7 +241,7 @@ def main():
if args.out:
print(f'\nwriting results to {args.out}')
assert False
#mmcv.dump(outputs['bbox_results'], args.out)
# mmcv.dump(outputs['bbox_results'], args.out)
kwargs = {} if args.eval_options is None else args.eval_options
kwargs['jsonfile_prefix'] = osp.join('test', args.config.split(
'/')[-1].split('.')[-2], time.ctime().replace(' ', '_').replace(':', '_'))
......@@ -253,13 +252,13 @@ def main():
eval_kwargs = cfg.get('evaluation', {}).copy()
# hard-code way to remove EvalHook args
for key in [
'interval', 'tmpdir', 'start', 'gpu_collect', 'save_best',
'rule','begin','end'
'interval', 'tmpdir', 'start', 'gpu_collect', 'save_best',
'rule', 'begin', 'end'
]:
eval_kwargs.pop(key, None)
eval_kwargs.update(dict(metric=args.eval, **kwargs))
dataset.evaluate_miou(outputs,show_dir=args.show_dir, **eval_kwargs)
dataset.evaluate_miou(outputs, show_dir=args.show_dir, **eval_kwargs)
if __name__ == '__main__':
......
......@@ -3,31 +3,30 @@
# ---------------------------------------------
# Modified by Zhiqi Li
# ---------------------------------------------
from __future__ import division
import argparse
import copy
import mmcv
import os
import time
import torch
import warnings
from mmcv import Config, DictAction
from mmcv.runner import get_dist_info, init_dist
from os import path as osp
import mmcv
import torch
from mmcv import Config, DictAction
from mmcv.runner import get_dist_info, init_dist
from mmcv.utils import TORCH_VERSION, digit_version
from mmdet import __version__ as mmdet_version
from mmdet3d import __version__ as mmdet3d_version
#from mmdet3d.apis import train_model
from mmdet3d.datasets import build_dataset
from mmdet3d.models import build_model
from mmdet3d.utils import collect_env, get_root_logger
from mmdet.apis import set_random_seed
from mmseg import __version__ as mmseg_version
from mmcv.utils import TORCH_VERSION, digit_version
# from mmdet3d.apis import train_model
def parse_args():
......@@ -45,13 +44,13 @@ def parse_args():
'--gpus',
type=int,
help='number of gpus to use '
'(only applicable to non-distributed training)')
'(only applicable to non-distributed training)')
group_gpus.add_argument(
'--gpu-ids',
type=int,
nargs='+',
help='ids of gpus to use '
'(only applicable to non-distributed training)')
'(only applicable to non-distributed training)')
parser.add_argument('--seed', type=int, default=0, help='random seed')
parser.add_argument(
'--deterministic',
......@@ -62,18 +61,18 @@ def parse_args():
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file (deprecate), '
'change to --cfg-options instead.')
'in xxx=yyy format will be merged into config file (deprecate), '
'change to --cfg-options instead.')
parser.add_argument(
'--cfg-options',
nargs='+',
action=DictAction,
help='override some settings in the used config, the key-value pair '
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
'in xxx=yyy format will be merged into config file. If the value to '
'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
'Note that the quotation marks are necessary and that no white space '
'is allowed.')
parser.add_argument(
'--launcher',
choices=['none', 'pytorch', 'slurm', 'mpi'],
......@@ -134,7 +133,8 @@ def main():
print(_module_path)
plg_lib = importlib.import_module(_module_path)
from projects.mmdet3d_plugin.bevformer.apis.train import custom_train_model
from projects.mmdet3d_plugin.bevformer.apis.train import \
custom_train_model
# set cudnn_benchmark
if cfg.get('cudnn_benchmark', False):
torch.backends.cudnn.benchmark = True
......@@ -155,7 +155,7 @@ def main():
else:
cfg.gpu_ids = range(1) if args.gpus is None else range(args.gpus)
if digit_version(TORCH_VERSION) == digit_version('1.8.1') and cfg.optimizer['type'] == 'AdamW':
cfg.optimizer['type'] = 'AdamW2' # fix bug in Adamw
cfg.optimizer['type'] = 'AdamW2' # fix bug in Adamw
if args.autoscale_lr:
# apply the linear scaling rule (https://arxiv.org/abs/1706.02677)
cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 8
......
import open3d as o3d
import pickle
import math
import numpy as np
import open3d as o3d
import torch
import math
from pathlib import Path
import os
from glob import glob
LINE_SEGMENTS = [
[4, 0], [3, 7], [5, 1], [6, 2], # lines along x-axis
[5, 4], [5, 6], [6, 7], [7, 4], # lines along x-axis
[0, 1], [1, 2], [2, 3], [3, 0]] # lines along y-axis
colors_map = np.array(
[
# [0, 0, 0, 255], # 0 undefined
[255, 158, 0, 255], # 1 car orange
[0, 0, 230, 255], # 2 pedestrian Blue
[47, 79, 79, 255], # 3 sign Darkslategrey
[0, 0, 230, 255], # 2 pedestrian Blue
[47, 79, 79, 255], # 3 sign Darkslategrey
[220, 20, 60, 255], # 4 CYCLIST Crimson
[255, 69, 0, 255], # 5 traiffic_light Orangered
[255, 69, 0, 255], # 5 traiffic_light Orangered
[255, 140, 0, 255], # 6 pole Darkorange
[233, 150, 70, 255], # 7 construction_cone Darksalmon
[233, 150, 70, 255], # 7 construction_cone Darksalmon
[255, 61, 99, 255], # 8 bycycle Red
[112, 128, 144, 255],# 9 motorcycle Slategrey
[222, 184, 135, 255],# 10 building Burlywood
[0, 175, 0, 255], # 11 vegetation Green
[112, 128, 144, 255], # 9 motorcycle Slategrey
[222, 184, 135, 255], # 10 building Burlywood
[0, 175, 0, 255], # 11 vegetation Green
[165, 42, 42, 255], # 12 trunk nuTonomy green
[0, 207, 191, 255], # 13 curb, road, lane_marker, other_ground
[75, 0, 75, 255], # 14 walkable, sidewalk
[255, 0, 0, 255], # 15 unobsrvd
[75, 0, 75, 255], # 14 walkable, sidewalk
[255, 0, 0, 255], # 15 unobsrvd
])
color = colors_map[:, :3] / 255
......@@ -48,42 +46,46 @@ def voxel2points(voxel, voxelSize, range=[-40.0, -40.0, -1.0, 40.0, 40.0, 5.4],
occIdx[2][:, None] * voxelSize[2] + voxelSize[2] / 2 + range[2]), dim=1)
return points, voxel[occIdx]
def voxel_profile(voxel, voxel_size):
centers = torch.cat((voxel[:, :2], voxel[:, 2][:, None] - voxel_size[2] / 2), dim=1)
# centers = voxel
wlh = torch.cat((torch.tensor(voxel_size[0]).repeat(centers.shape[0])[:, None],
torch.tensor(voxel_size[1]).repeat(centers.shape[0])[:, None],
torch.tensor(voxel_size[2]).repeat(centers.shape[0])[:, None]), dim=1)
torch.tensor(voxel_size[1]).repeat(centers.shape[0])[:, None],
torch.tensor(voxel_size[2]).repeat(centers.shape[0])[:, None]), dim=1)
yaw = torch.full_like(centers[:, 0:1], 0)
return torch.cat((centers, wlh, yaw), dim=1)
def rotz(t):
"""Rotation about the z-axis."""
c = torch.cos(t)
s = torch.sin(t)
return torch.tensor([[c, -s, 0],
[s, c, 0],
[0, 0, 1]])
return torch.tensor([[c, -s, 0],
[s, c, 0],
[0, 0, 1]])
def my_compute_box_3d(center, size, heading_angle):
h, w, l = size[:, 2], size[:, 0], size[:, 1]
heading_angle = -heading_angle - math.pi / 2
center[:, 2] = center[:, 2] + h / 2
#R = rotz(1 * heading_angle)
# R = rotz(1 * heading_angle)
l, w, h = (l / 2).unsqueeze(1), (w / 2).unsqueeze(1), (h / 2).unsqueeze(1)
x_corners = torch.cat([-l, l, l, -l, -l, l, l, -l], dim=1)[..., None]
y_corners = torch.cat([w, w, -w, -w, w, w, -w, -w], dim=1)[..., None]
z_corners = torch.cat([h, h, h, h, -h, -h, -h, -h], dim=1)[..., None]
#corners_3d = R @ torch.vstack([x_corners, y_corners, z_corners])
# corners_3d = R @ torch.vstack([x_corners, y_corners, z_corners])
corners_3d = torch.cat([x_corners, y_corners, z_corners], dim=2)
corners_3d[..., 0] += center[:, 0:1]
corners_3d[..., 1] += center[:, 1:2]
corners_3d[..., 2] += center[:, 2:3]
return corners_3d
def generate_the_ego_car():
ego_range = [-2, -1, 0, 2, 1, 1.5]
ego_voxel_size=[0.1, 0.1, 0.1]
ego_voxel_size = [0.1, 0.1, 0.1]
ego_xdim = int((ego_range[3] - ego_range[0]) / ego_voxel_size[0])
ego_ydim = int((ego_range[4] - ego_range[1]) / ego_voxel_size[1])
ego_zdim = int((ego_range[5] - ego_range[2]) / ego_voxel_size[2])
......@@ -96,13 +98,16 @@ def generate_the_ego_car():
ego_point_y = (ego_xyz[:, 1:2] + 0.5) / ego_ydim * (ego_range[4] - ego_range[1]) + ego_range[1]
ego_point_z = (ego_xyz[:, 2:3] + 0.5) / ego_zdim * (ego_range[5] - ego_range[2]) + ego_range[2]
ego_point_xyz = np.concatenate((ego_point_y, ego_point_x, ego_point_z), axis=-1)
ego_points_label = (np.ones((ego_point_xyz.shape[0]))*16).astype(np.uint8)
ego_points_label = (np.ones((ego_point_xyz.shape[0])) * 16).astype(np.uint8)
ego_dict = {}
ego_dict['point'] = ego_point_xyz
ego_dict['label'] = ego_points_label
return ego_point_xyz
def show_point_cloud(points: np.ndarray, colors=True, points_colors=None, obj_bboxes=None, voxelize=False, bbox_corners=None, linesets=None, ego_pcd=None, scene_idx=0, frame_idx=0, large_voxel=True, voxel_size=0.4) -> None:
def show_point_cloud(points: np.ndarray, colors=True, points_colors=None, obj_bboxes=None, voxelize=False,
bbox_corners=None, linesets=None, ego_pcd=None, scene_idx=0, frame_idx=0, large_voxel=True,
voxel_size=0.4) -> None:
vis = o3d.visualization.VisualizerWithKeyCallback()
vis.create_window(str(scene_idx))
......@@ -136,13 +141,14 @@ def show_point_cloud(points: np.ndarray, colors=True, points_colors=None, obj_bb
vis.update_renderer()
return vis
def vis_nuscene():
voxelSize = [0.4, 0.4, 0.4]
point_cloud_range = [-40.0, -40.0, -1.0, 40.0, 40.0, 5.4]
ignore_labels = [17, 255]
vis_voxel_size = 0.4
file = "data/29796060110c4163b07f06eff4af0753/labels.npz"
file = 'data/29796060110c4163b07f06eff4af0753/labels.npz'
data = np.load(file)
semantics, mask_lidar, mask_camera = data['semantics'], data['mask_lidar'], data['mask_camera']
......@@ -158,13 +164,15 @@ def vis_nuscene():
ego_pcd.points = o3d.utility.Vector3dVector(ego_points)
bboxes_corners = my_compute_box_3d(bboxes[:, 0:3], bboxes[:, 3:6], bboxes[:, 6:7])
bases_ = torch.arange(0, bboxes_corners.shape[0] * 8, 8)
edges = torch.tensor([[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7]]) # lines along y-axis
edges = torch.tensor([[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6],
[3, 7]]) # lines along y-axis
edges = edges.reshape((1, 12, 2)).repeat(bboxes_corners.shape[0], 1, 1)
edges = edges + bases_[:, None, None]
vis = show_point_cloud(points=points, colors=True, points_colors=pcd_colors, voxelize=True, obj_bboxes=None,
bbox_corners=bboxes_corners.numpy(), linesets=edges.numpy(), ego_pcd=ego_pcd, large_voxel=True, voxel_size=vis_voxel_size)
bbox_corners=bboxes_corners.numpy(), linesets=edges.numpy(), ego_pcd=ego_pcd,
large_voxel=True, voxel_size=vis_voxel_size)
# control view
# control view
# view_control = vis.get_view_control()
# view_control.set_zoom(args.zoom)
# view_control.set_up(args.up_vec)
......@@ -179,5 +187,6 @@ def vis_nuscene():
vis.destroy_window()
del vis
if __name__ == '__main__':
vis_nuscene()
\ No newline at end of file
vis_nuscene()
<div id="top" align="center">
# OpenLane-Huawei
**全球首个自动驾驶道路结构感知和推理基准。**
<a href="#数据">
<img alt="OpenLane-v2: v1.0" src="https://img.shields.io/badge/OpenLane--V2-v1.0-blueviolet"/>
</a>
<a href="#开发工具">
<img alt="devkit: v0.1.0" src="https://img.shields.io/badge/devkit-v0.1.0-blueviolet"/>
</a>
<a href="#许可说明">
<img alt="License: Apache2.0" src="https://img.shields.io/badge/license-Apache%202.0-blue.svg"/>
</a>
**中文 | [English](./README.md)**
<img src="./imgs/poster.gif" width="696px">
</div>
## 目录
- [关键](#特色---我们为什么是独一无二的)
- [任务](#任务)
- [3D车道线检测🛣️](#3d车道线检测-%EF%B8%8F)
- [交通标志检测🚥](#交通标志检测-)
- [拓扑认知🕸️](#拓扑认知-%EF%B8%8F)
- [信息发布](#信息发布)
- [数据](#数据)
- [开发工具](#开发工具)
- [入门指南](#入门指南)
- [训练模型](#训练模型)
- [基准和排行榜](#基准和排行榜)
- [引用](#引用)
- [许可说明](#许可说明)
## 特色 - 我们为什么是独一无二的?
### 三维场景,3D车道
道路环境需要怎样的建模才能满足车辆自动驾驶功能的需求?
以往的数据集一般都在2D图像上标注车道,但在实际应用中,由于缺乏高度信息,2D车道数据无法支持车辆在上下坡、路面不平整等场景行驶,因此**3D车道**数据是不可或缺的。
同我们之前的工作 [OpenLane](https://github.com/OpenDriveLab/OpenLane) 一致,OpenLane-Huawei 提供三维车道标注。
### 关注交通要素,确保行车规范
在道路上平稳的行驶只是第一步,驾驶汽车还需要遵循环境中的**交通要素**(交通灯,路标)信息指示,确保不违反当地交通法规,因此 OpenLane-Huawei 也提供了2D交通要素标注。
交通要素在2D图像上尺寸大多都较小,检测领域中小目标检测一直是个热点,这也是该基准的挑战之一。
### 拓扑关系支撑场景结构化
环境中交通要素应仅对其特定的车道有指示作用,遵循错误的信号将造成灾难性的后果,因此需要明确车道与交通要素的关系。环境中的车道也不应是割裂存在的,车道与车道的关系也同样重要。
OpenLane-Huawei 提供车道与车道、车道与交通要素之间的拓扑关系,打造结构化场景。
自动驾驶汽车需要通过**推理**捕捉正确的**拓扑关系**以正确的方式行驶。
我们希望这个数据集的建立可以促进**道路场景感知和推理**任务的发展。
### 多元大规模数据,搭建超赞数据集
对于机器学习任务,数据是必备的基石。
我们提供从奥斯汀到新加坡,从波士顿到迈阿密等各个城市收集的数据的标注,
支撑数据的**多元性**
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 任务
数据集的首要任务是**场景结构感知和推理**,这需要模型能够识别周围环境中车道的可行驶状态。
该数据集的任务不仅包括车道中心线和交通要素检测,还包括检测到的对象的拓扑关系识别。
我们定义了[**OpenLane-V2 Score (OLS)**](./docs/metrics.md#openlane-v2-score),该指标为各个子任务指标的平均值:
$$
\text{OLS} = \frac{1}{4} \bigg[ \text{DET}_{l} + \text{DET}_{t} + f(\text{TOP}_{ll}) + f(\text{TOP}_{lt}) \bigg].
$$
子任务的指标如下所述:
### 3D车道线检测 🛣️
[OpenLane](https://github.com/OpenDriveLab/OpenLane) 数据集是迄今为止第一个真实世界和规模最大的 3D 车道数据集,提供 3D 空间下的车道线标注。
在OpenLane基础上,我们将 3D 车道检测的任务定义如下:从覆盖整个水平 FOV(视场角-Field Of View) 的多视图中检测带方向的 3D 车道中心线。
用平均精度 $mAP_{LC}$ 指标评估车道中心线的检测性能。
<p align="center">
<img src="./imgs/lane.gif" width="696px" >
</p>
### 交通标志检测 🚥
现有的数据集很少关注交通标志的检测及其语义,但是交通标志是自动驾驶汽车中关键信息。
该属性表示交通要素的语义,例如交通灯的红色。
在这个子任务中,在给定的前视图图像上,要求同时感知交通要素(交通灯和路标)的位置及其属性。
与典型的 2D 检测数据集相比,挑战在于由于室外环境的大规模,交通要素的尺寸很小。
与典型的多分类 2D 检测任务类似, $mAP_{TE}$ 用于衡量交通要素 (TE)综合的检测性能。
<p align="center">
<img src="./imgs/traffic_element.gif" width="696px" >
</p>
### 拓扑认知 🕸️
我们首先定义在自动驾驶领域识别拓扑关系的任务。
给定多视图图像,该模型学习识别车道中心线之间以及车道中心线与交通要素之间的拓扑关系。
最相似的任务是图领域的连通性预测,其中顶点是给定的,模型只预测边。
在我们的例子中,模型的顶点和边都是未知的。
因此,首先需要检测车道中心线和交通要素,然后建立拓扑关系。
参照连通性预测任务,
我们用 $mAP_{LCLC}$ 评估车道中心线(LCLC)之间的拓扑表现,
用 $mAP_{LCTE}$ 评估车道中心线和交通要素(LCTE)之间的拓扑表现。
<p align="center">
<img src="./imgs/topology.gif" width="696px" >
</p>
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 信息发布
- [2023/02]
* 数据集 `v1.0`: `subset_A` 数据发布。
* 基模型发布。
- [2023/01]
* 数据集 `v0.1`: OpenLane-Huawei 数据集样本发布。
* 开发工具 `v0.1.0`: OpenLane-Huawei 开发工具发布。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 数据
OpenLane-Huawei 数据集是自动驾驶领域用于道路结构感知和推理的大规模数据集。
[OpenLane](https://github.com/OpenDriveLab/OpenLane) 数据集一致,我们提供三维空间中的车道真值。与之有区别的是,OpenLane-Huawei 提供的是车道中心线的3D标注,而OpenLane提供的是车道分割线3D标注。此外,我们还提供了交通标志(交通灯和路标)及其属性的2D框标注,和车道中心线之间以及车道中心线与交通要素之间的拓扑关系标注。
数据集分为两个子集。
**`subset_A`作为主要子集,服务于即将到来的比赛和排行榜,比赛中不允许任何外部数据,包括本数据集其他子集**
`subset_B`可以用来测试模型的泛化能力。
更多信息请参考对应的页面:[使用数据](./data/README.md)[标注文档](./docs/annotation.md)[数据统计](./docs/statistics.md)
现在就[下载](./data/README.md#download)我们的数据集来发现更多!
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 开发工具
我们提供了一个开发工具来方便社区熟悉并使用 OpenLane-Huawei 数据集。
可以通过 `openlanv2` 的API实现数据集的使用,例如加载图像、加载元数据和评估结果。
更多开发工具信息请参考[开发工具](./docs/devkit.md)
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 入门指南
按照以下步骤熟悉 OpenLane-Huawei 数据集:
1. 运行以下命令安装必要的工具包,完成研究环境准备:
```sh
git clone https://github.com/OpenDriveLab/OpenLane-V2.git
cd OpenLane-V2
conda create -n openlanev2 python=3.8 -y
conda activate openlanev2
pip install -r requirements.txt
python setup.py develop
```
2. 点击[链接](./data/README.md#download)从合适的渠道下载数据:
- <img src="https://user-images.githubusercontent.com/29263416/222076048-21501bac-71df-40fa-8671-2b5f8013d2cd.png" alt="OpenDataLab" width="18"/> OpenDataLab,
- <img src="https://ssl.gstatic.com/docs/doclist/images/drive_2022q3_32dp.png" alt="Google Drive" width="18"/> Google Drive,
- <img src="https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico" alt="百度云" width="18"/> 百度云。
并将它们移动至 `data/OpenLane-V2/` 文件夹下解压。
生成的目录结构应[如下](./data/README.md#hierarchy)所示。
或者用这些命令来下载数据集样本:
```sh
cd data/OpenLane-V2
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6" -O OpenLane-V2_sample.tar
md5sum -c openlanev2.md5
tar -xvf *.tar
cd ../..
```
3. 在 jupyter notebook 上运行 [tutorial](./tutorial.ipynb) 来熟悉数据集与对应的开发工具。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 训练模型
我们提供不同神经网络训练框架的插件来支持在我们的数据集上训练模型。
如果缺少你常用的训练框架,我们欢迎你的提议或对插件的共同维护。
### mmdet3d
这个[插件](./plugin/mmdet3d/)基于 [mmdet3d v1.0.0rc6](https://github.com/open-mmlab/mmdetection3d/tree/v1.0.0rc6),并且在以下的环境中进行过测试:
- Python 3.8.15
- PyTorch 1.9.1
- CUDA 11.1
- GCC 5.4.0
- mmcv-full==1.5.2
- mmdet==2.26.0
- mmsegmentation==0.29.1
请按照 mmdet3d 的[指引](https://github.com/open-mmlab/mmdetection3d/blob/v1.0.0rc6/docs/en/getting_started.md)来安装这个训练框架。
假设这个数据集安装在 `OpenLane-V2/` 目录下,并且 mmdet3d 安装在 `mmdetection3d/` 目录下,你可以通过软连接的方式将该插件引入到训练框架中:
```
└── mmdetection3d
└── projects
├── example_project
└── openlanev2 -> OpenLane-V2/plugin/mmdet3d
```
在将数据路径换成你的本地路径之后,你可以使用我们提供的 config 文件 `mmdetection3d/projects/openlanev2/configs/baseline.py` 来进行模型训练和各种 mmdet3d 中支持的操作。
并且可以通过在对模型进行推理时输入不同的选项来获取不同的功能,已经实现的功能有:`--eval-options dump=True dump_dir=/PATH/TO/DUMP` 来存储用于上传测试集结果的文件;`--eval-options visualization=True visualization_dir=/PATH/TO/VIS` 来对模型输出进行可视化。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 基准和排行榜
我们将提供 OpenLane-Huawei 数据集的初始基准测试,欢迎您在这里添加您的工作!
基准和排行榜将在不久后发布,请持续关注。
| Method | OLS (main metric) (%) | $mAP_{LC}$ (%) | $mAP_{TE}$ (%) | $mAP_{LCLC}$ (%) | $mAP_{LCTE}$ (%) | F-Score* (%) |
| - | - | - | - | - | - | - |
| Baseline | 0.29 | 0.08 | 0.31 | 0.00 | 0.01 | 8.56 |
<sub>*在比赛和排行榜中不考虑车道中心线检测的 F-Score。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 引用
使用 OpenLane-Huawei 时请使用如下引用:
```bibtex
@misc{ openlanev2_dataset,
author = {{OpenLane-V2 Dataset Contributors}},
title = {{OpenLane-V2: The World's First Perception and Reasoning Benchmark for Scene Structure in Autonomous Driving}},
url = {https://github.com/OpenDriveLab/OpenLane-V2},
license = {Apache-2.0},
year = {2023}
}
```
我们的数据集是基于[NuScenes](https://www.nuscenes.org/nuscenes)[Argoverse](https://www.argoverse.org/av2.html)数据集工作拓展而来。如果引用本作,也请使用如下引用:
```bibtex
@article{ nuscenes2019,
author = {Holger Caesar and Varun Bankiti and Alex H. Lang and Sourabh Vora and Venice Erin Liong and Qiang Xu and Anush Krishnan and Yu Pan and Giancarlo Baldan and Oscar Beijbom},
title = {nuScenes: A multimodal dataset for autonomous driving},
journal = {arXiv preprint arXiv:1903.11027},
year = {2019}
}
@INPROCEEDINGS { Argoverse2,
author = {Benjamin Wilson and William Qi and Tanmay Agarwal and John Lambert and Jagjeet Singh and Siddhesh Khandelwal and Bowen Pan and Ratnesh Kumar and Andrew Hartnett and Jhony Kaesemodel Pontes and Deva Ramanan and Peter Carr and James Hays},
title = {Argoverse 2: Next Generation Datasets for Self-driving Perception and Forecasting},
booktitle = {Proceedings of the Neural Information Processing Systems Track on Datasets and Benchmarks (NeurIPS Datasets and Benchmarks 2021)},
year = {2021}
}
```
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 许可说明
使用 OpenLane-Huawei 数据集时,您需要在网站上注册并同意 [nuScenes](https://www.nuscenes.org/nuscenes)[Argoverse 2](https://www.argoverse.org/av2.html) 数据集的使用条款。
本项目的发布受 [Apache License 2.0](./LICENSE)许可认证。
<p align="right">(<a href="#top">回到顶部</a>)</p>
<div id="top" align="center">
# OpenLane-Huawei
**全球首个自动驾驶道路结构感知和推理基准。**
<a href="#数据">
<img alt="OpenLane-v2: v1.0" src="https://img.shields.io/badge/OpenLane--V2-v1.0-blueviolet"/>
</a>
<a href="#开发工具">
<img alt="devkit: v0.1.0" src="https://img.shields.io/badge/devkit-v0.1.0-blueviolet"/>
</a>
<a href="#许可说明">
<img alt="License: Apache2.0" src="https://img.shields.io/badge/license-Apache%202.0-blue.svg"/>
</a>
**中文 | [English](./README.md)**
<img src="./imgs/poster.gif" width="696px">
</div>
## 目录
- [关键](#特色---我们为什么是独一无二的)
- [任务](#任务)
- [3D车道线检测🛣️](#3d车道线检测-%EF%B8%8F)
- [交通标志检测🚥](#交通标志检测-)
- [拓扑认知🕸️](#拓扑认知-%EF%B8%8F)
- [信息发布](#信息发布)
- [数据](#数据)
- [开发工具](#开发工具)
- [入门指南](#入门指南)
- [训练模型](#训练模型)
- [基准和排行榜](#基准和排行榜)
- [引用](#引用)
- [许可说明](#许可说明)
## 特色 - 我们为什么是独一无二的?
### 三维场景,3D车道
道路环境需要怎样的建模才能满足车辆自动驾驶功能的需求?
以往的数据集一般都在2D图像上标注车道,但在实际应用中,由于缺乏高度信息,2D车道数据无法支持车辆在上下坡、路面不平整等场景行驶,因此**3D车道**数据是不可或缺的。
同我们之前的工作 [OpenLane](https://github.com/OpenDriveLab/OpenLane) 一致,OpenLane-Huawei 提供三维车道标注。
### 关注交通要素,确保行车规范
在道路上平稳的行驶只是第一步,驾驶汽车还需要遵循环境中的**交通要素**(交通灯,路标)信息指示,确保不违反当地交通法规,因此 OpenLane-Huawei 也提供了2D交通要素标注。
交通要素在2D图像上尺寸大多都较小,检测领域中小目标检测一直是个热点,这也是该基准的挑战之一。
### 拓扑关系支撑场景结构化
环境中交通要素应仅对其特定的车道有指示作用,遵循错误的信号将造成灾难性的后果,因此需要明确车道与交通要素的关系。环境中的车道也不应是割裂存在的,车道与车道的关系也同样重要。
OpenLane-Huawei 提供车道与车道、车道与交通要素之间的拓扑关系,打造结构化场景。
自动驾驶汽车需要通过**推理**捕捉正确的**拓扑关系**以正确的方式行驶。 我们希望这个数据集的建立可以促进**道路场景感知和推理**任务的发展。
### 多元大规模数据,搭建超赞数据集
对于机器学习任务,数据是必备的基石。 我们提供从奥斯汀到新加坡,从波士顿到迈阿密等各个城市收集的数据的标注, 支撑数据的**多元性**
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 任务
数据集的首要任务是**场景结构感知和推理**,这需要模型能够识别周围环境中车道的可行驶状态。 该数据集的任务不仅包括车道中心线和交通要素检测,还包括检测到的对象的拓扑关系识别。 我们定义了[**OpenLane-V2 Score (
OLS)**](./docs/metrics.md#openlane-v2-score),该指标为各个子任务指标的平均值:
$$ \\text{OLS} = \\frac{1}{4} \\bigg\[ \\text{DET}_{l} + \\text{DET}_{t} + f(\\text{TOP}_{ll}) + f(\\text{TOP}_{lt})
\\bigg\]. $$
子任务的指标如下所述:
### 3D车道线检测 🛣️
[OpenLane](https://github.com/OpenDriveLab/OpenLane) 数据集是迄今为止第一个真实世界和规模最大的 3D 车道数据集,提供 3D 空间下的车道线标注。 在OpenLane基础上,我们将 3D
车道检测的任务定义如下:从覆盖整个水平 FOV(视场角-Field Of View) 的多视图中检测带方向的 3D 车道中心线。 用平均精度 $mAP\_{LC}$ 指标评估车道中心线的检测性能。
<p align="center">
<img src="./imgs/lane.gif" width="696px" >
</p>
### 交通标志检测 🚥
现有的数据集很少关注交通标志的检测及其语义,但是交通标志是自动驾驶汽车中关键信息。 该属性表示交通要素的语义,例如交通灯的红色。 在这个子任务中,在给定的前视图图像上,要求同时感知交通要素(交通灯和路标)的位置及其属性。 与典型的 2D
检测数据集相比,挑战在于由于室外环境的大规模,交通要素的尺寸很小。 与典型的多分类 2D 检测任务类似, $mAP\_{TE}$ 用于衡量交通要素 (TE)综合的检测性能。
<p align="center">
<img src="./imgs/traffic_element.gif" width="696px" >
</p>
### 拓扑认知 🕸️
我们首先定义在自动驾驶领域识别拓扑关系的任务。 给定多视图图像,该模型学习识别车道中心线之间以及车道中心线与交通要素之间的拓扑关系。 最相似的任务是图领域的连通性预测,其中顶点是给定的,模型只预测边。
在我们的例子中,模型的顶点和边都是未知的。 因此,首先需要检测车道中心线和交通要素,然后建立拓扑关系。 参照连通性预测任务, 我们用 $mAP\_{LCLC}$ 评估车道中心线(LCLC)之间的拓扑表现, 用 $mAP\_{LCTE}$
评估车道中心线和交通要素(LCTE)之间的拓扑表现。
<p align="center">
<img src="./imgs/topology.gif" width="696px" >
</p>
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 信息发布
- \[2023/02\]
- 数据集 `v1.0`: `subset_A` 数据发布。
- 基模型发布。
- \[2023/01\]
- 数据集 `v0.1`: OpenLane-Huawei 数据集样本发布。
- 开发工具 `v0.1.0`: OpenLane-Huawei 开发工具发布。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 数据
OpenLane-Huawei 数据集是自动驾驶领域用于道路结构感知和推理的大规模数据集。 与 [OpenLane](https://github.com/OpenDriveLab/OpenLane)
数据集一致,我们提供三维空间中的车道真值。与之有区别的是,OpenLane-Huawei 提供的是车道中心线的3D标注,而OpenLane提供的是车道分割线3D标注。此外,我们还提供了交通标志(交通灯和路标)
及其属性的2D框标注,和车道中心线之间以及车道中心线与交通要素之间的拓扑关系标注。
数据集分为两个子集。
**`subset_A`作为主要子集,服务于即将到来的比赛和排行榜,比赛中不允许任何外部数据,包括本数据集其他子集**
`subset_B`可以用来测试模型的泛化能力。 更多信息请参考对应的页面:[使用数据](./data/README.md)[标注文档](./docs/annotation.md)[数据统计](./docs/statistics.md)
现在就[下载](./data/README.md#download)我们的数据集来发现更多!
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 开发工具
我们提供了一个开发工具来方便社区熟悉并使用 OpenLane-Huawei 数据集。 可以通过 `openlanv2` 的API实现数据集的使用,例如加载图像、加载元数据和评估结果。
更多开发工具信息请参考[开发工具](./docs/devkit.md)
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 入门指南
按照以下步骤熟悉 OpenLane-Huawei 数据集:
1. 运行以下命令安装必要的工具包,完成研究环境准备:
```sh
git clone https://github.com/OpenDriveLab/OpenLane-V2.git
cd OpenLane-V2
conda create -n openlanev2 python=3.8 -y
conda activate openlanev2
pip install -r requirements.txt
python setup.py develop
```
2. 点击[链接](./data/README.md#download)从合适的渠道下载数据:
- <img src="https://user-images.githubusercontent.com/29263416/222076048-21501bac-71df-40fa-8671-2b5f8013d2cd.png" alt="OpenDataLab" width="18"/> OpenDataLab,
- <img src="https://ssl.gstatic.com/docs/doclist/images/drive_2022q3_32dp.png" alt="Google Drive" width="18"/> Google Drive,
- <img src="https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico" alt="百度云" width="18"/> 百度云。
并将它们移动至 `data/OpenLane-V2/` 文件夹下解压。 生成的目录结构应[如下](./data/README.md#hierarchy)所示。 或者用这些命令来下载数据集样本:
```sh
cd data/OpenLane-V2
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6" -O OpenLane-V2_sample.tar
md5sum -c openlanev2.md5
tar -xvf *.tar
cd ../..
```
3. 在 jupyter notebook 上运行 [tutorial](./tutorial.ipynb) 来熟悉数据集与对应的开发工具。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 训练模型
我们提供不同神经网络训练框架的插件来支持在我们的数据集上训练模型。 如果缺少你常用的训练框架,我们欢迎你的提议或对插件的共同维护。
### mmdet3d
这个[插件](./plugin/mmdet3d/)
基于 [mmdet3d v1.0.0rc6](https://github.com/open-mmlab/mmdetection3d/tree/v1.0.0rc6),并且在以下的环境中进行过测试:
- Python 3.8.15
- PyTorch 1.9.1
- CUDA 11.1
- GCC 5.4.0
- mmcv-full==1.5.2
- mmdet==2.26.0
- mmsegmentation==0.29.1
请按照 mmdet3d 的[指引](https://github.com/open-mmlab/mmdetection3d/blob/v1.0.0rc6/docs/en/getting_started.md)来安装这个训练框架。
假设这个数据集安装在 `OpenLane-V2/` 目录下,并且 mmdet3d 安装在 `mmdetection3d/` 目录下,你可以通过软连接的方式将该插件引入到训练框架中:
```
└── mmdetection3d
└── projects
├── example_project
└── openlanev2 -> OpenLane-V2/plugin/mmdet3d
```
在将数据路径换成你的本地路径之后,你可以使用我们提供的 config 文件 `mmdetection3d/projects/openlanev2/configs/baseline.py` 来进行模型训练和各种 mmdet3d 中支持的操作。
并且可以通过在对模型进行推理时输入不同的选项来获取不同的功能,已经实现的功能有:`--eval-options dump=True dump_dir=/PATH/TO/DUMP`
来存储用于上传测试集结果的文件;`--eval-options visualization=True visualization_dir=/PATH/TO/VIS` 来对模型输出进行可视化。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 基准和排行榜
我们将提供 OpenLane-Huawei 数据集的初始基准测试,欢迎您在这里添加您的工作!
基准和排行榜将在不久后发布,请持续关注。
| Method | OLS (main metric) (%) | $mAP\_{LC}$ (%) | $mAP\_{TE}$ (%) | $mAP\_{LCLC}$ (%) | $mAP\_{LCTE}$ (%) | F-Score\* (%) |
| -------- | --------------------- | --------------- | --------------- | ----------------- | ----------------- | ------------- |
| Baseline | 0.29 | 0.08 | 0.31 | 0.00 | 0.01 | 8.56 |
<sub>\*在比赛和排行榜中不考虑车道中心线检测的 F-Score。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 引用
使用 OpenLane-Huawei 时请使用如下引用:
```bibtex
@misc{ openlanev2_dataset,
author = {{OpenLane-V2 Dataset Contributors}},
title = {{OpenLane-V2: The World's First Perception and Reasoning Benchmark for Scene Structure in Autonomous Driving}},
url = {https://github.com/OpenDriveLab/OpenLane-V2},
license = {Apache-2.0},
year = {2023}
}
```
我们的数据集是基于[NuScenes](https://www.nuscenes.org/nuscenes)
[Argoverse](https://www.argoverse.org/av2.html)数据集工作拓展而来。如果引用本作,也请使用如下引用:
```bibtex
@article{ nuscenes2019,
author = {Holger Caesar and Varun Bankiti and Alex H. Lang and Sourabh Vora and Venice Erin Liong and Qiang Xu and Anush Krishnan and Yu Pan and Giancarlo Baldan and Oscar Beijbom},
title = {nuScenes: A multimodal dataset for autonomous driving},
journal = {arXiv preprint arXiv:1903.11027},
year = {2019}
}
@INPROCEEDINGS { Argoverse2,
author = {Benjamin Wilson and William Qi and Tanmay Agarwal and John Lambert and Jagjeet Singh and Siddhesh Khandelwal and Bowen Pan and Ratnesh Kumar and Andrew Hartnett and Jhony Kaesemodel Pontes and Deva Ramanan and Peter Carr and James Hays},
title = {Argoverse 2: Next Generation Datasets for Self-driving Perception and Forecasting},
booktitle = {Proceedings of the Neural Information Processing Systems Track on Datasets and Benchmarks (NeurIPS Datasets and Benchmarks 2021)},
year = {2021}
}
```
<p align="right">(<a href="#top">回到顶部</a>)</p>
## 许可说明
使用 OpenLane-Huawei 数据集时,您需要在网站上注册并同意 [nuScenes](https://www.nuscenes.org/nuscenes)
[Argoverse 2](https://www.argoverse.org/av2.html) 数据集的使用条款。
本项目的发布受 [Apache License 2.0](./LICENSE)许可认证。
<p align="right">(<a href="#top">回到顶部</a>)</p>
## InternImage-based Baseline for CVPR23 OpenLane-V2 Challenge!!!!
We improve our baseline with a more powerful image backbone: **InternImage**, which shows its excellent ability within a series of leaderboards and benchmarks, such as *COCO* and *nuScenes*.
We improve our baseline with a more powerful image backbone: **InternImage**, which shows its excellent ability within a
series of leaderboards and benchmarks, such as *COCO* and *nuScenes*.
#### 1. Requirements
```bash
python>=3.8
torch==1.11
......@@ -13,8 +14,8 @@ mmsegmentation==0.29.1
timm
```
### 2. Install DCNv3 for InternImage
```bash
cd plugin/mmdet3d/baseline/models/backbones/ops_dcnv3
bash make.sh
......@@ -28,11 +29,10 @@ bash make.sh
Notes: InternImage provides abundant pre-trained model weights that can be used!!!
### 4. Performance compared to baseline
| | OpenLane-V2 Score | DET<sub>l</sub> | DET<sub>t</sub> | TOP<sub>ll</sub> | TOP<sub>lt</sub> | F-Score |
|-------------|-------------------|-----------------|-----------------|------------------|------------------|---------|
| ----------- | ----------------- | --------------- | --------------- | ---------------- | ---------------- | ------- |
| base r50 | 0.292 | 0.183 | 0.457 | 0.022 | 0.143 | 0.215 |
| InternImage | 0.325 | 0.194 | 0.537 | 0.02 | 0.17 | 0.224 |
......@@ -40,12 +40,14 @@ Notes: InternImage provides abundant pre-trained model weights that can be used!
InternImage-S: [download](https://drive.google.com/file/d/1PsyVOEkCdo-q-jxeDKGRjw28_kWWm1d1/view?usp=sharing)
## Leaderboard
## Leaderboard
To be released.
<div id="top" align="center">
# OpenLane-V2
**The World's First Perception and Reasoning Benchmark for Scene Structure in Autonomous Driving.**
<a href="#data">
......@@ -62,7 +64,6 @@ To be released.
_In terms of ambiguity, the English version shall prevail._
<img src="./imgs/poster.gif" width="696px">
</div>
......@@ -72,6 +73,7 @@ _In terms of ambiguity, the English version shall prevail._
> The dataset name OpenLane-V2, is termed as **RoadGenome** at Huawei.
## Table of Contents
- [News](#news)
- [Benchmark and Leaderboard](#benchmark-and-leaderboard)
- [Highlight](#highlight---why-we-are-exclusive)
......@@ -87,90 +89,106 @@ _In terms of ambiguity, the English version shall prevail._
- [License](#license)
## News
- [2023/03]
* We are hosting a Challenge at the [CVPR 2023 Workshop](https://opendrivelab.com/AD23Challenge.html) :star:.
- [2023/02]
* Dataset `v1.0`: Data of `subset_A` released.
* Baseline model released.
- [2023/01]
* Dataset `v0.1`: Initial OpenLane-V2 dataset sample released.
* Devkit `v0.1.0`: Initial OpenLane-V2 devkit released.
- \[2023/03\]
- We are hosting a Challenge at the [CVPR 2023 Workshop](https://opendrivelab.com/AD23Challenge.html) :star:.
- \[2023/02\]
- Dataset `v1.0`: Data of `subset_A` released.
- Baseline model released.
- \[2023/01\]
- Dataset `v0.1`: Initial OpenLane-V2 dataset sample released.
- Devkit `v0.1.0`: Initial OpenLane-V2 devkit released.
<p align="right">(<a href="#top">back to top</a>)</p>
## Benchmark and Leaderboard
We will provide an initial benchmark on the OpenLane-V2 dataset, please stay tuned for the release.
Currently, we are maintaining leaderboards on the [*val*](https://paperswithcode.com/sota/3d-lane-detection-on-openlane-v2-2) and [*test*](https://eval.ai/web/challenges/challenge-page/1925/leaderboard/4549) split of `subset_A`.
We will provide an initial benchmark on the OpenLane-V2 dataset, please stay tuned for the release.
Currently, we are maintaining leaderboards on the [\*
val\*](https://paperswithcode.com/sota/3d-lane-detection-on-openlane-v2-2) and [\*
test\*](https://eval.ai/web/challenges/challenge-page/1925/leaderboard/4549) split of `subset_A`.
<p align="right">(<a href="#top">back to top</a>)</p>
## Highlight - why we are exclusive?
### The world is three-dimensional - Introducing 3D lane
Previous datasets annotate lanes on images in the perspective view. Such a type of 2D annotation is insufficient to fulfill real-world requirements.
Following the [OpenLane](https://github.com/OpenDriveLab/OpenLane) dataset, we annotate **lanes in 3D space** to reflect their properties in the real world.
Previous datasets annotate lanes on images in the perspective view. Such a type of 2D annotation is insufficient to
fulfill real-world requirements. Following the [OpenLane](https://github.com/OpenDriveLab/OpenLane) dataset, we
annotate **lanes in 3D space** to reflect their properties in the real world.
### Be aware of traffic signals - Recognizing Extremely Small road elements
Not only preventing collision but also facilitating efficiency is essential.
Vehicles follow predefined traffic rules for self-disciplining and cooperating with others to ensure a safe and efficient traffic system.
Not only preventing collision but also facilitating efficiency is essential. Vehicles follow predefined traffic rules
for self-disciplining and cooperating with others to ensure a safe and efficient traffic system.
**Traffic elements** on the roads, such as traffic lights and road signs, provide practical and real-time information.
### Beyond perception - Topology Reasoning between lane and road elements
A traffic element is only valid for its corresponding lanes.
Following the wrong signals would be catastrophic.
Also, lanes have their predecessors and successors to build the map.
Autonomous vehicles are required to **reason** about the **topology relationships** to drive in the right way.
In this dataset, we hope to shed light on the task of **scene structure perception and reasoning**.
### Beyond perception - Topology Reasoning between lane and road elements
A traffic element is only valid for its corresponding lanes. Following the wrong signals would be catastrophic. Also,
lanes have their predecessors and successors to build the map. Autonomous vehicles are required to **reason** about
the **topology relationships** to drive in the right way. In this dataset, we hope to shed light on the task of **scene
structure perception and reasoning**.
### Data scale and diversity matters - building on Top of Awesome Benchmarks
Experience from the sunny day does not apply to the dancing snowflakes.
For machine learning, data is the must-have food.
We provide annotations on data collected in various cities, from Austin to Singapore and from Boston to Miami.
Experience from the sunny day does not apply to the dancing snowflakes. For machine learning, data is the must-have
food. We provide annotations on data collected in various cities, from Austin to Singapore and from Boston to Miami.
The **diversity** of data enables models to generalize in different atmospheres and landscapes.
<p align="right">(<a href="#top">back to top</a>)</p>
## Task
The primary task of the dataset is **scene structure perception and reasoning**, which requires the model to recognize the dynamic drivable states of lanes in the surrounding environment.
The challenge of this dataset includes not only detecting lane centerlines and traffic elements but also recognizing the attribute of traffic elements and topology relationships on detected objects.
We define the **[OpenLane-V2 Score (OLS)](./docs/metrics.md#openlane-v2-score)**, which is the average of various metrics covering different aspects of the primary task:
$$
\text{OLS} = \frac{1}{4} \bigg[ \text{DET}_{l} + \text{DET}_{t} + f(\text{TOP}_{ll}) + f(\text{TOP}_{lt}) \bigg].
$$
The primary task of the dataset is **scene structure perception and reasoning**, which requires the model to recognize
the dynamic drivable states of lanes in the surrounding environment. The challenge of this dataset includes not only
detecting lane centerlines and traffic elements but also recognizing the attribute of traffic elements and topology
relationships on detected objects. We define the **[OpenLane-V2 Score (OLS)](./docs/metrics.md#openlane-v2-score)**,
which is the average of various metrics covering different aspects of the primary task:
$$ \\text{OLS} = \\frac{1}{4} \\bigg\[ \\text{DET}_{l} + \\text{DET}_{t} + f(\\text{TOP}_{ll}) + f(\\text{TOP}_{lt})
\\bigg\]. $$
The metrics of different subtasks are described below.
### 3D Lane Detection 🛣️
The [OpenLane](https://github.com/OpenDriveLab/OpenLane) dataset, which is the first real-world and the largest scaled 3D lane dataset to date, provides lane line annotations in 3D space.
Similarly, we annotate 3D lane centerlines and include the F-Score for evaluating predicted results of undirected lane centerlines.
Furthermore, we define the subtask of 3D lane detection as detecting directed 3D lane centerlines from the given multi-view images covering the whole horizontal FOV.
The instance-level evaluation metric of average precision $\text{DET}_{l}$ is utilized to measure the detection performance on lane centerlines (l).
The [OpenLane](https://github.com/OpenDriveLab/OpenLane) dataset, which is the first real-world and the largest scaled
3D lane dataset to date, provides lane line annotations in 3D space. Similarly, we annotate 3D lane centerlines and
include the F-Score for evaluating predicted results of undirected lane centerlines. Furthermore, we define the subtask
of 3D lane detection as detecting directed 3D lane centerlines from the given multi-view images covering the whole
horizontal FOV. The instance-level evaluation metric of average precision $\\text{DET}\_{l}$ is utilized to measure the
detection performance on lane centerlines (l).
<p align="center">
<img src="./imgs/lane.gif" width="696px" >
</p>
### Traffic Element Recognition 🚥
Traffic elements and their attribute provide crucial information for autonomous vehicles.
The attribute represents the semantic meaning of a traffic element, such as the red color of a traffic light.
In this subtask, on the given image in the front view, the location of traffic elements (traffic lights and road signs) and their attributes are demanded to be perceived simultaneously.
Compared to typical 2D detection datasets, the challenge is that the size of traffic elements is tiny due to the large scale of outdoor environments.
Similar to the typical 2D detection task, the metric of $\text{DET}_{t}$ is utilized to measure the performance of traffic elements (t) detection averaged over different attributes.
Traffic elements and their attribute provide crucial information for autonomous vehicles. The attribute represents the
semantic meaning of a traffic element, such as the red color of a traffic light. In this subtask, on the given image in
the front view, the location of traffic elements (traffic lights and road signs) and their attributes are demanded to be
perceived simultaneously. Compared to typical 2D detection datasets, the challenge is that the size of traffic elements
is tiny due to the large scale of outdoor environments. Similar to the typical 2D detection task, the metric of
$\\text{DET}\_{t}$ is utilized to measure the performance of traffic elements (t) detection averaged over different
attributes.
<p align="center">
<img src="./imgs/traffic_element.gif" width="696px" >
</p>
### Topology Recognition 🕸️
We first define the task of recognizing topology relationships in the field of autonomous driving.
Given multi-view images, the model learns to recognize the topology relationships among lane centerlines and between lane centerlines and traffic elements.
The most similar task is link prediction in the field of graph, in which the vertices are given and only edges are predicted by models.
In our case, both vertices and edges are unknown for the model.
Thus, lane centerlines and traffic elements are needed to be detected first, and then the topology relationships are built.
Adapted from the task of link prediction, $\text{TOP}$ is used for topology among lane centerlines (ll) and between lane centerlines and traffic elements (lt).
We first define the task of recognizing topology relationships in the field of autonomous driving. Given multi-view
images, the model learns to recognize the topology relationships among lane centerlines and between lane centerlines and
traffic elements. The most similar task is link prediction in the field of graph, in which the vertices are given and
only edges are predicted by models. In our case, both vertices and edges are unknown for the model. Thus, lane
centerlines and traffic elements are needed to be detected first, and then the topology relationships are built. Adapted
from the task of link prediction, $\\text{TOP}$ is used for topology among lane centerlines (ll) and between lane
centerlines and traffic elements (lt).
<p align="center">
<img src="./imgs/topology.gif" width="696px" >
......@@ -179,72 +197,79 @@ Adapted from the task of link prediction, $\text{TOP}$ is used for topology amon
<p align="right">(<a href="#top">back to top</a>)</p>
## Data
The OpenLane-V2 dataset is a large-scale dataset for scene structure perception and reasoning in the field of autonomous driving.
Following [OpenLane](https://github.com/OpenDriveLab/OpenLane), the first 3D lane dataset, we provide lane annotations in 3D space.
The difference is that instead of lane lines, we annotate lane centerlines, which can be served as the trajectory for autonomous vehicles.
Besides, we provide annotations on traffic elements (traffic lights and road signs) and their attribute, and the topology relationships among lane centerlines and between lane centerlines and traffic elements.
The dataset is divided into two subsets.
**The `subset_A` serves as the primary subset and is utilized for the coming challenges and leaderboard, in which no external data, including the other subset, is allowed**.
The `subset_B` can be used to test the generalization ability of the model.
For more details, please refer to the corresponding pages: [use of data](./data/README.md), [notes of annotation](./docs/annotation.md), and [dataset statistics](./docs/statistics.md).
The OpenLane-V2 dataset is a large-scale dataset for scene structure perception and reasoning in the field of autonomous
driving. Following [OpenLane](https://github.com/OpenDriveLab/OpenLane), the first 3D lane dataset, we provide lane
annotations in 3D space. The difference is that instead of lane lines, we annotate lane centerlines, which can be served
as the trajectory for autonomous vehicles. Besides, we provide annotations on traffic elements (traffic lights and road
signs) and their attribute, and the topology relationships among lane centerlines and between lane centerlines and
traffic elements.
The dataset is divided into two subsets.
**The `subset_A` serves as the primary subset and is utilized for the coming challenges and leaderboard, in which no
external data, including the other subset, is allowed**. The `subset_B` can be used to test the generalization ability
of the model. For more details, please refer to the corresponding pages: [use of data](./data/README.md)
, [notes of annotation](./docs/annotation.md), and [dataset statistics](./docs/statistics.md).
[Download](./data/README.md#download) now to discover our dataset!
<p align="right">(<a href="#top">back to top</a>)</p>
## Devkit
We provide a devkit for easy access to the OpenLane-V2 dataset.
After installing the package, the use of the dataset, such as loading images, loading meta data, and evaluating results, can be accessed through the API of `openlanv2`.
For more details on the API, please refer to [devkit](./docs/devkit.md).
<p align="right">(<a href="#top">back to top</a>)</p>
We provide a devkit for easy access to the OpenLane-V2 dataset. After installing the package, the use of the dataset,
such as loading images, loading meta data, and evaluating results, can be accessed through the API of `openlanv2`. For
more details on the API, please refer to [devkit](./docs/devkit.md).
<p align="right">(<a href="#top">back to top</a>)</p>
## Get Started
Please follow the steps below to get familiar with the OpenLane-V2 dataset.
1. Run the following commands to install the environment for setting up the dataset:
```sh
git clone https://github.com/OpenDriveLab/OpenLane-V2.git
cd OpenLane-V2
conda create -n openlanev2 python=3.8 -y
conda activate openlanev2
pip install -r requirements.txt
python setup.py develop
```
2. Use [links](./data/README.md#download) to download data manually from
- <img src="https://user-images.githubusercontent.com/29263416/222076048-21501bac-71df-40fa-8671-2b5f8013d2cd.png" alt="OpenDataLab" width="18"/> OpenDataLab,
- <img src="https://ssl.gstatic.com/docs/doclist/images/drive_2022q3_32dp.png" alt="Google Drive" width="18"/> Google Drive,
- <img src="https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico" alt="Baidu Yun" width="18"/> Baidu Yun.
Then put them into the `data/OpenLane-V2/` folder and unzip them.
The resulting folder hierarchy is described [here](./data/README.md#hierarchy).
Or use the following commands to download example data for a quick glance at the dataset:
```sh
cd data/OpenLane-V2
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6" -O OpenLane-V2_sample.tar
md5sum -c openlanev2.md5
tar -xvf *.tar
cd ../..
```
```sh
git clone https://github.com/OpenDriveLab/OpenLane-V2.git
cd OpenLane-V2
conda create -n openlanev2 python=3.8 -y
conda activate openlanev2
pip install -r requirements.txt
python setup.py develop
```
2. Use [links](./data/README.md#download) to download data manually from
- <img src="https://user-images.githubusercontent.com/29263416/222076048-21501bac-71df-40fa-8671-2b5f8013d2cd.png" alt="OpenDataLab" width="18"/> OpenDataLab,
- <img src="https://ssl.gstatic.com/docs/doclist/images/drive_2022q3_32dp.png" alt="Google Drive" width="18"/> Google Drive,
- <img src="https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico" alt="Baidu Yun" width="18"/> Baidu Yun.
Then put them into the `data/OpenLane-V2/` folder and unzip them. The resulting folder hierarchy is
described [here](./data/README.md#hierarchy). Or use the following commands to download example data for a quick
glance at the dataset:
```sh
cd data/OpenLane-V2
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1Ni-L6u1MGKJRAfUXm39PdBIxdk_ntdc6" -O OpenLane-V2_sample.tar
md5sum -c openlanev2.md5
tar -xvf *.tar
cd ../..
```
3. Run the [tutorial](./tutorial.ipynb) on jupyter notebook to get familiar with the dataset and devkit.
<p align="right">(<a href="#top">back to top</a>)</p>
## Train a Model
Plug-ins to prevail deep learning frameworks for training models are provided to start training models on the OpenLane-V2 dataset.
We appreciate your valuable feedback and contributions to plug-ins on different frameworks.
Plug-ins to prevail deep learning frameworks for training models are provided to start training models on the
OpenLane-V2 dataset. We appreciate your valuable feedback and contributions to plug-ins on different frameworks.
### mmdet3d
The [plug-in](./plugin/mmdet3d/) to MMDetection3d is built on top of [mmdet3d v1.0.0rc6](https://github.com/open-mmlab/mmdetection3d/tree/v1.0.0rc6) and tested under:
The [plug-in](./plugin/mmdet3d/) to MMDetection3d is built on top
of [mmdet3d v1.0.0rc6](https://github.com/open-mmlab/mmdetection3d/tree/v1.0.0rc6) and tested under:
- Python 3.8.15
- PyTorch 1.9.1
- CUDA 11.1
......@@ -253,22 +278,26 @@ The [plug-in](./plugin/mmdet3d/) to MMDetection3d is built on top of [mmdet3d v1
- mmdet==2.26.0
- mmsegmentation==0.29.1
Please follow the [instruction](https://github.com/open-mmlab/mmdetection3d/blob/v1.0.0rc6/docs/en/getting_started.md) to install mmdet3d.
Assuming OpenLane-V2 is installed under `OpenLane-V2/` and mmdet3d is built under `mmdetection3d/`, create a soft link to the plug-in file:
Please follow the [instruction](https://github.com/open-mmlab/mmdetection3d/blob/v1.0.0rc6/docs/en/getting_started.md)
to install mmdet3d. Assuming OpenLane-V2 is installed under `OpenLane-V2/` and mmdet3d is built under `mmdetection3d/`,
create a soft link to the plug-in file:
```
└── mmdetection3d
└── projects
├── example_project
└── openlanev2 -> OpenLane-V2/plugin/mmdet3d
```
Then you can train or evaluate a model using the config `mmdetection3d/projects/openlanev2/configs/baseline.py`, whose path is replaced accordingly.
Options can be passed to enable supported functions during evaluation, such as `--eval-options dump=True dump_dir=/PATH/TO/DUMP` to save pickle file for submission and `--eval-options visualization=True visualization_dir=/PATH/TO/VIS` for visualization.
Then you can train or evaluate a model using the config `mmdetection3d/projects/openlanev2/configs/baseline.py`, whose
path is replaced accordingly. Options can be passed to enable supported functions during evaluation, such
as `--eval-options dump=True dump_dir=/PATH/TO/DUMP` to save pickle file for submission
and `--eval-options visualization=True visualization_dir=/PATH/TO/VIS` for visualization.
<p align="right">(<a href="#top">back to top</a>)</p>
## Citation
Please use the following citation when referencing OpenLane-V2:
```bibtex
......@@ -285,10 +314,13 @@ Please use the following citation when referencing OpenLane-V2:
## License
Before using the dataset, you should register on the website and agree to the terms of use of the [nuScenes](https://www.nuscenes.org/nuscenes).
Before using the dataset, you should register on the website and agree to the terms of use of
the [nuScenes](https://www.nuscenes.org/nuscenes).
Our dataset is built on top of the [nuScenes](https://www.nuscenes.org/nuscenes) and [Argoverse 2](https://www.argoverse.org/av2.html) datasets.
Before using the OpenLane-V2 dataset, you should agree to the terms of use of the [nuScenes](https://www.nuscenes.org/nuscenes) and [Argoverse 2](https://www.argoverse.org/av2.html) datasets respectively.
Our dataset is built on top of the [nuScenes](https://www.nuscenes.org/nuscenes)
and [Argoverse 2](https://www.argoverse.org/av2.html) datasets. Before using the OpenLane-V2 dataset, you should agree
to the terms of use of the [nuScenes](https://www.nuscenes.org/nuscenes)
and [Argoverse 2](https://www.argoverse.org/av2.html) datasets respectively.
All code within this repository is under [Apache License 2.0](./LICENSE).
......
{
"train": {
"00492": [
"315970272249927212.json",
"315970273249927208.json",
"315970277249927220.json",
"315970282749927222.json",
"315970283249927220.json",
"315970284749927218.json",
"315970270749927221.json",
"315970275749927218.json",
"315970277749927214.json",
"315970279749927222.json",
"315970275249927215.json",
"315970278249927213.json",
"315970271249927219.json",
"315970274749927217.json",
"315970281749927215.json",
"315970273749927222.json",
"315970272749927210.json",
"315970269249927220.json",
"315970284249927211.json",
"315970280249927220.json",
"315970283749927209.json",
"315970276249927212.json",
"315970282249927217.json",
"315970271749927213.json",
"315970279249927218.json",
"315970270249927208.json",
"315970278749927211.json",
"315970269749927218.json",
"315970280749927221.json",
"315970281249927219.json",
"315970276749927222.json",
"315970274249927212.json"
],
"00556": [
"315969900049927216.json",
"315969913049927216.json",
"315969910049927218.json",
"315969912049927218.json",
"315969907549927221.json",
"315969911549927216.json",
"315969906549927214.json",
"315969908049927220.json",
"315969905549927209.json",
"315969904549927220.json",
"315969901549927216.json",
"315969899549927217.json",
"315969913549927214.json",
"315969902049927218.json",
"315969902549927213.json",
"315969909549927216.json",
"315969907049927209.json",
"315969909049927221.json",
"315969899049927218.json",
"315969910549927209.json",
"315969908549927214.json",
"315969900549927214.json",
"315969903549927214.json",
"315969904049927221.json",
"315969912549927218.json",
"315969906049927216.json",
"315969911049927216.json",
"315969901049927213.json",
"315969898549927216.json",
"315969898049927213.json",
"315969903049927216.json",
"315969905049927210.json"
]
}
}
\ No newline at end of file
"train": {
"00492": [
"315970272249927212.json",
"315970273249927208.json",
"315970277249927220.json",
"315970282749927222.json",
"315970283249927220.json",
"315970284749927218.json",
"315970270749927221.json",
"315970275749927218.json",
"315970277749927214.json",
"315970279749927222.json",
"315970275249927215.json",
"315970278249927213.json",
"315970271249927219.json",
"315970274749927217.json",
"315970281749927215.json",
"315970273749927222.json",
"315970272749927210.json",
"315970269249927220.json",
"315970284249927211.json",
"315970280249927220.json",
"315970283749927209.json",
"315970276249927212.json",
"315970282249927217.json",
"315970271749927213.json",
"315970279249927218.json",
"315970270249927208.json",
"315970278749927211.json",
"315970269749927218.json",
"315970280749927221.json",
"315970281249927219.json",
"315970276749927222.json",
"315970274249927212.json"
],
"00556": [
"315969900049927216.json",
"315969913049927216.json",
"315969910049927218.json",
"315969912049927218.json",
"315969907549927221.json",
"315969911549927216.json",
"315969906549927214.json",
"315969908049927220.json",
"315969905549927209.json",
"315969904549927220.json",
"315969901549927216.json",
"315969899549927217.json",
"315969913549927214.json",
"315969902049927218.json",
"315969902549927213.json",
"315969909549927216.json",
"315969907049927209.json",
"315969909049927221.json",
"315969899049927218.json",
"315969910549927209.json",
"315969908549927214.json",
"315969900549927214.json",
"315969903549927214.json",
"315969904049927221.json",
"315969912549927218.json",
"315969906049927216.json",
"315969911049927216.json",
"315969901049927213.json",
"315969898549927216.json",
"315969898049927213.json",
"315969903049927216.json",
"315969905049927210.json"
]
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
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