Shortcuts

Note

You are reading the documentation for MMOCR 0.x, which will soon be deprecated by the end of 2022. We recommend you upgrade to MMOCR 1.0 to enjoy fruitful new features and better performance brought by OpenMMLab 2.0. Check out the maintenance plan, changelog, code and documentation of MMOCR 1.0 for more details.

Source code for mmocr.core.evaluation.hmean

# Copyright (c) OpenMMLab. All rights reserved.
import warnings
from operator import itemgetter

import mmcv
import numpy as np
from mmcv.utils import print_log

import mmocr.utils as utils
from mmocr.core.evaluation import hmean_ic13, hmean_iou
from mmocr.core.evaluation.utils import (filter_2dlist_result,
                                         select_top_boundary)
from mmocr.core.mask import extract_boundary


def output_ranklist(img_results, img_infos, out_file):
    """Output the worst results for debugging.

    Args:
        img_results (list[dict]): Image result list.
        img_infos (list[dict]): Image information list.
        out_file (str): The output file path.

    Returns:
        sorted_results (list[dict]): Image results sorted by hmean.
    """
    assert utils.is_type_list(img_results, dict)
    assert utils.is_type_list(img_infos, dict)
    assert isinstance(out_file, str)
    assert out_file.endswith('json')

    sorted_results = []
    for idx, result in enumerate(img_results):
        name = img_infos[idx]['file_name']
        img_result = result
        img_result['file_name'] = name
        sorted_results.append(img_result)
    sorted_results = sorted(
        sorted_results, key=itemgetter('hmean'), reverse=False)

    mmcv.dump(sorted_results, file=out_file)

    return sorted_results


def get_gt_masks(ann_infos):
    """Get ground truth masks and ignored masks.

    Args:
        ann_infos (list[dict]): Each dict contains annotation
            infos of one image, containing following keys:
            masks, masks_ignore.
    Returns:
        gt_masks (list[list[list[int]]]): Ground truth masks.
        gt_masks_ignore (list[list[list[int]]]): Ignored masks.
    """
    assert utils.is_type_list(ann_infos, dict)

    gt_masks = []
    gt_masks_ignore = []
    for ann_info in ann_infos:
        masks = ann_info['masks']
        mask_gt = []
        for mask in masks:
            assert len(mask[0]) >= 8 and len(mask[0]) % 2 == 0
            mask_gt.append(mask[0])
        gt_masks.append(mask_gt)

        masks_ignore = ann_info['masks_ignore']
        mask_gt_ignore = []
        for mask_ignore in masks_ignore:
            assert len(mask_ignore[0]) >= 8 and len(mask_ignore[0]) % 2 == 0
            mask_gt_ignore.append(mask_ignore[0])
        gt_masks_ignore.append(mask_gt_ignore)

    return gt_masks, gt_masks_ignore


[docs]def eval_hmean(results, img_infos, ann_infos, metrics={'hmean-iou'}, score_thr=None, min_score_thr=0.3, max_score_thr=0.9, step=0.1, rank_list=None, logger=None, **kwargs): """Evaluation in hmean metric. It conducts grid search over a range of boundary score thresholds and reports the best result. Args: results (list[dict]): Each dict corresponds to one image, containing the following keys: boundary_result img_infos (list[dict]): Each dict corresponds to one image, containing the following keys: filename, height, width ann_infos (list[dict]): Each dict corresponds to one image, containing the following keys: masks, masks_ignore score_thr (float): Deprecated. Please use min_score_thr instead. min_score_thr (float): Minimum score threshold of prediction map. max_score_thr (float): Maximum score threshold of prediction map. step (float): The spacing between score thresholds. metrics (set{str}): Hmean metric set, should be one or all of {'hmean-iou', 'hmean-ic13'} Returns: dict[str: float] """ assert utils.is_type_list(results, dict) assert utils.is_type_list(img_infos, dict) assert utils.is_type_list(ann_infos, dict) if score_thr: warnings.warn('score_thr is deprecated. Please use min_score_thr ' 'instead.') min_score_thr = score_thr assert 0 <= min_score_thr <= max_score_thr <= 1 assert 0 <= step <= 1 assert len(results) == len(img_infos) == len(ann_infos) assert isinstance(metrics, set) min_score_thr = float(min_score_thr) max_score_thr = float(max_score_thr) step = float(step) gts, gts_ignore = get_gt_masks(ann_infos) preds = [] pred_scores = [] for result in results: _, texts, scores = extract_boundary(result) if len(texts) > 0: assert utils.valid_boundary(texts[0], False) valid_texts, valid_text_scores = filter_2dlist_result( texts, scores, min_score_thr) preds.append(valid_texts) pred_scores.append(valid_text_scores) eval_results = {} for metric in metrics: msg = f'Evaluating {metric}...' if logger is None: msg = '\n' + msg print_log(msg, logger=logger) best_result = dict(hmean=-1) for thr in np.arange(min_score_thr, min(max_score_thr + step, 1.0), step): top_preds = select_top_boundary(preds, pred_scores, thr) if metric == 'hmean-iou': result, img_result = hmean_iou.eval_hmean_iou( top_preds, gts, gts_ignore) elif metric == 'hmean-ic13': result, img_result = hmean_ic13.eval_hmean_ic13( top_preds, gts, gts_ignore) else: raise NotImplementedError if rank_list is not None: output_ranklist(img_result, img_infos, rank_list) print_log( 'thr {0:.2f}, recall: {1[recall]:.3f}, ' 'precision: {1[precision]:.3f}, ' 'hmean: {1[hmean]:.3f}'.format(thr, result), logger=logger) if result['hmean'] > best_result['hmean']: best_result = result eval_results[metric + ':recall'] = best_result['recall'] eval_results[metric + ':precision'] = best_result['precision'] eval_results[metric + ':hmean'] = best_result['hmean'] return eval_results
Read the Docs v: v0.6.3
Versions
latest
stable
v0.6.3
v0.6.2
v0.6.1
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.1
v0.2.0
v0.1.0
dev-1.x
Downloads
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.