from typing import Iterable import numpy as np from cv_analysis.utils.structures import Rectangle def find_max_overlap(box: Rectangle, box_list: Iterable[Rectangle]): best_candidate = max(box_list, key=lambda x: box.iou(x)) iou = box.iou(best_candidate) return best_candidate, iou def compute_page_iou(results_boxes: Iterable[Rectangle], ground_truth_boxes: Iterable[Rectangle]): results = list(results_boxes) truth = list(ground_truth_boxes) if (not results) or (not truth): return 0 iou_sum = 0 denominator = max(len(results), len(truth)) while results and truth: gt_box = truth.pop() best_match, best_iou = find_max_overlap(gt_box, results) results.remove(best_match) iou_sum += best_iou score = iou_sum / denominator return score def compute_document_score(results_dict, annotation_dict): page_weights = np.array([len(page["cells"]) for page in annotation_dict["pages"]]) page_weights = page_weights / sum(page_weights) scores = [] for i in range(len(annotation_dict["pages"])): scores.append( compute_page_iou( map(Rectangle.from_dict_xywh, results_dict["pages"][i]["cells"]), map(Rectangle.from_dict_xywh, annotation_dict["pages"][i]["cells"]), ) ) doc_score = np.average(np.array(scores), weights=page_weights) return doc_score """ from cv_analysis.utils.test_metrics import * r1 = Rectangle.from_dict_xywh({'x': 30, 'y': 40, 'width': 50, 'height': 60}) r2 = Rectangle.from_dict_xywh({'x': 40, 'y': 30, 'width': 55, 'height': 65}) r3 = Rectangle.from_dict_xywh({'x': 45, 'y': 35, 'width': 45, 'height': 55}) r4 = Rectangle.from_dict_xywh({'x': 25, 'y': 45, 'width': 45, 'height': 55}) d1 = {"pages": [{"cells": [r1.json_xywh(), r2.json_xywh()]}]} d2 = {"pages": [{"cells": [r3.json_xywh(), r4.json_xywh()]}]} compute_iou_from_boxes(r1, r2) find_max_overlap(r1, [r2, r3, r4]) compute_page_iou([r1, r2], [r3, r4]) compute_document_score(d1, d2) """