Isaac Riley beb40da3b1 Pull request #22: add single-cell filtering to table parsing and increase tolerance parameter to 7; refactor postprocessing to use the Rectangles data structure
Merge in RR/cv-analysis from remove_isolated to master

Squashed commit of the following:

commit 2613ed1615d1b69b3e4f2acea197993a91d00561
Author: Isaac Riley <Isaac.Riley@iqser.com>
Date:   Tue Aug 2 10:17:33 2022 +0200

    add single-cell filtering to table parsing and increase tolerance parameter to 7; refactored postprocessing to use the Rectangles data structure
2022-08-02 10:54:13 +02:00

51 lines
1.9 KiB
Python

from collections import namedtuple
from functools import partial
from itertools import starmap, compress
from typing import Iterable
from cv_analysis.utils.structures import Rectangle
def remove_overlapping(rectangles: Iterable[Rectangle]) -> list[Rectangle]:
def overlap(a: Rectangle, rect2: Rectangle) -> float:
return a.intersection(rect2) > 0
def does_not_overlap(rect: Rectangle, rectangles: Iterable[Rectangle]) -> list:
return not any(overlap(rect, rect2) for rect2 in rectangles if not rect == rect2)
rectangles = list(filter(partial(does_not_overlap, rectangles=rectangles), rectangles))
return rectangles
def remove_included(rectangles: Iterable[Rectangle]) -> list[Rectangle]:
rectangles = list(filter(partial(Rectangle.is_not_included, rectangles=rectangles), rectangles))
return rectangles
def __remove_isolated_unsorted(rectangles: Iterable[Rectangle]) -> list[Rectangle]:
def is_connected(rect: Rectangle, rectangles: Iterable[Rectangle]):
return any(rect.adjacent(rect2) for rect2 in rectangles if not rect == rect2)
rectangles = list(filter(partial(is_connected, rectangles=list(rectangles)), rectangles))
return rectangles
def __remove_isolated_sorted(rectangles: Iterable[Rectangle]) -> list[Rectangle]:
def is_connected(left, center, right):
return any([left.adjacent(center), center.adjacent(right)])
rectangles = list(rectangles)
lefts = [None, *rectangles[:-1]]
rights = [*rectangles[1:], None]
mask = starmap(is_connected, zip(lefts, rectangles, rights))
rectangles = list(compress(rectangles, mask))
return rectangles
def remove_isolated(rectangles: Iterable[Rectangle], input_unsorted=True) -> list[Rectangle]:
return (__remove_isolated_unsorted if input_unsorted else __remove_isolated_sorted)(rectangles)
def has_no_parent(hierarchy):
return hierarchy[-1] <= 0