Unverified Commit 0c22c625 authored by Xiang Xu's avatar Xiang Xu Committed by GitHub
Browse files

[Enhancement] Support format_only for LyftDataset. (#2333)

parent cf6f4732
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from collections import OrderedDict from collections import OrderedDict
from typing import Dict, List, Optional, Sequence from typing import Dict, List, Optional, Sequence, Union
import numpy as np import numpy as np
from mmdet.evaluation import eval_map from mmdet.evaluation import eval_map
...@@ -17,37 +17,34 @@ class IndoorMetric(BaseMetric): ...@@ -17,37 +17,34 @@ class IndoorMetric(BaseMetric):
"""Indoor scene evaluation metric. """Indoor scene evaluation metric.
Args: Args:
iou_thr (list[float]): List of iou threshold when calculate the iou_thr (float or List[float]): List of iou threshold when calculate
metric. Defaults to [0.25, 0.5]. the metric. Defaults to [0.25, 0.5].
collect_device (str, optional): Device name used for collecting collect_device (str): Device name used for collecting results from
results from different ranks during distributed training. different ranks during distributed training. Must be 'cpu' or
Must be 'cpu' or 'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
prefix (str): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Default: None be used instead. Defaults to None.
""" """
def __init__(self, def __init__(self,
iou_thr: List[float] = [0.25, 0.5], iou_thr: List[float] = [0.25, 0.5],
collect_device: str = 'cpu', collect_device: str = 'cpu',
prefix: Optional[str] = None, prefix: Optional[str] = None) -> None:
**kwargs):
super(IndoorMetric, self).__init__( super(IndoorMetric, self).__init__(
prefix=prefix, collect_device=collect_device) prefix=prefix, collect_device=collect_device)
self.iou_thr = iou_thr self.iou_thr = [iou_thr] if isinstance(iou_thr, float) else iou_thr
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None:
"""Process one batch of data samples and predictions. """Process one batch of data samples and predictions.
The processed results should be stored in ``self.results``, The processed results should be stored in ``self.results``, which will
which will be used to compute the metrics when all batches be used to compute the metrics when all batches have been processed.
have been processed.
Args: Args:
data_batch (dict): A batch of data from the dataloader. data_batch (dict): A batch of data from the dataloader.
data_samples (Sequence[dict]): A batch of outputs from data_samples (Sequence[dict]): A batch of outputs from the model.
the model.
""" """
for data_sample in data_samples: for data_sample in data_samples:
pred_3d = data_sample['pred_instances_3d'] pred_3d = data_sample['pred_instances_3d']
...@@ -98,37 +95,34 @@ class Indoor2DMetric(BaseMetric): ...@@ -98,37 +95,34 @@ class Indoor2DMetric(BaseMetric):
"""indoor 2d predictions evaluation metric. """indoor 2d predictions evaluation metric.
Args: Args:
iou_thr (list[float]): List of iou threshold when calculate the iou_thr (float or List[float]): List of iou threshold when calculate
metric. Defaults to [0.5]. the metric. Defaults to [0.5].
collect_device (str, optional): Device name used for collecting collect_device (str): Device name used for collecting results from
results from different ranks during distributed training. different ranks during distributed training. Must be 'cpu' or
Must be 'cpu' or 'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
prefix (str): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Default: None be used instead. Defaults to None.
""" """
def __init__(self, def __init__(self,
iou_thr: List[float] = [0.5], iou_thr: Union[float, List[float]] = [0.5],
collect_device: str = 'cpu', collect_device: str = 'cpu',
prefix: Optional[str] = None, prefix: Optional[str] = None):
**kwargs):
super(Indoor2DMetric, self).__init__( super(Indoor2DMetric, self).__init__(
prefix=prefix, collect_device=collect_device) prefix=prefix, collect_device=collect_device)
self.iou_thr = iou_thr self.iou_thr = [iou_thr] if isinstance(iou_thr, float) else iou_thr
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None:
"""Process one batch of data samples and predictions. """Process one batch of data samples and predictions.
The processed results should be stored in ``self.results``, The processed results should be stored in ``self.results``, which will
which will be used to compute the metrics when all batches be used to compute the metrics when all batches have been processed.
have been processed.
Args: Args:
data_batch (dict): A batch of data from the dataloader. data_batch (dict): A batch of data from the dataloader.
predictions (Sequence[dict]): A batch of outputs from data_samples (Sequence[dict]): A batch of outputs from the model.
the model.
""" """
for data_sample in data_samples: for data_sample in data_samples:
pred = data_sample['pred_instances'] pred = data_sample['pred_instances']
...@@ -163,9 +157,7 @@ class Indoor2DMetric(BaseMetric): ...@@ -163,9 +157,7 @@ class Indoor2DMetric(BaseMetric):
logger: MMLogger = MMLogger.get_current_instance() logger: MMLogger = MMLogger.get_current_instance()
annotations, preds = zip(*results) annotations, preds = zip(*results)
eval_results = OrderedDict() eval_results = OrderedDict()
iou_thr_2d = (self.iou_thr) if isinstance(self.iou_thr, for iou_thr_2d_single in self.iou_thr:
float) else self.iou_thr
for iou_thr_2d_single in iou_thr_2d:
mean_ap, _ = eval_map( mean_ap, _ = eval_map(
preds, preds,
annotations, annotations,
......
...@@ -13,33 +13,30 @@ class InstanceSegMetric(BaseMetric): ...@@ -13,33 +13,30 @@ class InstanceSegMetric(BaseMetric):
"""3D instance segmentation evaluation metric. """3D instance segmentation evaluation metric.
Args: Args:
collect_device (str, optional): Device name used for collecting collect_device (str): Device name used for collecting results from
results from different ranks during distributed training. different ranks during distributed training. Must be 'cpu' or
Must be 'cpu' or 'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
prefix (str): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Default: None be used instead. Defaults to None.
""" """
def __init__(self, def __init__(self,
collect_device: str = 'cpu', collect_device: str = 'cpu',
prefix: Optional[str] = None, prefix: Optional[str] = None):
**kwargs):
super(InstanceSegMetric, self).__init__( super(InstanceSegMetric, self).__init__(
prefix=prefix, collect_device=collect_device) prefix=prefix, collect_device=collect_device)
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None:
"""Process one batch of data samples and predictions. """Process one batch of data samples and predictions.
The processed results should be stored in ``self.results``, The processed results should be stored in ``self.results``, which will
which will be used to compute the metrics when all batches be used to compute the metrics when all batches have been processed.
have been processed.
Args: Args:
data_batch (dict): A batch of data from the dataloader. data_batch (dict): A batch of data from the dataloader.
data_samples (Sequence[dict]): A batch of outputs from data_samples (Sequence[dict]): A batch of outputs from the model.
the model.
""" """
for data_sample in data_samples: for data_sample in data_samples:
pred_3d = data_sample['pred_pts_seg'] pred_3d = data_sample['pred_pts_seg']
......
...@@ -22,30 +22,28 @@ class KittiMetric(BaseMetric): ...@@ -22,30 +22,28 @@ class KittiMetric(BaseMetric):
Args: Args:
ann_file (str): Annotation file path. ann_file (str): Annotation file path.
metric (str or List[str]): Metrics to be evaluated. metric (str or List[str]): Metrics to be evaluated. Defaults to 'bbox'.
Defaults to 'bbox'. pcd_limit_range (List[float]): The range of point cloud used to filter
pcd_limit_range (List[float]): The range of point cloud used to invalid predicted boxes. Defaults to [0, -40, -3, 70.4, 40, 0.0].
filter invalid predicted boxes.
Defaults to [0, -40, -3, 70.4, 40, 0.0].
prefix (str, optional): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Defaults to None. be used instead. Defaults to None.
pklfile_prefix (str, optional): The prefix of pkl files, including pklfile_prefix (str, optional): The prefix of pkl files, including the
the file path and the prefix of filename, e.g., "a/b/prefix". file path and the prefix of filename, e.g., "a/b/prefix". If not
If not specified, a temp file will be created. Defaults to None. specified, a temp file will be created. Defaults to None.
default_cam_key (str): The default camera for lidar to camera default_cam_key (str): The default camera for lidar to camera
conversion. By default, KITTI: 'CAM2', Waymo: 'CAM_FRONT'. conversion. By default, KITTI: 'CAM2', Waymo: 'CAM_FRONT'.
Defaults to 'CAM2' Defaults to 'CAM2'.
format_only (bool): Format the output results without perform format_only (bool): Format the output results without perform
evaluation. It is useful when you want to format the result evaluation. It is useful when you want to format the result to a
to a specific format and submit it to the test server. specific format and submit it to the test server.
Defaults to False. Defaults to False.
submission_prefix (str, optional): The prefix of submission data. submission_prefix (str, optional): The prefix of submission data. If
If not specified, the submission data will not be generated. not specified, the submission data will not be generated.
Defaults to None. Defaults to None.
collect_device (str): Device name used for collecting results collect_device (str): Device name used for collecting results from
from different ranks during distributed training. Must be 'cpu' or different ranks during distributed training. Must be 'cpu' or
'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
backend_args (dict, optional): Arguments to instantiate the backend_args (dict, optional): Arguments to instantiate the
corresponding backend. Defaults to None. corresponding backend. Defaults to None.
...@@ -147,14 +145,12 @@ class KittiMetric(BaseMetric): ...@@ -147,14 +145,12 @@ class KittiMetric(BaseMetric):
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None:
"""Process one batch of data samples and predictions. """Process one batch of data samples and predictions.
The processed results should be stored in ``self.results``, The processed results should be stored in ``self.results``, which will
which will be used to compute the metrics when all batches be used to compute the metrics when all batches have been processed.
have been processed.
Args: Args:
data_batch (dict): A batch of data from the dataloader. data_batch (dict): A batch of data from the dataloader.
data_samples (Sequence[dict]): A batch of outputs from data_samples (Sequence[dict]): A batch of outputs from the model.
the model.
""" """
for data_sample in data_samples: for data_sample in data_samples:
...@@ -196,8 +192,8 @@ class KittiMetric(BaseMetric): ...@@ -196,8 +192,8 @@ class KittiMetric(BaseMetric):
metric_dict = {} metric_dict = {}
if self.format_only: if self.format_only:
logger.info('results are saved in ' logger.info(
f'{osp.dirname(self.submission_prefix)}') f'results are saved in {osp.dirname(self.submission_prefix)}')
return metric_dict return metric_dict
gt_annos = [ gt_annos = [
...@@ -230,12 +226,11 @@ class KittiMetric(BaseMetric): ...@@ -230,12 +226,11 @@ class KittiMetric(BaseMetric):
Args: Args:
results_dict (dict): Formatted results of the dataset. results_dict (dict): Formatted results of the dataset.
gt_annos (List[dict]): Contain gt information of each sample. gt_annos (List[dict]): Contain gt information of each sample.
metric (str, optional): Metrics to be evaluated. metric (str, optional): Metrics to be evaluated. Defaults to None.
Defaults to None.
classes (List[str], optional): A list of class name. classes (List[str], optional): A list of class name.
Defaults to None. Defaults to None.
logger (MMLogger, optional): Logger used for printing logger (MMLogger, optional): Logger used for printing related
related information during evaluation. Defaults to None. information during evaluation. Defaults to None.
Returns: Returns:
Dict[str, float]: Results of each evaluation metric. Dict[str, float]: Results of each evaluation metric.
...@@ -278,9 +273,9 @@ class KittiMetric(BaseMetric): ...@@ -278,9 +273,9 @@ class KittiMetric(BaseMetric):
Defaults to None. Defaults to None.
Returns: Returns:
tuple: (result_dict, tmp_dir), result_dict is a dict containing tuple: (result_dict, tmp_dir), result_dict is a dict containing the
the formatted result, tmp_dir is the temporal directory created formatted result, tmp_dir is the temporal directory created for
for saving json files when jsonfile_prefix is not specified. saving json files when jsonfile_prefix is not specified.
""" """
if pklfile_prefix is None: if pklfile_prefix is None:
tmp_dir = tempfile.TemporaryDirectory() tmp_dir = tempfile.TemporaryDirectory()
...@@ -326,8 +321,8 @@ class KittiMetric(BaseMetric): ...@@ -326,8 +321,8 @@ class KittiMetric(BaseMetric):
submission. submission.
Args: Args:
net_outputs (List[dict]): List of dict storing the net_outputs (List[dict]): List of dict storing the inferenced
inferenced bounding boxes and scores. bounding boxes and scores.
sample_idx_list (List[int]): List of input sample idx. sample_idx_list (List[int]): List of input sample idx.
class_names (List[str]): A list of class names. class_names (List[str]): A list of class names.
pklfile_prefix (str, optional): The prefix of pkl file. pklfile_prefix (str, optional): The prefix of pkl file.
...@@ -453,8 +448,8 @@ class KittiMetric(BaseMetric): ...@@ -453,8 +448,8 @@ class KittiMetric(BaseMetric):
submission. submission.
Args: Args:
net_outputs (List[dict]): List of dict storing the net_outputs (List[dict]): List of dict storing the inferenced
inferenced bounding boxes and scores. bounding boxes and scores.
sample_idx_list (List[int]): List of input sample idx. sample_idx_list (List[int]): List of input sample idx.
class_names (List[str]): A list of class names. class_names (List[str]): A list of class names.
pklfile_prefix (str, optional): The prefix of pkl file. pklfile_prefix (str, optional): The prefix of pkl file.
...@@ -571,14 +566,14 @@ class KittiMetric(BaseMetric): ...@@ -571,14 +566,14 @@ class KittiMetric(BaseMetric):
Returns: Returns:
dict: Valid predicted boxes. dict: Valid predicted boxes.
- bbox (np.ndarray): 2D bounding boxes. - bbox (np.ndarray): 2D bounding boxes.
- box3d_camera (np.ndarray): 3D bounding boxes in - box3d_camera (np.ndarray): 3D bounding boxes in
camera coordinate. camera coordinate.
- box3d_lidar (np.ndarray): 3D bounding boxes in - box3d_lidar (np.ndarray): 3D bounding boxes in
LiDAR coordinate. LiDAR coordinate.
- scores (np.ndarray): Scores of boxes. - scores (np.ndarray): Scores of boxes.
- label_preds (np.ndarray): Class label predictions. - label_preds (np.ndarray): Class label predictions.
- sample_idx (int): Sample index. - sample_idx (int): Sample index.
""" """
# TODO: refactor this function # TODO: refactor this function
box_preds = box_dict['bboxes_3d'] box_preds = box_dict['bboxes_3d']
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import logging
import os import os
import tempfile import tempfile
from os import path as osp from os import path as osp
...@@ -26,24 +25,29 @@ class LyftMetric(BaseMetric): ...@@ -26,24 +25,29 @@ class LyftMetric(BaseMetric):
Args: Args:
data_root (str): Path of dataset root. data_root (str): Path of dataset root.
ann_file (str): Path of annotation file. ann_file (str): Path of annotation file.
metric (str | list[str]): Metrics to be evaluated. metric (str or List[str]): Metrics to be evaluated. Defaults to 'bbox'.
Default to 'bbox'. modality (dict): Modality to specify the sensor data used as input.
modality (dict): Modality to specify the sensor data used Defaults to dict(use_camera=False, use_lidar=True).
as input. Defaults to dict(use_camera=False, use_lidar=True).
prefix (str, optional): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Defaults to None. be used instead. Defaults to None.
jsonfile_prefix (str, optional): The prefix of json files including jsonfile_prefix (str, optional): The prefix of json files including the
the file path and the prefix of filename, e.g., "a/b/prefix". file path and the prefix of filename, e.g., "a/b/prefix". If not
If not specified, a temp file will be created. Default: None. specified, a temp file will be created. Defaults to None.
csv_savepath (str, optional): The path for saving csv files. format_only (bool): Format the output results without perform
It includes the file path and the csv filename, evaluation. It is useful when you want to format the result to a
e.g., "a/b/filename.csv". If not specified, specific format and submit it to the test server.
the result will not be converted to csv file. Defaults to False.
collect_device (str): Device name used for collecting results csv_savepath (str, optional): The path for saving csv files. It
from different ranks during distributed training. Must be 'cpu' or includes the file path and the csv filename, e.g.,
"a/b/filename.csv". If not specified, the result will not be
converted to csv file. Defaults to None.
collect_device (str): Device name used for collecting results from
different ranks during distributed training. Must be 'cpu' or
'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
backend_args (dict, optional): Arguments to instantiate the
corresponding backend. Defaults to None.
""" """
def __init__(self, def __init__(self,
...@@ -56,6 +60,7 @@ class LyftMetric(BaseMetric): ...@@ -56,6 +60,7 @@ class LyftMetric(BaseMetric):
), ),
prefix: Optional[str] = None, prefix: Optional[str] = None,
jsonfile_prefix: str = None, jsonfile_prefix: str = None,
format_only: bool = False,
csv_savepath: str = None, csv_savepath: str = None,
collect_device: str = 'cpu', collect_device: str = 'cpu',
backend_args: Optional[dict] = None) -> None: backend_args: Optional[dict] = None) -> None:
...@@ -66,6 +71,12 @@ class LyftMetric(BaseMetric): ...@@ -66,6 +71,12 @@ class LyftMetric(BaseMetric):
self.data_root = data_root self.data_root = data_root
self.modality = modality self.modality = modality
self.jsonfile_prefix = jsonfile_prefix self.jsonfile_prefix = jsonfile_prefix
self.format_only = format_only
if self.format_only:
assert csv_savepath is not None, 'csv_savepath must be not None '
'when format_only is True, otherwise the result files will be '
'saved to a temp directory which will be cleaned up at the end.'
self.backend_args = backend_args self.backend_args = backend_args
self.csv_savepath = csv_savepath self.csv_savepath = csv_savepath
self.metrics = metric if isinstance(metric, list) else [metric] self.metrics = metric if isinstance(metric, list) else [metric]
...@@ -73,14 +84,12 @@ class LyftMetric(BaseMetric): ...@@ -73,14 +84,12 @@ class LyftMetric(BaseMetric):
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None:
"""Process one batch of data samples and data_samples. """Process one batch of data samples and data_samples.
The processed results should be stored in ``self.results``, The processed results should be stored in ``self.results``, which will
which will be used to compute the metrics when all batches be used to compute the metrics when all batches have been processed.
have been processed.
Args: Args:
data_batch (dict): A batch of data from the dataloader. data_batch (dict): A batch of data from the dataloader.
data_samples (Sequence[dict]): A batch of outputs from data_samples (Sequence[dict]): A batch of outputs from the model.
the model.
""" """
for data_sample in data_samples: for data_sample in data_samples:
result = dict() result = dict()
...@@ -94,13 +103,13 @@ class LyftMetric(BaseMetric): ...@@ -94,13 +103,13 @@ class LyftMetric(BaseMetric):
result['pred_instances'] = pred_2d result['pred_instances'] = pred_2d
sample_idx = data_sample['sample_idx'] sample_idx = data_sample['sample_idx']
result['sample_idx'] = sample_idx result['sample_idx'] = sample_idx
self.results.append(result) self.results.append(result)
def compute_metrics(self, results: list) -> Dict[str, float]: def compute_metrics(self, results: List[dict]) -> Dict[str, float]:
"""Compute the metrics from processed results. """Compute the metrics from processed results.
Args: Args:
results (list): The processed results of each batch. results (List[dict]): The processed results of the whole dataset.
Returns: Returns:
Dict[str, float]: The computed metrics. The keys are the names of Dict[str, float]: The computed metrics. The keys are the names of
...@@ -110,14 +119,21 @@ class LyftMetric(BaseMetric): ...@@ -110,14 +119,21 @@ class LyftMetric(BaseMetric):
classes = self.dataset_meta['classes'] classes = self.dataset_meta['classes']
self.version = self.dataset_meta['version'] self.version = self.dataset_meta['version']
# load annotations
# load annotations
self.data_infos = load( self.data_infos = load(
self.ann_file, backend_args=self.backend_args)['data_list'] self.ann_file, backend_args=self.backend_args)['data_list']
result_dict, tmp_dir = self.format_results(results, classes, result_dict, tmp_dir = self.format_results(results, classes,
self.jsonfile_prefix) self.jsonfile_prefix,
self.csv_savepath)
metric_dict = {} metric_dict = {}
if self.format_only:
logger.info(
f'results are saved in {osp.dirname(self.csv_savepath)}')
return metric_dict
for metric in self.metrics: for metric in self.metrics:
ap_dict = self.lyft_evaluate( ap_dict = self.lyft_evaluate(
result_dict, metric=metric, logger=logger) result_dict, metric=metric, logger=logger)
...@@ -128,31 +144,33 @@ class LyftMetric(BaseMetric): ...@@ -128,31 +144,33 @@ class LyftMetric(BaseMetric):
tmp_dir.cleanup() tmp_dir.cleanup()
return metric_dict return metric_dict
def format_results(self, def format_results(
results: List[dict], self,
classes: List[str] = None, results: List[dict],
jsonfile_prefix: str = None, classes: Optional[List[str]] = None,
csv_savepath: str = None) -> Tuple: jsonfile_prefix: Optional[str] = None,
csv_savepath: Optional[str] = None
) -> Tuple[dict, Union[tempfile.TemporaryDirectory, None]]:
"""Format the results to json (standard format for COCO evaluation). """Format the results to json (standard format for COCO evaluation).
Args: Args:
results (list[dict]): Testing results of the dataset. results (List[dict]): Testing results of the dataset.
classes (list[String], optional): A list of class name. Defaults classes (List[str], optional): A list of class name.
to None. Defaults to None.
jsonfile_prefix (str, optional): The prefix of json files. It jsonfile_prefix (str, optional): The prefix of json files. It
includes the file path and the prefix of filename, e.g., includes the file path and the prefix of filename, e.g.,
"a/b/prefix". If not specified, a temp file will be created. "a/b/prefix". If not specified, a temp file will be created.
Default: None. Defaults to None.
csv_savepath (str, optional): The path for saving csv files. csv_savepath (str, optional): The path for saving csv files. It
It includes the file path and the csv filename, includes the file path and the csv filename, e.g.,
e.g., "a/b/filename.csv". If not specified, "a/b/filename.csv". If not specified, the result will not be
the result will not be converted to csv file. converted to csv file. Defaults to None.
Returns: Returns:
tuple: Returns (result_dict, tmp_dir), where `result_dict` is a tuple: Returns (result_dict, tmp_dir), where ``result_dict`` is a
dict containing the json filepaths, `tmp_dir` is the temporal dict containing the json filepaths, ``tmp_dir`` is the temporal
directory created for saving json files when directory created for saving json files when ``jsonfile_prefix`` is
`jsonfile_prefix` is not specified. not specified.
""" """
assert isinstance(results, list), 'results must be a list' assert isinstance(results, list), 'results must be a list'
...@@ -162,7 +180,7 @@ class LyftMetric(BaseMetric): ...@@ -162,7 +180,7 @@ class LyftMetric(BaseMetric):
else: else:
tmp_dir = None tmp_dir = None
result_dict = dict() result_dict = dict()
sample_id_list = [result['sample_idx'] for result in results] sample_idx_list = [result['sample_idx'] for result in results]
for name in results[0]: for name in results[0]:
if 'pred' in name and '3d' in name and name[0] != '_': if 'pred' in name and '3d' in name and name[0] != '_':
...@@ -172,8 +190,9 @@ class LyftMetric(BaseMetric): ...@@ -172,8 +190,9 @@ class LyftMetric(BaseMetric):
# 'img_pred_instances_3d' # 'img_pred_instances_3d'
results_ = [out[name] for out in results] results_ = [out[name] for out in results]
tmp_file_ = osp.join(jsonfile_prefix, name) tmp_file_ = osp.join(jsonfile_prefix, name)
result_dict[name] = self._format_bbox(results_, sample_id_list, result_dict[name] = self._format_bbox(results_,
classes, tmp_file_) sample_idx_list, classes,
tmp_file_)
if csv_savepath is not None: if csv_savepath is not None:
if 'pred_instances_3d' in result_dict: if 'pred_instances_3d' in result_dict:
self.json2csv(result_dict['pred_instances_3d'], csv_savepath) self.json2csv(result_dict['pred_instances_3d'], csv_savepath)
...@@ -221,19 +240,19 @@ class LyftMetric(BaseMetric): ...@@ -221,19 +240,19 @@ class LyftMetric(BaseMetric):
def _format_bbox(self, def _format_bbox(self,
results: List[dict], results: List[dict],
sample_id_list: List[int], sample_idx_list: List[int],
classes: List[str] = None, classes: Optional[List[str]] = None,
jsonfile_prefix: str = None) -> str: jsonfile_prefix: Optional[str] = None) -> str:
"""Convert the results to the standard format. """Convert the results to the standard format.
Args: Args:
results (list[dict]): Testing results of the dataset. results (List[dict]): Testing results of the dataset.
sample_id_list (list[int]): List of result sample id. sample_idx_list (List[int]): List of result sample idx.
classes (list[String], optional): A list of class name. Defaults classes (List[str], optional): A list of class name.
to None. Defaults to None.
jsonfile_prefix (str, optional): The prefix of the output jsonfile. jsonfile_prefix (str, optional): The prefix of the output jsonfile.
You can specify the output directory/filename by You can specify the output directory/filename by modifying the
modifying the jsonfile_prefix. Default: None. jsonfile_prefix. Defaults to None.
Returns: Returns:
str: Path of the output json file. str: Path of the output json file.
...@@ -244,9 +263,10 @@ class LyftMetric(BaseMetric): ...@@ -244,9 +263,10 @@ class LyftMetric(BaseMetric):
for i, det in enumerate(mmengine.track_iter_progress(results)): for i, det in enumerate(mmengine.track_iter_progress(results)):
annos = [] annos = []
boxes = output_to_lyft_box(det) boxes = output_to_lyft_box(det)
sample_id = sample_id_list[i] sample_idx = sample_idx_list[i]
sample_token = self.data_infos[sample_id]['token'] sample_token = self.data_infos[sample_idx]['token']
boxes = lidar_lyft_box_to_global(self.data_infos[sample_id], boxes) boxes = lidar_lyft_box_to_global(self.data_infos[sample_idx],
boxes)
for i, box in enumerate(boxes): for i, box in enumerate(boxes):
name = classes[box.label] name = classes[box.label]
lyft_anno = dict( lyft_anno = dict(
...@@ -272,27 +292,24 @@ class LyftMetric(BaseMetric): ...@@ -272,27 +292,24 @@ class LyftMetric(BaseMetric):
def lyft_evaluate(self, def lyft_evaluate(self,
result_dict: dict, result_dict: dict,
metric: str = 'bbox', metric: str = 'bbox',
logger: logging.Logger = None) -> dict: logger: Optional[MMLogger] = None) -> Dict[str, float]:
"""Evaluation in Lyft protocol. """Evaluation in Lyft protocol.
Args: Args:
result_dict (dict): Formatted results of the dataset. result_dict (dict): Formatted results of the dataset.
metric (str): Metrics to be evaluated. metric (str): Metrics to be evaluated. Defaults to 'bbox'.
Default: 'bbox'. logger (MMLogger, optional): Logger used for printing related
classes (list[String], optional): A list of class name. Defaults information during evaluation. Defaults to None.
to None.
logger (MMLogger, optional): Logger used for printing
related information during evaluation. Default: None.
Returns: Returns:
dict[str, float]: Evaluation results. Dict[str, float]: Evaluation results.
""" """
metric_dict = dict() metric_dict = dict()
for name in result_dict: for name in result_dict:
print('Evaluating bboxes of {}'.format(name)) print(f'Evaluating bboxes of {name}')
ret_dict = self._evaluate_single( ret_dict = self._evaluate_single(
result_dict[name], logger=logger, result_name=name) result_dict[name], logger=logger, result_name=name)
metric_dict.update(ret_dict) metric_dict.update(ret_dict)
return metric_dict return metric_dict
def _evaluate_single(self, def _evaluate_single(self,
...@@ -303,15 +320,13 @@ class LyftMetric(BaseMetric): ...@@ -303,15 +320,13 @@ class LyftMetric(BaseMetric):
Args: Args:
result_path (str): Path of the result file. result_path (str): Path of the result file.
logger (logging.Logger | str, optional): Logger used for printing logger (MMLogger, optional): Logger used for printing related
related information during evaluation. Default: None. information during evaluation. Defaults to None.
metric (str): Metric name used for evaluation.
Default: 'bbox'.
result_name (str): Result name in the metric prefix. result_name (str): Result name in the metric prefix.
Default: 'pts_bbox'. Defaults to 'pts_bbox'.
Returns: Returns:
dict: Dictionary of evaluation details. Dict[str, float]: Dictionary of evaluation details.
""" """
output_dir = osp.join(*osp.split(result_path)[:-1]) output_dir = osp.join(*osp.split(result_path)[:-1])
lyft = Lyft( lyft = Lyft(
...@@ -343,7 +358,7 @@ def output_to_lyft_box(detection: dict) -> List[LyftBox]: ...@@ -343,7 +358,7 @@ def output_to_lyft_box(detection: dict) -> List[LyftBox]:
detection (dict): Detection results. detection (dict): Detection results.
Returns: Returns:
list[:obj:`LyftBox`]: List of standard LyftBoxes. List[:obj:`LyftBox`]: List of standard LyftBoxes.
""" """
bbox3d = detection['bbox_3d'] bbox3d = detection['bbox_3d']
scores = detection['scores_3d'].numpy() scores = detection['scores_3d'].numpy()
...@@ -374,13 +389,13 @@ def lidar_lyft_box_to_global(info: dict, ...@@ -374,13 +389,13 @@ def lidar_lyft_box_to_global(info: dict,
"""Convert the box from ego to global coordinate. """Convert the box from ego to global coordinate.
Args: Args:
info (dict): Info for a specific sample data, including the info (dict): Info for a specific sample data, including the calibration
calibration information. information.
boxes (list[:obj:`LyftBox`]): List of predicted LyftBoxes. boxes (List[:obj:`LyftBox`]): List of predicted LyftBoxes.
Returns: Returns:
list: List of standard LyftBoxes in the global List[:obj:`LyftBox`]: List of standard LyftBoxes in the global
coordinate. coordinate.
""" """
box_list = [] box_list = []
for box in boxes: for box in boxes:
......
...@@ -27,25 +27,24 @@ class NuScenesMetric(BaseMetric): ...@@ -27,25 +27,24 @@ class NuScenesMetric(BaseMetric):
Args: Args:
data_root (str): Path of dataset root. data_root (str): Path of dataset root.
ann_file (str): Path of annotation file. ann_file (str): Path of annotation file.
metric (str or List[str]): Metrics to be evaluated. metric (str or List[str]): Metrics to be evaluated. Defaults to 'bbox'.
Defaults to 'bbox'. modality (dict): Modality to specify the sensor data used as input.
modality (dict): Modality to specify the sensor data used Defaults to dict(use_camera=False, use_lidar=True).
as input. Defaults to dict(use_camera=False, use_lidar=True).
prefix (str, optional): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Defaults to None. be used instead. Defaults to None.
format_only (bool): Format the output results without perform format_only (bool): Format the output results without perform
evaluation. It is useful when you want to format the result evaluation. It is useful when you want to format the result to a
to a specific format and submit it to the test server. specific format and submit it to the test server.
Defaults to False. Defaults to False.
jsonfile_prefix (str, optional): The prefix of json files including jsonfile_prefix (str, optional): The prefix of json files including the
the file path and the prefix of filename, e.g., "a/b/prefix". file path and the prefix of filename, e.g., "a/b/prefix".
If not specified, a temp file will be created. Defaults to None. If not specified, a temp file will be created. Defaults to None.
eval_version (str): Configuration version of evaluation. eval_version (str): Configuration version of evaluation.
Defaults to 'detection_cvpr_2019'. Defaults to 'detection_cvpr_2019'.
collect_device (str): Device name used for collecting results collect_device (str): Device name used for collecting results from
from different ranks during distributed training. Must be 'cpu' or different ranks during distributed training. Must be 'cpu' or
'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
backend_args (dict, optional): Arguments to instantiate the backend_args (dict, optional): Arguments to instantiate the
corresponding backend. Defaults to None. corresponding backend. Defaults to None.
...@@ -111,10 +110,9 @@ class NuScenesMetric(BaseMetric): ...@@ -111,10 +110,9 @@ class NuScenesMetric(BaseMetric):
self.modality = modality self.modality = modality
self.format_only = format_only self.format_only = format_only
if self.format_only: if self.format_only:
assert jsonfile_prefix is not None, 'jsonfile_prefix must be ' assert jsonfile_prefix is not None, 'jsonfile_prefix must be not '
'not None when format_only is True, otherwise the result files ' 'None when format_only is True, otherwise the result files will '
'will be saved to a temp directory which will be cleanup at ' 'be saved to a temp directory which will be cleanup at the end.'
'the end.'
self.jsonfile_prefix = jsonfile_prefix self.jsonfile_prefix = jsonfile_prefix
self.backend_args = backend_args self.backend_args = backend_args
...@@ -127,14 +125,12 @@ class NuScenesMetric(BaseMetric): ...@@ -127,14 +125,12 @@ class NuScenesMetric(BaseMetric):
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None:
"""Process one batch of data samples and predictions. """Process one batch of data samples and predictions.
The processed results should be stored in ``self.results``, The processed results should be stored in ``self.results``, which will
which will be used to compute the metrics when all batches be used to compute the metrics when all batches have been processed.
have been processed.
Args: Args:
data_batch (dict): A batch of data from the dataloader. data_batch (dict): A batch of data from the dataloader.
data_samples (Sequence[dict]): A batch of outputs from data_samples (Sequence[dict]): A batch of outputs from the model.
the model.
""" """
for data_sample in data_samples: for data_sample in data_samples:
result = dict() result = dict()
...@@ -173,8 +169,8 @@ class NuScenesMetric(BaseMetric): ...@@ -173,8 +169,8 @@ class NuScenesMetric(BaseMetric):
metric_dict = {} metric_dict = {}
if self.format_only: if self.format_only:
logger.info('results are saved in ' logger.info(
f'{osp.basename(self.jsonfile_prefix)}') f'results are saved in {osp.basename(self.jsonfile_prefix)}')
return metric_dict return metric_dict
for metric in self.metrics: for metric in self.metrics:
...@@ -199,8 +195,8 @@ class NuScenesMetric(BaseMetric): ...@@ -199,8 +195,8 @@ class NuScenesMetric(BaseMetric):
metric (str): Metrics to be evaluated. Defaults to 'bbox'. metric (str): Metrics to be evaluated. Defaults to 'bbox'.
classes (List[str], optional): A list of class name. classes (List[str], optional): A list of class name.
Defaults to None. Defaults to None.
logger (MMLogger, optional): Logger used for printing logger (MMLogger, optional): Logger used for printing related
related information during evaluation. Defaults to None. information during evaluation. Defaults to None.
Returns: Returns:
Dict[str, float]: Results of each evaluation metric. Dict[str, float]: Results of each evaluation metric.
...@@ -210,7 +206,7 @@ class NuScenesMetric(BaseMetric): ...@@ -210,7 +206,7 @@ class NuScenesMetric(BaseMetric):
print(f'Evaluating bboxes of {name}') print(f'Evaluating bboxes of {name}')
ret_dict = self._evaluate_single( ret_dict = self._evaluate_single(
result_dict[name], classes=classes, result_name=name) result_dict[name], classes=classes, result_name=name)
metric_dict.update(ret_dict) metric_dict.update(ret_dict)
return metric_dict return metric_dict
def _evaluate_single( def _evaluate_single(
...@@ -286,10 +282,10 @@ class NuScenesMetric(BaseMetric): ...@@ -286,10 +282,10 @@ class NuScenesMetric(BaseMetric):
Defaults to None. Defaults to None.
Returns: Returns:
tuple: Returns (result_dict, tmp_dir), where `result_dict` is a tuple: Returns (result_dict, tmp_dir), where ``result_dict`` is a
dict containing the json filepaths, `tmp_dir` is the temporal dict containing the json filepaths, ``tmp_dir`` is the temporal
directory created for saving json files when directory created for saving json files when ``jsonfile_prefix`` is
`jsonfile_prefix` is not specified. not specified.
""" """
assert isinstance(results, list), 'results must be a list' assert isinstance(results, list), 'results must be a list'
...@@ -320,9 +316,9 @@ class NuScenesMetric(BaseMetric): ...@@ -320,9 +316,9 @@ class NuScenesMetric(BaseMetric):
"""Get attribute from predicted index. """Get attribute from predicted index.
This is a workaround to predict attribute when the predicted velocity This is a workaround to predict attribute when the predicted velocity
is not reliable. We map the predicted attribute index to the one is not reliable. We map the predicted attribute index to the one in the
in the attribute set. If it is consistent with the category, we will attribute set. If it is consistent with the category, we will keep it.
keep it. Otherwise, we will use the default attribute. Otherwise, we will use the default attribute.
Args: Args:
attr_idx (int): Attribute index. attr_idx (int): Attribute index.
...@@ -376,8 +372,8 @@ class NuScenesMetric(BaseMetric): ...@@ -376,8 +372,8 @@ class NuScenesMetric(BaseMetric):
classes (List[str], optional): A list of class name. classes (List[str], optional): A list of class name.
Defaults to None. Defaults to None.
jsonfile_prefix (str, optional): The prefix of the output jsonfile. jsonfile_prefix (str, optional): The prefix of the output jsonfile.
You can specify the output directory/filename by You can specify the output directory/filename by modifying the
modifying the jsonfile_prefix. Defaults to None. jsonfile_prefix. Defaults to None.
Returns: Returns:
str: Path of the output json file. str: Path of the output json file.
...@@ -499,8 +495,8 @@ class NuScenesMetric(BaseMetric): ...@@ -499,8 +495,8 @@ class NuScenesMetric(BaseMetric):
classes (List[str], optional): A list of class name. classes (List[str], optional): A list of class name.
Defaults to None. Defaults to None.
jsonfile_prefix (str, optional): The prefix of the output jsonfile. jsonfile_prefix (str, optional): The prefix of the output jsonfile.
You can specify the output directory/filename by You can specify the output directory/filename by modifying the
modifying the jsonfile_prefix. Defaults to None. jsonfile_prefix. Defaults to None.
Returns: Returns:
str: Path of the output json file. str: Path of the output json file.
...@@ -573,8 +569,8 @@ def output_to_nusc_box( ...@@ -573,8 +569,8 @@ def output_to_nusc_box(
- labels_3d (torch.Tensor): Predicted box labels. - labels_3d (torch.Tensor): Predicted box labels.
Returns: Returns:
Tuple[List[:obj:`NuScenesBox`], np.ndarray or None]: Tuple[List[:obj:`NuScenesBox`], np.ndarray or None]: List of standard
List of standard NuScenesBoxes and attribute labels. NuScenesBoxes and attribute labels.
""" """
bbox3d = detection['bboxes_3d'] bbox3d = detection['bboxes_3d']
scores = detection['scores_3d'].numpy() scores = detection['scores_3d'].numpy()
...@@ -640,8 +636,8 @@ def lidar_nusc_box_to_global( ...@@ -640,8 +636,8 @@ def lidar_nusc_box_to_global(
"""Convert the box from ego to global coordinate. """Convert the box from ego to global coordinate.
Args: Args:
info (dict): Info for a specific sample data, including the info (dict): Info for a specific sample data, including the calibration
calibration information. information.
boxes (List[:obj:`NuScenesBox`]): List of predicted NuScenesBoxes. boxes (List[:obj:`NuScenesBox`]): List of predicted NuScenesBoxes.
classes (List[str]): Mapped classes in the evaluation. classes (List[str]): Mapped classes in the evaluation.
eval_configs (:obj:`DetectionConfig`): Evaluation configuration object. eval_configs (:obj:`DetectionConfig`): Evaluation configuration object.
...@@ -683,8 +679,8 @@ def cam_nusc_box_to_global( ...@@ -683,8 +679,8 @@ def cam_nusc_box_to_global(
"""Convert the box from camera to global coordinate. """Convert the box from camera to global coordinate.
Args: Args:
info (dict): Info for a specific sample data, including the info (dict): Info for a specific sample data, including the calibration
calibration information. information.
boxes (List[:obj:`NuScenesBox`]): List of predicted NuScenesBoxes. boxes (List[:obj:`NuScenesBox`]): List of predicted NuScenesBoxes.
attrs (np.ndarray): Predicted attributes. attrs (np.ndarray): Predicted attributes.
classes (List[str]): Mapped classes in the evaluation. classes (List[str]): Mapped classes in the evaluation.
...@@ -692,9 +688,8 @@ def cam_nusc_box_to_global( ...@@ -692,9 +688,8 @@ def cam_nusc_box_to_global(
camera_type (str): Type of camera. Defaults to 'CAM_FRONT'. camera_type (str): Type of camera. Defaults to 'CAM_FRONT'.
Returns: Returns:
Tuple[List[:obj:`NuScenesBox`], List[int]]: Tuple[List[:obj:`NuScenesBox`], List[int]]: List of standard
List of standard NuScenesBoxes in the global coordinate and NuScenesBoxes in the global coordinate and attribute label.
attribute label.
""" """
box_list = [] box_list = []
attr_list = [] attr_list = []
...@@ -726,15 +721,15 @@ def global_nusc_box_to_cam(info: dict, boxes: List[NuScenesBox], ...@@ -726,15 +721,15 @@ def global_nusc_box_to_cam(info: dict, boxes: List[NuScenesBox],
"""Convert the box from global to camera coordinate. """Convert the box from global to camera coordinate.
Args: Args:
info (dict): Info for a specific sample data, including the info (dict): Info for a specific sample data, including the calibration
calibration information. information.
boxes (List[:obj:`NuScenesBox`]): List of predicted NuScenesBoxes. boxes (List[:obj:`NuScenesBox`]): List of predicted NuScenesBoxes.
classes (List[str]): Mapped classes in the evaluation. classes (List[str]): Mapped classes in the evaluation.
eval_configs (:obj:`DetectionConfig`): Evaluation configuration object. eval_configs (:obj:`DetectionConfig`): Evaluation configuration object.
Returns: Returns:
List[:obj:`NuScenesBox`]: List of standard NuScenesBoxes in List[:obj:`NuScenesBox`]: List of standard NuScenesBoxes in camera
camera coordinate. coordinate.
""" """
box_list = [] box_list = []
for box in boxes: for box in boxes:
......
...@@ -24,30 +24,28 @@ class WaymoMetric(KittiMetric): ...@@ -24,30 +24,28 @@ class WaymoMetric(KittiMetric):
Args: Args:
ann_file (str): The path of the annotation file in kitti format. ann_file (str): The path of the annotation file in kitti format.
waymo_bin_file (str): The path of the annotation file in waymo format. waymo_bin_file (str): The path of the annotation file in waymo format.
data_root (str): Path of dataset root. data_root (str): Path of dataset root. Used for storing waymo
Used for storing waymo evaluation programs. evaluation programs.
split (str): The split of the evaluation set. Defaults to 'training'. split (str): The split of the evaluation set. Defaults to 'training'.
metric (str or List[str]): Metrics to be evaluated. metric (str or List[str]): Metrics to be evaluated. Defaults to 'mAP'.
Defaults to 'mAP'. pcd_limit_range (List[float]): The range of point cloud used to filter
pcd_limit_range (List[float]): The range of point cloud used to invalid predicted boxes. Defaults to [-85, -85, -5, 85, 85, 5].
filter invalid predicted boxes. convert_kitti_format (bool): Whether to convert the results to kitti
Defaults to [-85, -85, -5, 85, 85, 5]. format. Now, in order to be compatible with camera-based methods,
convert_kitti_format (bool): Whether to convert the results to defaults to True.
kitti format. Now, in order to be compatible with camera-based
methods, defaults to True.
prefix (str, optional): The prefix that will be added in the metric prefix (str, optional): The prefix that will be added in the metric
names to disambiguate homonymous metrics of different evaluators. names to disambiguate homonymous metrics of different evaluators.
If prefix is not provided in the argument, self.default_prefix If prefix is not provided in the argument, self.default_prefix will
will be used instead. Defaults to None. be used instead. Defaults to None.
format_only (bool): Format the output results without perform format_only (bool): Format the output results without perform
evaluation. It is useful when you want to format the result evaluation. It is useful when you want to format the result to a
to a specific format and submit it to the test server. specific format and submit it to the test server.
Defaults to False. Defaults to False.
pklfile_prefix (str, optional): The prefix of pkl files, including pklfile_prefix (str, optional): The prefix of pkl files, including the
the file path and the prefix of filename, e.g., "a/b/prefix". file path and the prefix of filename, e.g., "a/b/prefix". If not
If not specified, a temp file will be created. Defaults to None. specified, a temp file will be created. Defaults to None.
submission_prefix (str, optional): The prefix of submission data. submission_prefix (str, optional): The prefix of submission data. If
If not specified, the submission data will not be generated. not specified, the submission data will not be generated.
Defaults to None. Defaults to None.
load_type (str): Type of loading mode during training. load_type (str): Type of loading mode during training.
...@@ -55,19 +53,19 @@ class WaymoMetric(KittiMetric): ...@@ -55,19 +53,19 @@ class WaymoMetric(KittiMetric):
- 'mv_image_based': Load all of the instances in the frame and need - 'mv_image_based': Load all of the instances in the frame and need
to convert to the FOV-based data type to support image-based to convert to the FOV-based data type to support image-based
detector. detector.
- 'fov_image_based': Only load the instances inside the default - 'fov_image_based': Only load the instances inside the default cam
cam, and need to convert to the FOV-based data type to support and need to convert to the FOV-based data type to support image-
image-based detector. based detector.
default_cam_key (str): The default camera for lidar to camera default_cam_key (str): The default camera for lidar to camera
conversion. By default, KITTI: 'CAM2', Waymo: 'CAM_FRONT'. conversion. By default, KITTI: 'CAM2', Waymo: 'CAM_FRONT'.
Defaults to 'CAM_FRONT'. Defaults to 'CAM_FRONT'.
use_pred_sample_idx (bool): In formating results, use the use_pred_sample_idx (bool): In formating results, use the sample index
sample index from the prediction or from the load annotations. from the prediction or from the load annotations. By default,
By default, KITTI: True, Waymo: False, Waymo has a conversion KITTI: True, Waymo: False, Waymo has a conversion process, which
process, which needs to use the sample idx from load annotation. needs to use the sample idx from load annotation.
Defaults to False. Defaults to False.
collect_device (str): Device name used for collecting results collect_device (str): Device name used for collecting results from
from different ranks during distributed training. Must be 'cpu' or different ranks during distributed training. Must be 'cpu' or
'gpu'. Defaults to 'cpu'. 'gpu'. Defaults to 'cpu'.
backend_args (dict, optional): Arguments to instantiate the backend_args (dict, optional): Arguments to instantiate the
corresponding backend. Defaults to None. corresponding backend. Defaults to None.
...@@ -120,10 +118,9 @@ class WaymoMetric(KittiMetric): ...@@ -120,10 +118,9 @@ class WaymoMetric(KittiMetric):
backend_args=backend_args) backend_args=backend_args)
self.format_only = format_only self.format_only = format_only
if self.format_only: if self.format_only:
assert pklfile_prefix is not None, 'pklfile_prefix must be ' assert pklfile_prefix is not None, 'pklfile_prefix must be not '
'not None when format_only is True, otherwise the result files ' 'None when format_only is True, otherwise the result files will '
'will be saved to a temp directory which will be cleaned up at ' 'be saved to a temp directory which will be cleaned up at the end.'
'the end.'
self.default_prefix = 'Waymo metric' self.default_prefix = 'Waymo metric'
...@@ -216,8 +213,8 @@ class WaymoMetric(KittiMetric): ...@@ -216,8 +213,8 @@ class WaymoMetric(KittiMetric):
pklfile_prefix (str): The location that stored the prediction pklfile_prefix (str): The location that stored the prediction
results. results.
metric (str, optional): Metric to be evaluated. Defaults to None. metric (str, optional): Metric to be evaluated. Defaults to None.
logger (MMLogger, optional): Logger used for printing logger (MMLogger, optional): Logger used for printing related
related information during evaluation. Defaults to None. information during evaluation. Defaults to None.
Returns: Returns:
Dict[str, float]: Results of each evaluation metric. Dict[str, float]: Results of each evaluation metric.
...@@ -348,9 +345,9 @@ class WaymoMetric(KittiMetric): ...@@ -348,9 +345,9 @@ class WaymoMetric(KittiMetric):
Defaults to None. Defaults to None.
Returns: Returns:
tuple: (result_dict, tmp_dir), result_dict is a dict containing tuple: (result_dict, tmp_dir), result_dict is a dict containing the
the formatted result, tmp_dir is the temporal directory created formatted result, tmp_dir is the temporal directory created for
for saving json files when jsonfile_prefix is not specified. saving json files when jsonfile_prefix is not specified.
""" """
waymo_save_tmp_dir = tempfile.TemporaryDirectory() waymo_save_tmp_dir = tempfile.TemporaryDirectory()
waymo_results_save_dir = waymo_save_tmp_dir.name waymo_results_save_dir = waymo_save_tmp_dir.name
...@@ -401,8 +398,8 @@ class WaymoMetric(KittiMetric): ...@@ -401,8 +398,8 @@ class WaymoMetric(KittiMetric):
"""Merge bounding boxes predicted from multi-view images. """Merge bounding boxes predicted from multi-view images.
Args: Args:
box_dict_per_frame (List[dict]): The results of prediction box_dict_per_frame (List[dict]): The results of prediction for each
for each camera. camera.
cam0_info (dict): Store the sample idx for the given frame. cam0_info (dict): Store the sample idx for the given frame.
Returns: Returns:
...@@ -475,8 +472,8 @@ class WaymoMetric(KittiMetric): ...@@ -475,8 +472,8 @@ class WaymoMetric(KittiMetric):
submission. submission.
Args: Args:
net_outputs (List[dict]): List of dict storing the net_outputs (List[dict]): List of dict storing the inferenced
inferenced bounding boxes and scores. bounding boxes and scores.
sample_idx_list (List[int]): List of input sample idx. sample_idx_list (List[int]): List of input sample idx.
class_names (List[str]): A list of class names. class_names (List[str]): A list of class names.
pklfile_prefix (str, optional): The prefix of pkl file. pklfile_prefix (str, optional): The prefix of pkl file.
...@@ -625,14 +622,13 @@ class WaymoMetric(KittiMetric): ...@@ -625,14 +622,13 @@ class WaymoMetric(KittiMetric):
Returns: Returns:
dict: Valid predicted boxes. dict: Valid predicted boxes.
- bbox (np.ndarray): 2D bounding boxes. - bbox (np.ndarray): 2D bounding boxes.
- box3d_camera (np.ndarray): 3D bounding boxes in - box3d_camera (np.ndarray): 3D bounding boxes in camera
camera coordinate. coordinate.
- box3d_lidar (np.ndarray): 3D bounding boxes in - box3d_lidar (np.ndarray): 3D bounding boxes in LiDAR coordinate.
LiDAR coordinate. - scores (np.ndarray): Scores of boxes.
- scores (np.ndarray): Scores of boxes. - label_preds (np.ndarray): Class label predictions.
- label_preds (np.ndarray): Class label predictions. - sample_idx (int): Sample index.
- sample_idx (int): Sample index.
""" """
# TODO: refactor this function # TODO: refactor this function
box_preds = box_dict['bboxes_3d'] box_preds = box_dict['bboxes_3d']
......
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