65 lines
1.8 KiB
Python
65 lines
1.8 KiB
Python
from functools import lru_cache
|
|
from itertools import groupby
|
|
|
|
import numpy as np
|
|
from funcy import compose, second
|
|
|
|
from image_prediction.stitching.utils import make_coord_getter
|
|
|
|
|
|
class CoordGrouper:
|
|
def __init__(self, axis, tolerance=0):
|
|
self.c1_getter = make_coord_getter(f"{other_axis(axis)}1")
|
|
self.c2_getter = make_coord_getter(f"{other_axis(axis)}2")
|
|
self.tolerance = tolerance
|
|
|
|
def group_pairs_by_lesser_coordinate(self, pairs):
|
|
return group_by_coordinate(pairs, self.c1_getter, self.tolerance)
|
|
|
|
def group_pairs_by_greater_coordinate(self, pairs):
|
|
return group_by_coordinate(pairs, self.c2_getter, self.tolerance)
|
|
|
|
|
|
def other_axis(axis):
|
|
return "y" if axis == "x" else "x"
|
|
|
|
|
|
def fuzzify(func, tolerance):
|
|
def inner(item):
|
|
nonlocal mid_points
|
|
nonlocal lower_bounds
|
|
nonlocal upper_bounds
|
|
print(tolerance)
|
|
|
|
value = func(item)
|
|
fits = (array(lower_bounds_array()) <= value) & (value <= array(upper_bounds_array()))
|
|
if any(fits):
|
|
return mid_points[np.argmax(fits)]
|
|
else:
|
|
mid_points = [*mid_points, value]
|
|
lower_bounds = [*lower_bounds, value - tolerance]
|
|
upper_bounds = [*upper_bounds, value + tolerance]
|
|
return value
|
|
|
|
def lower_bounds_array():
|
|
return tuple(lower_bounds)
|
|
|
|
def upper_bounds_array():
|
|
return tuple(upper_bounds)
|
|
|
|
@lru_cache(maxsize=None)
|
|
def array(tpl):
|
|
return np.array(tpl)
|
|
|
|
lower_bounds = []
|
|
upper_bounds = []
|
|
mid_points = []
|
|
|
|
return inner
|
|
|
|
|
|
def group_by_coordinate(pairs, coord_getter, tolerance=0):
|
|
coord_getter = fuzzify(coord_getter, tolerance)
|
|
pairs = sorted(pairs, key=coord_getter)
|
|
return map(compose(list, second), groupby(pairs, coord_getter))
|