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,21 +3,14 @@ ...@@ -3,21 +3,14 @@
# Modified by Zhiqi Li # Modified by Zhiqi Li
# --------------------------------------------- # ---------------------------------------------
import os.path as osp
import torch import torch
import mmcv
from mmcv.runner.base_runner import BaseRunner
from mmcv.runner.epoch_based_runner import EpochBasedRunner
from mmcv.runner.builder import RUNNERS
from mmcv.runner.checkpoint import save_checkpoint
from mmcv.runner.utils import get_host_info
from pprint import pprint
from mmcv.parallel.data_container import DataContainer from mmcv.parallel.data_container import DataContainer
from mmcv.runner.builder import RUNNERS
from mmcv.runner.epoch_based_runner import EpochBasedRunner
@RUNNERS.register_module() @RUNNERS.register_module()
class EpochBasedRunner_video(EpochBasedRunner): class EpochBasedRunner_video(EpochBasedRunner):
''' '''
# basic logic # basic logic
...@@ -71,14 +64,17 @@ class EpochBasedRunner_video(EpochBasedRunner): ...@@ -71,14 +64,17 @@ class EpochBasedRunner_video(EpochBasedRunner):
data[key] = data_batch[key] data[key] = data_batch[key]
else: else:
if key == 'img': if key == 'img':
data['img'] = DataContainer(data=[data_batch['img'].data[0][:, i]], cpu_only=data_batch['img'].cpu_only, stack=True) data['img'] = DataContainer(data=[data_batch['img'].data[0][:, i]],
cpu_only=data_batch['img'].cpu_only, stack=True)
elif key == 'img_metas': elif key == 'img_metas':
data['img_metas'] = DataContainer(data=[[each[i] for each in data_batch['img_metas'].data[0]]], cpu_only=data_batch['img_metas'].cpu_only) data['img_metas'] = DataContainer(
data=[[each[i] for each in data_batch['img_metas'].data[0]]],
cpu_only=data_batch['img_metas'].cpu_only)
else: else:
assert False assert False
data_list.append(data) data_list.append(data)
with torch.no_grad(): with torch.no_grad():
for i in range(num_samples-1): for i in range(num_samples - 1):
if data_list[i]['img_metas'].data[0][0]['prev_bev_exists']: if data_list[i]['img_metas'].data[0][0]['prev_bev_exists']:
data_list[i]['prev_bev'] = DataContainer(data=[prev_bev], cpu_only=False) data_list[i]['prev_bev'] = DataContainer(data=[prev_bev], cpu_only=False)
prev_bev = self.eval_model.val_step(data_list[i], self.optimizer, **kwargs) prev_bev = self.eval_model.val_step(data_list[i], self.optimizer, **kwargs)
......
import torch import torch
from mmdet.core.bbox.assigners import AssignResult, BaseAssigner
from mmdet.core.bbox.builder import BBOX_ASSIGNERS from mmdet.core.bbox.builder import BBOX_ASSIGNERS
from mmdet.core.bbox.assigners import AssignResult
from mmdet.core.bbox.assigners import BaseAssigner
from mmdet.core.bbox.match_costs import build_match_cost from mmdet.core.bbox.match_costs import build_match_cost
from mmdet.models.utils.transformer import inverse_sigmoid
from projects.mmdet3d_plugin.core.bbox.util import normalize_bbox from projects.mmdet3d_plugin.core.bbox.util import normalize_bbox
try: try:
...@@ -89,10 +86,10 @@ class HungarianAssigner3D(BaseAssigner): ...@@ -89,10 +86,10 @@ class HungarianAssigner3D(BaseAssigner):
num_gts, num_bboxes = gt_bboxes.size(0), bbox_pred.size(0) num_gts, num_bboxes = gt_bboxes.size(0), bbox_pred.size(0)
# 1. assign -1 by default # 1. assign -1 by default
assigned_gt_inds = bbox_pred.new_full((num_bboxes, ), assigned_gt_inds = bbox_pred.new_full((num_bboxes,),
-1, -1,
dtype=torch.long) dtype=torch.long)
assigned_labels = bbox_pred.new_full((num_bboxes, ), assigned_labels = bbox_pred.new_full((num_bboxes,),
-1, -1,
dtype=torch.long) dtype=torch.long)
if num_gts == 0 or num_bboxes == 0: if num_gts == 0 or num_bboxes == 0:
......
import torch import torch
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS from mmdet.core.bbox.builder import BBOX_CODERS
from projects.mmdet3d_plugin.core.bbox.util import denormalize_bbox from projects.mmdet3d_plugin.core.bbox.util import denormalize_bbox
import numpy as np
@BBOX_CODERS.register_module() @BBOX_CODERS.register_module()
...@@ -119,4 +117,3 @@ class NMSFreeCoder(BaseBBoxCoder): ...@@ -119,4 +117,3 @@ class NMSFreeCoder(BaseBBoxCoder):
for i in range(batch_size): for i in range(batch_size):
predictions_list.append(self.decode_single(all_cls_scores[i], all_bbox_preds[i])) predictions_list.append(self.decode_single(all_cls_scores[i], all_bbox_preds[i]))
return predictions_list return predictions_list
from mmdet.core.bbox.match_costs import build_match_cost
from .match_cost import BBox3DL1Cost from .match_cost import BBox3DL1Cost
__all__ = ['build_match_cost', 'BBox3DL1Cost'] __all__ = ['build_match_cost', 'BBox3DL1Cost']
...@@ -2,7 +2,6 @@ import torch ...@@ -2,7 +2,6 @@ import torch
def normalize_bbox(bboxes, pc_range): def normalize_bbox(bboxes, pc_range):
cx = bboxes[..., 0:1] cx = bboxes[..., 0:1]
cy = bboxes[..., 1:2] cy = bboxes[..., 1:2]
cz = bboxes[..., 2:3] cz = bboxes[..., 2:3]
...@@ -23,6 +22,7 @@ def normalize_bbox(bboxes, pc_range): ...@@ -23,6 +22,7 @@ def normalize_bbox(bboxes, pc_range):
) )
return normalized_bboxes return normalized_bboxes
def denormalize_bbox(normalized_bboxes, pc_range): def denormalize_bbox(normalized_bboxes, pc_range):
# rotation # rotation
rot_sine = normalized_bboxes[..., 6:7] rot_sine = normalized_bboxes[..., 6:7]
......
# Note: Considering that MMCV's EvalHook updated its interface in V1.3.16, # Note: Considering that MMCV's EvalHook updated its interface in V1.3.16,
# in order to avoid strong version dependency, we did not directly # in order to avoid strong version dependency, we did not directly
# inherit EvalHook but BaseDistEvalHook. # inherit EvalHook but BaseDistEvalHook.
...@@ -9,9 +8,7 @@ import os.path as osp ...@@ -9,9 +8,7 @@ import os.path as osp
import mmcv import mmcv
import torch.distributed as dist import torch.distributed as dist
from mmcv.runner import DistEvalHook as BaseDistEvalHook from mmcv.runner import DistEvalHook as BaseDistEvalHook
from mmcv.runner import EvalHook as BaseEvalHook
from torch.nn.modules.batchnorm import _BatchNorm from torch.nn.modules.batchnorm import _BatchNorm
from mmdet.core.evaluation.eval_hooks import DistEvalHook
def _calc_dynamic_intervals(start_interval, dynamic_interval_list): def _calc_dynamic_intervals(start_interval, dynamic_interval_list):
...@@ -73,7 +70,8 @@ class CustomDistEvalHook(BaseDistEvalHook): ...@@ -73,7 +70,8 @@ class CustomDistEvalHook(BaseDistEvalHook):
if tmpdir is None: if tmpdir is None:
tmpdir = osp.join(runner.work_dir, '.eval_hook') tmpdir = osp.join(runner.work_dir, '.eval_hook')
from projects.mmdet3d_plugin.bevformer.apis.test import custom_multi_gpu_test # to solve circlur import from projects.mmdet3d_plugin.bevformer.apis.test import \
custom_multi_gpu_test # to solve circlur import
results = custom_multi_gpu_test( results = custom_multi_gpu_test(
runner.model, runner.model,
...@@ -89,4 +87,3 @@ class CustomDistEvalHook(BaseDistEvalHook): ...@@ -89,4 +87,3 @@ class CustomDistEvalHook(BaseDistEvalHook):
runner=runner) runner=runner)
# if self.save_best: # if self.save_best:
# self._save_ckpt(runner, key_score) # self._save_ckpt(runner, key_score)
from .builder import custom_build_dataset
from .nuscenes_dataset import CustomNuScenesDataset from .nuscenes_dataset import CustomNuScenesDataset
from .nuscenes_occ import NuSceneOcc from .nuscenes_occ import NuSceneOcc
from .builder import custom_build_dataset
__all__ = [ __all__ = [
'CustomNuScenesDataset' 'CustomNuScenesDataset'
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import copy import copy
import platform import platform
...@@ -8,13 +7,14 @@ from functools import partial ...@@ -8,13 +7,14 @@ from functools import partial
import numpy as np import numpy as np
from mmcv.parallel import collate from mmcv.parallel import collate
from mmcv.runner import get_dist_info from mmcv.runner import get_dist_info
from mmcv.utils import Registry, build_from_cfg
from torch.utils.data import DataLoader
from mmdet.datasets.samplers import GroupSampler from mmdet.datasets.samplers import GroupSampler
from projects.mmdet3d_plugin.datasets.samplers.group_sampler import DistributedGroupSampler from projects.mmdet3d_plugin.datasets.samplers.distributed_sampler import \
from projects.mmdet3d_plugin.datasets.samplers.distributed_sampler import DistributedSampler DistributedSampler
from projects.mmdet3d_plugin.datasets.samplers.group_sampler import \
DistributedGroupSampler
from projects.mmdet3d_plugin.datasets.samplers.sampler import build_sampler from projects.mmdet3d_plugin.datasets.samplers.sampler import build_sampler
from torch.utils.data import DataLoader
def build_dataloader(dataset, def build_dataloader(dataset,
samples_per_gpu, samples_per_gpu,
...@@ -48,7 +48,8 @@ def build_dataloader(dataset, ...@@ -48,7 +48,8 @@ def build_dataloader(dataset,
# DistributedGroupSampler will definitely shuffle the data to satisfy # DistributedGroupSampler will definitely shuffle the data to satisfy
# that images on each GPU are in the same group # that images on each GPU are in the same group
if shuffle: if shuffle:
sampler = build_sampler(shuffler_sampler if shuffler_sampler is not None else dict(type='DistributedGroupSampler'), sampler = build_sampler(
shuffler_sampler if shuffler_sampler is not None else dict(type='DistributedGroupSampler'),
dict( dict(
dataset=dataset, dataset=dataset,
samples_per_gpu=samples_per_gpu, samples_per_gpu=samples_per_gpu,
...@@ -58,7 +59,8 @@ def build_dataloader(dataset, ...@@ -58,7 +59,8 @@ def build_dataloader(dataset,
) )
else: else:
sampler = build_sampler(nonshuffler_sampler if nonshuffler_sampler is not None else dict(type='DistributedSampler'), sampler = build_sampler(
nonshuffler_sampler if nonshuffler_sampler is not None else dict(type='DistributedSampler'),
dict( dict(
dataset=dataset, dataset=dataset,
num_replicas=world_size, num_replicas=world_size,
...@@ -103,14 +105,15 @@ def worker_init_fn(worker_id, num_workers, rank, seed): ...@@ -103,14 +105,15 @@ def worker_init_fn(worker_id, num_workers, rank, seed):
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import platform import platform
from mmcv.utils import Registry, build_from_cfg
from mmcv.utils import Registry, build_from_cfg
from mmdet.datasets import DATASETS from mmdet.datasets import DATASETS
from mmdet.datasets.builder import _concat_dataset from mmdet.datasets.builder import _concat_dataset
if platform.system() != 'Windows': if platform.system() != 'Windows':
# https://github.com/pytorch/pytorch/issues/973 # https://github.com/pytorch/pytorch/issues/973
import resource import resource
rlimit = resource.getrlimit(resource.RLIMIT_NOFILE) rlimit = resource.getrlimit(resource.RLIMIT_NOFILE)
base_soft_limit = rlimit[0] base_soft_limit = rlimit[0]
hard_limit = rlimit[1] hard_limit = rlimit[1]
......
import copy import copy
import random
from os import path as osp
import mmcv
import numpy as np import numpy as np
from mmdet.datasets import DATASETS import torch
from mmcv.parallel import DataContainer as DC
from mmdet3d.core.bbox import LiDARInstance3DBoxes
from mmdet3d.datasets import NuScenesDataset from mmdet3d.datasets import NuScenesDataset
import mmcv
from os import path as osp
from mmdet.datasets import DATASETS from mmdet.datasets import DATASETS
import torch from nuscenes.eval.common.utils import Quaternion, quaternion_yaw
import numpy as np
from nuscenes.eval.common.utils import quaternion_yaw, Quaternion
from mmdet3d.core.bbox import Box3DMode, Coord3DMode, LiDARInstance3DBoxes
from .nuscnes_eval import NuScenesEval_custom from .nuscnes_eval import NuScenesEval_custom
from projects.mmdet3d_plugin.models.utils.visual import save_tensor
from mmcv.parallel import DataContainer as DC
import random
@DATASETS.register_module() @DATASETS.register_module()
...@@ -38,7 +36,7 @@ class CustomNuScenesDataset(NuScenesDataset): ...@@ -38,7 +36,7 @@ class CustomNuScenesDataset(NuScenesDataset):
dict: Training data dict of the corresponding index. dict: Training data dict of the corresponding index.
""" """
queue = [] queue = []
index_list = list(range(index-self.queue_length, index)) index_list = list(range(index - self.queue_length, index))
random.shuffle(index_list) random.shuffle(index_list)
index_list = sorted(index_list[1:]) index_list = sorted(index_list[1:])
index_list.append(index) index_list.append(index)
...@@ -55,7 +53,6 @@ class CustomNuScenesDataset(NuScenesDataset): ...@@ -55,7 +53,6 @@ class CustomNuScenesDataset(NuScenesDataset):
queue.append(example) queue.append(example)
return self.union2one(queue) return self.union2one(queue)
def union2one(self, queue): def union2one(self, queue):
imgs_list = [each['img'].data for each in queue] imgs_list = [each['img'].data for each in queue]
metas_map = {} metas_map = {}
...@@ -127,8 +124,6 @@ class CustomNuScenesDataset(NuScenesDataset): ...@@ -127,8 +124,6 @@ class CustomNuScenesDataset(NuScenesDataset):
box_dim=gt_bboxes_3d.shape[-1], box_dim=gt_bboxes_3d.shape[-1],
origin=(0.5, 0.5, 0.5)).convert_to(self.box_mode_3d) origin=(0.5, 0.5, 0.5)).convert_to(self.box_mode_3d)
anns_results = dict( anns_results = dict(
gt_bboxes_3d=gt_bboxes_3d, gt_bboxes_3d=gt_bboxes_3d,
gt_labels_3d=gt_labels_3d, gt_labels_3d=gt_labels_3d,
......
import copy import copy
import os import os
import numpy as np import random
from tqdm import tqdm
from mmdet.datasets import DATASETS
from mmdet3d.datasets import NuScenesDataset
import mmcv import mmcv
from os import path as osp
from mmdet.datasets import DATASETS
import torch
import numpy as np import numpy as np
from nuscenes.eval.common.utils import quaternion_yaw, Quaternion import torch
from .nuscnes_eval import NuScenesEval_custom
from projects.mmdet3d_plugin.models.utils.visual import save_tensor
from mmcv.parallel import DataContainer as DC from mmcv.parallel import DataContainer as DC
import random from mmdet3d.datasets import NuScenesDataset
from mmdet.datasets import DATASETS
from nuscenes.eval.common.utils import Quaternion, quaternion_yaw
from nuscenes.utils.geometry_utils import transform_matrix from nuscenes.utils.geometry_utils import transform_matrix
from .occ_metrics import Metric_mIoU, Metric_FScore from tqdm import tqdm
from .occ_metrics import Metric_FScore, Metric_mIoU
@DATASETS.register_module() @DATASETS.register_module()
...@@ -209,8 +206,8 @@ class NuSceneOcc(NuScenesDataset): ...@@ -209,8 +206,8 @@ class NuSceneOcc(NuScenesDataset):
if not os.path.exists(show_dir): if not os.path.exists(show_dir):
os.mkdir(show_dir) os.mkdir(show_dir)
print('\nSaving output and gt in {} for visualization.'.format(show_dir)) print('\nSaving output and gt in {} for visualization.'.format(show_dir))
begin=eval_kwargs.get('begin',None) begin = eval_kwargs.get('begin', None)
end=eval_kwargs.get('end',None) end = eval_kwargs.get('end', None)
self.occ_eval_metrics = Metric_mIoU( self.occ_eval_metrics = Metric_mIoU(
num_classes=18, num_classes=18,
use_lidar_mask=False, use_lidar_mask=False,
...@@ -233,15 +230,14 @@ class NuSceneOcc(NuScenesDataset): ...@@ -233,15 +230,14 @@ class NuSceneOcc(NuScenesDataset):
occ_gt = np.load(os.path.join(self.data_root, info['occ_gt_path'])) occ_gt = np.load(os.path.join(self.data_root, info['occ_gt_path']))
if show_dir is not None: if show_dir is not None:
if begin is not None and end is not None: if begin is not None and end is not None:
if index>= begin and index<end: if index >= begin and index < end:
sample_token = info['token'] sample_token = info['token']
save_path = os.path.join(show_dir,str(index).zfill(4)) save_path = os.path.join(show_dir, str(index).zfill(4))
np.savez_compressed(save_path, pred=occ_pred, gt=occ_gt, sample_token=sample_token) np.savez_compressed(save_path, pred=occ_pred, gt=occ_gt, sample_token=sample_token)
else: else:
sample_token=info['token'] sample_token = info['token']
save_path=os.path.join(show_dir,str(index).zfill(4)) save_path = os.path.join(show_dir, str(index).zfill(4))
np.savez_compressed(save_path,pred=occ_pred,gt=occ_gt,sample_token=sample_token) np.savez_compressed(save_path, pred=occ_pred, gt=occ_gt, sample_token=sample_token)
gt_semantics = occ_gt['semantics'] gt_semantics = occ_gt['semantics']
mask_lidar = occ_gt['mask_lidar'].astype(bool) mask_lidar = occ_gt['mask_lidar'].astype(bool)
...@@ -254,6 +250,3 @@ class NuSceneOcc(NuScenesDataset): ...@@ -254,6 +250,3 @@ class NuSceneOcc(NuScenesDataset):
self.occ_eval_metrics.count_miou() self.occ_eval_metrics.count_miou()
if self.eval_fscore: if self.eval_fscore:
self.fscore_eval_metrics.count_fscore() self.fscore_eval_metrics.count_fscore()
...@@ -3,74 +3,42 @@ import copy ...@@ -3,74 +3,42 @@ import copy
import json import json
import os import os
import time import time
from typing import Tuple, Dict, Any from typing import Any, Dict, Tuple
import torch
import numpy as np
import numpy as np
import tqdm
from matplotlib import pyplot as plt
from nuscenes import NuScenes from nuscenes import NuScenes
from nuscenes.eval.common.config import config_factory from nuscenes.eval.common.config import config_factory
from nuscenes.eval.common.data_classes import EvalBoxes from nuscenes.eval.common.data_classes import EvalBoxes
from nuscenes.eval.detection.data_classes import DetectionConfig from nuscenes.eval.common.loaders import (add_center_dist, filter_eval_boxes,
load_gt, load_prediction)
from nuscenes.eval.common.render import setup_axis
from nuscenes.eval.detection.algo import accumulate, calc_ap, calc_tp
from nuscenes.eval.detection.constants import (DETECTION_NAMES,
PRETTY_DETECTION_NAMES,
PRETTY_TP_METRICS, TP_METRICS,
TP_METRICS_UNITS)
from nuscenes.eval.detection.data_classes import (DetectionBox,
DetectionConfig,
DetectionMetricDataList,
DetectionMetrics)
from nuscenes.eval.detection.evaluate import NuScenesEval from nuscenes.eval.detection.evaluate import NuScenesEval
from pyquaternion import Quaternion from nuscenes.eval.detection.render import (class_pr_curve, dist_pr_curve,
summary_plot)
from nuscenes import NuScenes
from nuscenes.eval.common.data_classes import EvalBoxes
from nuscenes.eval.detection.data_classes import DetectionBox
from nuscenes.eval.detection.utils import category_to_detection_name from nuscenes.eval.detection.utils import category_to_detection_name
from nuscenes.eval.tracking.data_classes import TrackingBox from nuscenes.eval.tracking.data_classes import TrackingBox
from nuscenes.utils.data_classes import Box from nuscenes.utils.data_classes import Box
from nuscenes.utils.geometry_utils import points_in_box from nuscenes.utils.geometry_utils import (BoxVisibility, transform_matrix,
view_points)
from nuscenes.utils.splits import create_splits_scenes from nuscenes.utils.splits import create_splits_scenes
from nuscenes.eval.common.loaders import load_prediction, add_center_dist, filter_eval_boxes from pyquaternion import Quaternion
import tqdm
from nuscenes.utils.geometry_utils import view_points, box_in_image, BoxVisibility, transform_matrix
from torchvision.transforms.functional import rotate
import pycocotools.mask as mask_util
# from projects.mmdet3d_plugin.models.utils.visual import save_tensor
from torchvision.transforms.functional import rotate
import cv2
import argparse
import json
import os
import random
import time
from typing import Tuple, Dict, Any
import numpy as np
from nuscenes import NuScenes
from nuscenes.eval.common.config import config_factory
from nuscenes.eval.common.data_classes import EvalBoxes
from nuscenes.eval.common.loaders import load_prediction, load_gt, add_center_dist, filter_eval_boxes
from nuscenes.eval.detection.algo import accumulate, calc_ap, calc_tp
from nuscenes.eval.detection.constants import TP_METRICS
from nuscenes.eval.detection.data_classes import DetectionConfig, DetectionMetrics, DetectionBox, \
DetectionMetricDataList
from nuscenes.eval.detection.render import summary_plot, class_pr_curve, dist_pr_curve, visualize_sample
from nuscenes.eval.common.utils import quaternion_yaw, Quaternion
from mmdet3d.core.bbox.iou_calculators import BboxOverlaps3D
from IPython import embed
import json
from typing import Any
import numpy as np
from matplotlib import pyplot as plt
from nuscenes import NuScenes
from nuscenes.eval.common.data_classes import EvalBoxes
from nuscenes.eval.common.render import setup_axis
from nuscenes.eval.common.utils import boxes_to_sensor
from nuscenes.eval.detection.constants import TP_METRICS, DETECTION_NAMES, DETECTION_COLORS, TP_METRICS_UNITS, \
PRETTY_DETECTION_NAMES, PRETTY_TP_METRICS
from nuscenes.eval.detection.data_classes import DetectionMetrics, DetectionMetricData, DetectionMetricDataList
from nuscenes.utils.data_classes import LidarPointCloud
from nuscenes.utils.geometry_utils import view_points
# from projects.mmdet3d_plugin.models.utils.visual import save_tensor
Axis = Any Axis = Any
def class_tp_curve(md_list: DetectionMetricDataList, def class_tp_curve(md_list: DetectionMetricDataList,
metrics: DetectionMetrics, metrics: DetectionMetrics,
detection_name: str, detection_name: str,
...@@ -124,7 +92,7 @@ def class_tp_curve(md_list: DetectionMetricDataList, ...@@ -124,7 +92,7 @@ def class_tp_curve(md_list: DetectionMetricDataList,
label = '{}: {:.2f} ({})'.format(PRETTY_TP_METRICS[metric], tp, TP_METRICS_UNITS[metric]) label = '{}: {:.2f} ({})'.format(PRETTY_TP_METRICS[metric], tp, TP_METRICS_UNITS[metric])
if metric == 'trans_err': if metric == 'trans_err':
label += f' ({md.max_recall_ind})' # add recall label += f' ({md.max_recall_ind})' # add recall
print(f'Recall: {detection_name}: {md.max_recall_ind/100}') print(f'Recall: {detection_name}: {md.max_recall_ind / 100}')
ax.plot(recall, error, label=label) ax.plot(recall, error, label=label)
ax.axvline(x=md.max_recall, linestyle='-.', color=(0, 0, 0, 0.3)) ax.axvline(x=md.max_recall, linestyle='-.', color=(0, 0, 0, 0.3))
ax.legend(loc='best') ax.legend(loc='best')
...@@ -211,7 +179,7 @@ def center_in_image(box, intrinsic: np.ndarray, imsize: Tuple[int, int], vis_lev ...@@ -211,7 +179,7 @@ def center_in_image(box, intrinsic: np.ndarray, imsize: Tuple[int, int], vis_lev
elif vis_level == BoxVisibility.NONE: elif vis_level == BoxVisibility.NONE:
return True return True
else: else:
raise ValueError("vis_level: {} not valid".format(vis_level)) raise ValueError('vis_level: {} not valid'.format(vis_level))
def exist_corners_in_image_but_not_all(box, intrinsic: np.ndarray, imsize: Tuple[int, int], def exist_corners_in_image_but_not_all(box, intrinsic: np.ndarray, imsize: Tuple[int, int],
...@@ -259,7 +227,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False): ...@@ -259,7 +227,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False):
print('Loading annotations for {} split from nuScenes version: {}'.format(eval_split, nusc.version)) print('Loading annotations for {} split from nuScenes version: {}'.format(eval_split, nusc.version))
# Read out all sample_tokens in DB. # Read out all sample_tokens in DB.
sample_tokens_all = [s['token'] for s in nusc.sample] sample_tokens_all = [s['token'] for s in nusc.sample]
assert len(sample_tokens_all) > 0, "Error: Database has no samples!" assert len(sample_tokens_all) > 0, 'Error: Database has no samples!'
# Only keep samples from this split. # Only keep samples from this split.
splits = create_splits_scenes() splits = create_splits_scenes()
...@@ -354,7 +322,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False): ...@@ -354,7 +322,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False):
all_annotations.add_boxes(sample_token, sample_boxes) all_annotations.add_boxes(sample_token, sample_boxes)
if verbose: if verbose:
print("Loaded ground truth annotations for {} samples.".format(len(all_annotations.sample_tokens))) print('Loaded ground truth annotations for {} samples.'.format(len(all_annotations.sample_tokens)))
return all_annotations return all_annotations
...@@ -385,8 +353,8 @@ def filter_eval_boxes_by_id(nusc: NuScenes, ...@@ -385,8 +353,8 @@ def filter_eval_boxes_by_id(nusc: NuScenes,
eval_boxes.boxes[sample_token] = filtered_boxes eval_boxes.boxes[sample_token] = filtered_boxes
if verbose: if verbose:
print("=> Original number of boxes: %d" % total) print('=> Original number of boxes: %d' % total)
print("=> After anns based filtering: %d" % anns_filter) print('=> After anns based filtering: %d' % anns_filter)
return eval_boxes return eval_boxes
...@@ -417,8 +385,8 @@ def filter_eval_boxes_by_visibility( ...@@ -417,8 +385,8 @@ def filter_eval_boxes_by_visibility(
eval_boxes.boxes[sample_token] = filtered_boxes eval_boxes.boxes[sample_token] = filtered_boxes
if verbose: if verbose:
print("=> Original number of boxes: %d" % total) print('=> Original number of boxes: %d' % total)
print("=> After visibility based filtering: %d" % anns_filter) print('=> After visibility based filtering: %d' % anns_filter)
return eval_boxes return eval_boxes
...@@ -498,8 +466,8 @@ def filter_eval_boxes_by_overlap(nusc: NuScenes, ...@@ -498,8 +466,8 @@ def filter_eval_boxes_by_overlap(nusc: NuScenes,
verbose = True verbose = True
if verbose: if verbose:
print("=> Original number of boxes: %d" % total) print('=> Original number of boxes: %d' % total)
print("=> After anns based filtering: %d" % anns_filter) print('=> After anns based filtering: %d' % anns_filter)
return eval_boxes return eval_boxes
...@@ -620,7 +588,6 @@ class NuScenesEval_custom(NuScenesEval): ...@@ -620,7 +588,6 @@ class NuScenesEval_custom(NuScenesEval):
self.pred_boxes = filter_by_sample_token(self.all_preds, valid_tokens) self.pred_boxes = filter_by_sample_token(self.all_preds, valid_tokens)
self.sample_tokens = self.gt_boxes.sample_tokens self.sample_tokens = self.gt_boxes.sample_tokens
def evaluate(self) -> Tuple[DetectionMetrics, DetectionMetricDataList]: def evaluate(self) -> Tuple[DetectionMetrics, DetectionMetricDataList]:
""" """
Performs the actual evaluation. Performs the actual evaluation.
...@@ -698,7 +665,7 @@ class NuScenesEval_custom(NuScenesEval): ...@@ -698,7 +665,7 @@ class NuScenesEval_custom(NuScenesEval):
savepath=savepath('dist_pr_' + str(dist_th))) savepath=savepath('dist_pr_' + str(dist_th)))
if __name__ == "__main__": if __name__ == '__main__':
# Settings. # Settings.
parser = argparse.ArgumentParser(description='Evaluate nuScenes detection results.', parser = argparse.ArgumentParser(description='Evaluate nuScenes detection results.',
...@@ -746,6 +713,6 @@ if __name__ == "__main__": ...@@ -746,6 +713,6 @@ if __name__ == "__main__":
nusc_eval.update_gt(type_='vis', visibility=vis) nusc_eval.update_gt(type_='vis', visibility=vis)
print(f'================ {vis} ===============') print(f'================ {vis} ===============')
nusc_eval.main(plot_examples=plot_examples_, render_curves=render_curves_) nusc_eval.main(plot_examples=plot_examples_, render_curves=render_curves_)
#for index in range(1, 41): # for index in range(1, 41):
# nusc_eval.update_gt(type_='ord', index=index) # nusc_eval.update_gt(type_='ord', index=index)
# #
import numpy as np
import os import os
from pathlib import Path from functools import reduce
from tqdm import tqdm
import pickle as pkl import numpy as np
import argparse
import time
import torch
import sys, platform
from sklearn.neighbors import KDTree from sklearn.neighbors import KDTree
from termcolor import colored from termcolor import colored
from pathlib import Path
from copy import deepcopy
from functools import reduce
np.seterr(divide='ignore', invalid='ignore') np.seterr(divide='ignore', invalid='ignore')
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
def pcolor(string, color, on_color=None, attrs=None): def pcolor(string, color, on_color=None, attrs=None):
...@@ -56,10 +48,10 @@ class Metric_mIoU(): ...@@ -56,10 +48,10 @@ class Metric_mIoU():
use_lidar_mask=False, use_lidar_mask=False,
use_image_mask=False, use_image_mask=False,
): ):
self.class_names = ['others','barrier', 'bicycle', 'bus', 'car', 'construction_vehicle', self.class_names = ['others', 'barrier', 'bicycle', 'bus', 'car', 'construction_vehicle',
'motorcycle', 'pedestrian', 'traffic_cone', 'trailer', 'truck', 'motorcycle', 'pedestrian', 'traffic_cone', 'trailer', 'truck',
'driveable_surface', 'other_flat', 'sidewalk', 'driveable_surface', 'other_flat', 'sidewalk',
'terrain', 'manmade', 'vegetation','free'] 'terrain', 'manmade', 'vegetation', 'free']
self.save_dir = save_dir self.save_dir = save_dir
self.use_lidar_mask = use_lidar_mask self.use_lidar_mask = use_lidar_mask
self.use_image_mask = use_image_mask self.use_image_mask = use_image_mask
...@@ -117,8 +109,7 @@ class Metric_mIoU(): ...@@ -117,8 +109,7 @@ class Metric_mIoU():
# print('===> mIoU: ' + str(round(np.nanmean(mIoUs) * 100, 2))) # print('===> mIoU: ' + str(round(np.nanmean(mIoUs) * 100, 2)))
return round(np.nanmean(mIoUs) * 100, 2), hist return round(np.nanmean(mIoUs) * 100, 2), hist
def add_batch(self, semantics_pred, semantics_gt, mask_lidar, mask_camera):
def add_batch(self,semantics_pred,semantics_gt,mask_lidar,mask_camera):
self.cnt += 1 self.cnt += 1
if self.use_image_mask: if self.use_image_mask:
masked_semantics_gt = semantics_gt[mask_camera] masked_semantics_gt = semantics_gt[mask_camera]
...@@ -138,10 +129,10 @@ class Metric_mIoU(): ...@@ -138,10 +129,10 @@ class Metric_mIoU():
mIoU = self.per_class_iu(self.hist) mIoU = self.per_class_iu(self.hist)
# assert cnt == num_samples, 'some samples are not included in the miou calculation' # assert cnt == num_samples, 'some samples are not included in the miou calculation'
print(f'===> per class IoU of {self.cnt} samples:') print(f'===> per class IoU of {self.cnt} samples:')
for ind_class in range(self.num_classes-1): for ind_class in range(self.num_classes - 1):
print(f'===> {self.class_names[ind_class]} - IoU = ' + str(round(mIoU[ind_class] * 100, 2))) print(f'===> {self.class_names[ind_class]} - IoU = ' + str(round(mIoU[ind_class] * 100, 2)))
print(f'===> mIoU of {self.cnt} samples: ' + str(round(np.nanmean(mIoU[:self.num_classes-1]) * 100, 2))) print(f'===> mIoU of {self.cnt} samples: ' + str(round(np.nanmean(mIoU[:self.num_classes - 1]) * 100, 2)))
# print(f'===> sample-wise averaged mIoU of {cnt} samples: ' + str(round(np.nanmean(mIoU_avg), 2))) # print(f'===> sample-wise averaged mIoU of {cnt} samples: ' + str(round(np.nanmean(mIoU_avg), 2)))
# return mIoU # return mIoU
...@@ -167,14 +158,12 @@ class Metric_FScore(): ...@@ -167,14 +158,12 @@ class Metric_FScore():
self.void = void self.void = void
self.use_lidar_mask = use_lidar_mask self.use_lidar_mask = use_lidar_mask
self.use_image_mask = use_image_mask self.use_image_mask = use_image_mask
self.cnt=0 self.cnt = 0
self.tot_acc = 0. self.tot_acc = 0.
self.tot_cmpl = 0. self.tot_cmpl = 0.
self.tot_f1_mean = 0. self.tot_f1_mean = 0.
self.eps = 1e-8 self.eps = 1e-8
def voxel2points(self, voxel): def voxel2points(self, voxel):
# occIdx = torch.where(torch.logical_and(voxel != FREE, voxel != NOT_OBSERVED)) # occIdx = torch.where(torch.logical_and(voxel != FREE, voxel != NOT_OBSERVED))
# if isinstance(voxel, np.ndarray): voxel = torch.from_numpy(voxel) # if isinstance(voxel, np.ndarray): voxel = torch.from_numpy(voxel)
...@@ -187,13 +176,12 @@ class Metric_FScore(): ...@@ -187,13 +176,12 @@ class Metric_FScore():
axis=1) axis=1)
return points return points
def add_batch(self,semantics_pred,semantics_gt,mask_lidar,mask_camera ): def add_batch(self, semantics_pred, semantics_gt, mask_lidar, mask_camera):
# for scene_token in tqdm(preds_dict.keys()): # for scene_token in tqdm(preds_dict.keys()):
self.cnt += 1 self.cnt += 1
if self.use_image_mask: if self.use_image_mask:
semantics_gt[mask_camera == False] = 255 semantics_gt[mask_camera == False] = 255
semantics_pred[mask_camera == False] = 255 semantics_pred[mask_camera == False] = 255
elif self.use_lidar_mask: elif self.use_lidar_mask:
...@@ -205,9 +193,9 @@ class Metric_FScore(): ...@@ -205,9 +193,9 @@ class Metric_FScore():
ground_truth = self.voxel2points(semantics_gt) ground_truth = self.voxel2points(semantics_gt)
prediction = self.voxel2points(semantics_pred) prediction = self.voxel2points(semantics_pred)
if prediction.shape[0] == 0: if prediction.shape[0] == 0:
accuracy=0 accuracy = 0
completeness=0 completeness = 0
fmean=0 fmean = 0
else: else:
prediction_tree = KDTree(prediction, leaf_size=self.leaf_size) prediction_tree = KDTree(prediction, leaf_size=self.leaf_size)
...@@ -226,14 +214,12 @@ class Metric_FScore(): ...@@ -226,14 +214,12 @@ class Metric_FScore():
accuracy_mask = accuracy_distance < self.threshold_acc accuracy_mask = accuracy_distance < self.threshold_acc
accuracy = accuracy_mask.mean() accuracy = accuracy_mask.mean()
fmean = 2.0 / (1 / (accuracy+self.eps) + 1 / (completeness+self.eps)) fmean = 2.0 / (1 / (accuracy + self.eps) + 1 / (completeness + self.eps))
self.tot_acc += accuracy self.tot_acc += accuracy
self.tot_cmpl += completeness self.tot_cmpl += completeness
self.tot_f1_mean += fmean self.tot_f1_mean += fmean
def count_fscore(self,): def count_fscore(self, ):
base_color, attrs = 'red', ['bold', 'dark'] base_color, attrs = 'red', ['bold', 'dark']
print(pcolor('\n######## F score: {} #######'.format(self.tot_f1_mean / self.cnt), base_color, attrs=attrs)) print(pcolor('\n######## F score: {} #######'.format(self.tot_f1_mean / self.cnt), base_color, attrs=attrs))
from .transform_3d import (
PadMultiViewImage, NormalizeMultiviewImage,
PhotoMetricDistortionMultiViewImage, CustomCollect3D, RandomScaleImageMultiViewImage)
from .formating import CustomDefaultFormatBundle3D from .formating import CustomDefaultFormatBundle3D
from .loading import LoadOccGTFromFile from .loading import LoadOccGTFromFile
from .transform_3d import (CustomCollect3D, NormalizeMultiviewImage,
PadMultiViewImage,
PhotoMetricDistortionMultiViewImage,
RandomScaleImageMultiViewImage)
__all__ = [ __all__ = [
'PadMultiViewImage', 'NormalizeMultiviewImage', 'PadMultiViewImage', 'NormalizeMultiviewImage',
'PhotoMetricDistortionMultiViewImage', 'CustomDefaultFormatBundle3D', 'CustomCollect3D', 'RandomScaleImageMultiViewImage' 'PhotoMetricDistortionMultiViewImage', 'CustomDefaultFormatBundle3D', 'CustomCollect3D',
'RandomScaleImageMultiViewImage'
] ]
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import numpy as np
from mmcv.parallel import DataContainer as DC from mmcv.parallel import DataContainer as DC
from mmdet3d.datasets.pipelines import DefaultFormatBundle3D
from mmdet3d.core.bbox import BaseInstance3DBoxes
from mmdet3d.core.points import BasePoints
from mmdet.datasets.builder import PIPELINES from mmdet.datasets.builder import PIPELINES
from mmdet.datasets.pipelines import to_tensor from mmdet.datasets.pipelines import to_tensor
from mmdet3d.datasets.pipelines import DefaultFormatBundle3D
@PIPELINES.register_module() @PIPELINES.register_module()
class CustomDefaultFormatBundle3D(DefaultFormatBundle3D): class CustomDefaultFormatBundle3D(DefaultFormatBundle3D):
......
import os
import numpy as np import numpy as np
from numpy import random
import mmcv
from mmdet.datasets.builder import PIPELINES from mmdet.datasets.builder import PIPELINES
from mmcv.parallel import DataContainer as DC
import os
@PIPELINES.register_module() @PIPELINES.register_module()
class LoadOccGTFromFile(object): class LoadOccGTFromFile(object):
...@@ -26,7 +25,7 @@ class LoadOccGTFromFile(object): ...@@ -26,7 +25,7 @@ class LoadOccGTFromFile(object):
def __call__(self, results): def __call__(self, results):
# print(results.keys()) # print(results.keys())
occ_gt_path = results['occ_gt_path'] occ_gt_path = results['occ_gt_path']
occ_gt_path = os.path.join(self.data_root,occ_gt_path) occ_gt_path = os.path.join(self.data_root, occ_gt_path)
occ_labels = np.load(occ_gt_path) occ_labels = np.load(occ_gt_path)
semantics = occ_labels['semantics'] semantics = occ_labels['semantics']
...@@ -37,7 +36,6 @@ class LoadOccGTFromFile(object): ...@@ -37,7 +36,6 @@ class LoadOccGTFromFile(object):
results['mask_lidar'] = mask_lidar results['mask_lidar'] = mask_lidar
results['mask_camera'] = mask_camera results['mask_camera'] = mask_camera
return results return results
def __repr__(self): def __repr__(self):
......
import numpy as np
from numpy import random
import mmcv import mmcv
from mmdet.datasets.builder import PIPELINES import numpy as np
from mmcv.parallel import DataContainer as DC from mmcv.parallel import DataContainer as DC
import os from mmdet.datasets.builder import PIPELINES
from numpy import random
@PIPELINES.register_module() @PIPELINES.register_module()
...@@ -78,7 +75,6 @@ class NormalizeMultiviewImage(object): ...@@ -78,7 +75,6 @@ class NormalizeMultiviewImage(object):
self.std = np.array(std, dtype=np.float32) self.std = np.array(std, dtype=np.float32)
self.to_rgb = to_rgb self.to_rgb = to_rgb
def __call__(self, results): def __call__(self, results):
"""Call function to normalize images. """Call function to normalize images.
Args: Args:
...@@ -140,7 +136,7 @@ class PhotoMetricDistortionMultiViewImage: ...@@ -140,7 +136,7 @@ class PhotoMetricDistortionMultiViewImage:
new_imgs = [] new_imgs = []
for img in imgs: for img in imgs:
assert img.dtype == np.float32, \ assert img.dtype == np.float32, \
'PhotoMetricDistortion needs the input image of dtype np.float32,'\ 'PhotoMetricDistortion needs the input image of dtype np.float32,' \
' please set "to_float32=True" in "LoadImageFromFile" pipeline' ' please set "to_float32=True" in "LoadImageFromFile" pipeline'
# random brightness # random brightness
if random.randint(2): if random.randint(2):
...@@ -199,7 +195,6 @@ class PhotoMetricDistortionMultiViewImage: ...@@ -199,7 +195,6 @@ class PhotoMetricDistortionMultiViewImage:
return repr_str return repr_str
@PIPELINES.register_module() @PIPELINES.register_module()
class CustomCollect3D(object): class CustomCollect3D(object):
"""Collect data from the loader relevant to the specific task. """Collect data from the loader relevant to the specific task.
...@@ -247,7 +242,7 @@ class CustomCollect3D(object): ...@@ -247,7 +242,7 @@ class CustomCollect3D(object):
def __init__(self, def __init__(self,
keys, keys,
meta_keys=('filename', 'ori_shape', 'img_shape', 'lidar2img','ego2lidar', meta_keys=('filename', 'ori_shape', 'img_shape', 'lidar2img', 'ego2lidar',
'depth2img', 'cam2img', 'pad_shape', 'depth2img', 'cam2img', 'pad_shape',
'scale_factor', 'flip', 'pcd_horizontal_flip', 'scale_factor', 'flip', 'pcd_horizontal_flip',
'pcd_vertical_flip', 'box_mode_3d', 'box_type_3d', 'pcd_vertical_flip', 'box_mode_3d', 'box_type_3d',
...@@ -288,7 +283,6 @@ class CustomCollect3D(object): ...@@ -288,7 +283,6 @@ class CustomCollect3D(object):
f'(keys={self.keys}, meta_keys={self.meta_keys})' f'(keys={self.keys}, meta_keys={self.meta_keys})'
@PIPELINES.register_module() @PIPELINES.register_module()
class RandomScaleImageMultiViewImage(object): class RandomScaleImageMultiViewImage(object):
"""Random scale the image """Random scale the image
...@@ -298,7 +292,7 @@ class RandomScaleImageMultiViewImage(object): ...@@ -298,7 +292,7 @@ class RandomScaleImageMultiViewImage(object):
def __init__(self, scales=[]): def __init__(self, scales=[]):
self.scales = scales self.scales = scales
assert len(self.scales)==1 assert len(self.scales) == 1
def __call__(self, results): def __call__(self, results):
"""Call function to pad images, masks, semantic segmentation maps. """Call function to pad images, masks, semantic segmentation maps.
...@@ -324,7 +318,6 @@ class RandomScaleImageMultiViewImage(object): ...@@ -324,7 +318,6 @@ class RandomScaleImageMultiViewImage(object):
return results return results
def __repr__(self): def __repr__(self):
repr_str = self.__class__.__name__ repr_str = self.__class__.__name__
repr_str += f'(size={self.scales}, ' repr_str += f'(size={self.scales}, '
......
from .group_sampler import DistributedGroupSampler
from .distributed_sampler import DistributedSampler from .distributed_sampler import DistributedSampler
from .group_sampler import DistributedGroupSampler
from .sampler import SAMPLER, build_sampler from .sampler import SAMPLER, build_sampler
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