from itertools import combinations from typing import List from cv_analysis.utils import until, make_merger_sentinel from cv_analysis.utils.rectangle import Rectangle from cv_analysis.utils.spacial import is_related def connect_related_rectangles(rectangles: List[Rectangle]) -> List[Rectangle]: assert isinstance(rectangles, list) no_new_merges = make_merger_sentinel() return until(no_new_merges, merge_rectangles_once, rectangles) def merge_rectangles_once(rectangles: List[Rectangle]) -> List[Rectangle]: for alpha, beta in combinations(rectangles, 2): if is_related(alpha, beta): rectangles.remove(alpha) rectangles.remove(beta) rectangles.append(bounding_rect(alpha, beta)) return rectangles return rectangles def bounding_rect(alpha: Rectangle, beta: Rectangle) -> Rectangle: return Rectangle( min(alpha.x1, beta.x1), min(alpha.y1, beta.y1), max(alpha.x2, beta.x2), max(alpha.y2, beta.y2), )