|
|
|
import warnings |
|
from typing import Sequence |
|
|
|
from mmengine.evaluator import DumpResults |
|
from mmengine.evaluator.metric import _to_cpu |
|
|
|
from mmdet.registry import METRICS |
|
from mmdet.structures.mask import encode_mask_results |
|
|
|
|
|
@METRICS.register_module() |
|
class DumpDetResults(DumpResults): |
|
"""Dump model predictions to a pickle file for offline evaluation. |
|
|
|
Different from `DumpResults` in MMEngine, it compresses instance |
|
segmentation masks into RLE format. |
|
|
|
Args: |
|
out_file_path (str): Path of the dumped file. Must end with '.pkl' |
|
or '.pickle'. |
|
collect_device (str): Device name used for collecting results from |
|
different ranks during distributed training. Must be 'cpu' or |
|
'gpu'. Defaults to 'cpu'. |
|
""" |
|
|
|
def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: |
|
"""transfer tensors in predictions to CPU.""" |
|
data_samples = _to_cpu(data_samples) |
|
for data_sample in data_samples: |
|
|
|
data_sample.pop('gt_instances', None) |
|
data_sample.pop('ignored_instances', None) |
|
data_sample.pop('gt_panoptic_seg', None) |
|
|
|
if 'pred_instances' in data_sample: |
|
pred = data_sample['pred_instances'] |
|
|
|
if 'masks' in pred: |
|
pred['masks'] = encode_mask_results(pred['masks'].numpy()) |
|
if 'pred_panoptic_seg' in data_sample: |
|
warnings.warn( |
|
'Panoptic segmentation map will not be compressed. ' |
|
'The dumped file will be extremely large! ' |
|
'Suggest using `CocoPanopticMetric` to save the coco ' |
|
'format json and segmentation png files directly.') |
|
self.results.extend(data_samples) |
|
|