Source code for mmdet.evaluation.metrics.dump_odvg_results
# Copyright (c) OpenMMLab. All rights reserved.
from typing import Any, Optional, Sequence
from mmcv.ops import batched_nms
from mmengine.evaluator import BaseMetric
from mmengine.logging import print_log
from mmdet.registry import METRICS
try:
import jsonlines
except ImportError:
jsonlines = None
[docs]@METRICS.register_module()
class DumpODVGResults(BaseMetric):
default_prefix: Optional[str] = 'pl_odvg'
def __init__(self,
outfile_path,
img_prefix: str,
score_thr: float = 0.1,
collect_device: str = 'cpu',
nms_thr: float = 0.5,
prefix: Optional[str] = None) -> None:
super().__init__(collect_device=collect_device, prefix=prefix)
self.outfile_path = outfile_path
self.score_thr = score_thr
self.img_prefix = img_prefix
self.nms_thr = nms_thr
if jsonlines is None:
raise ImportError('Please run "pip install jsonlines" to install '
'this package.')
[docs] def process(self, data_batch: Any, data_samples: Sequence[dict]) -> None:
for data_sample in data_samples:
result = {}
filename = data_sample['img_path']
filename = filename.replace(self.img_prefix, '')
if filename.startswith('/'):
filename = filename[1:]
result['filename'] = filename
height = data_sample['ori_shape'][0]
width = data_sample['ori_shape'][1]
result['height'] = height
result['width'] = width
pred_instances = data_sample['pred_instances']
bboxes = pred_instances['bboxes'].cpu()
scores = pred_instances['scores'].cpu()
labels = pred_instances['labels'].cpu()
bboxes = bboxes[scores > self.score_thr]
labels = labels[scores > self.score_thr]
scores = scores[scores > self.score_thr]
if 'tokens_positive' in data_sample:
task = 'vg'
else:
task = 'od'
if task == 'od':
classes_name = data_sample['text']
result['detection'] = {}
if len(bboxes) > 0:
det_bboxes, keep = batched_nms(
bboxes, scores, labels,
dict(type='nms', iou_threshold=self.nms_thr))
_scores = det_bboxes[:, -1]
_bboxes = det_bboxes[:, :-1]
_labels = labels[keep]
instances = []
_bboxes = _bboxes.numpy().tolist()
_scores = _scores.numpy().tolist()
_labels = _labels.numpy().tolist()
for bbox, score, label in zip(_bboxes, _scores, _labels):
round_bbox = [round(b, 2) for b in bbox]
round_score = round(score, 2)
instances.append({
'bbox': round_bbox,
'score': round_score,
'label': label,
'category': classes_name[label]
})
result['detection']['instances'] = instances
else:
result['detection']['instances'] = []
self.results.append(result)
else:
caption = data_sample['text']
result['grounding'] = {}
result['grounding']['caption'] = caption
tokens_positive = data_sample['tokens_positive']
region_list = []
for label, positive in enumerate(tokens_positive):
phrase = [caption[pos[0]:pos[1]] for pos in positive]
_bboxes = bboxes[labels == label]
_scores = scores[labels == label]
det_bboxes, _ = batched_nms(
_bboxes,
_scores,
None,
dict(type='nms', iou_threshold=self.nms_thr),
class_agnostic=True)
_scores = det_bboxes[:, -1].numpy().tolist()
_bboxes = det_bboxes[:, :-1].numpy().tolist()
round_bboxes = []
for bbox in _bboxes:
round_bboxes.append([round(b, 2) for b in bbox])
_scores = [[round(s, 2) for s in _scores]]
region = {
'phrase': phrase,
'bbox': round_bboxes,
'score': _scores,
'tokens_positive': positive
}
region_list.append(region)
result['grounding']['regions'] = region_list
self.results.append(result)
[docs] def compute_metrics(self, results: list) -> dict:
with jsonlines.open(self.outfile_path, mode='w') as writer:
writer.write_all(results)
print_log(
f'Results has been saved to {self.outfile_path}.',
logger='current')
return {}