def prepare_boundary_points_ray_join(seg,
                                     centers,
                                     close_points=5,
                                     min_diam=MIN_ELLIPSE_DAIM,
                                     sel_bg=STRUC_ELEM_BG,
                                     sel_fg=STRUC_ELEM_FG):
    """ extract some point around foreground boundaries

    :param ndarray seg: input segmentation
    :param [(int, int)] centers: list of centers
    :param float close_points: remove closest point then a given threshold
    :param int min_diam: minimal size of expected objest
    :param int sel_bg: smoothing background with morphological operation
    :param int sel_fg: smoothing foreground with morphological operation
    :return [ndarray]:

    >>> seg = np.zeros((10, 20), dtype=int)
    >>> ell_params = 5, 10, 4, 6, np.deg2rad(30)
    >>> seg = add_overlap_ellipse(seg, ell_params, 1)
    >>> pts = prepare_boundary_points_ray_join(seg, [(4, 9)], 5, 3,
    ...                                        sel_bg=1, sel_fg=0)
    >>> np.round(pts).tolist()  # doctest: +NORMALIZE_WHITESPACE
    [[[4.0, 16.0],
      [7.0, 10.0],
      [9.0, 6.0],
      [1.0, 9.0],
      [4.0, 16.0],
      [7.0, 10.0],
      [1.0, 9.0]]]

    """
    seg_bg, seg_fg = split_segm_background_foreground(seg, sel_bg, sel_fg)

    points_centers = []
    for center in centers:
        ray_bg = seg_fts.compute_ray_features_segm_2d(seg_bg, center)
        ray_bg[ray_bg < min_diam] = min_diam
        points_bg = seg_fts.reconstruct_ray_features_2d(center, ray_bg)
        points_bg = seg_fts.reduce_close_points(points_bg, close_points)

        ray_fc = seg_fts.compute_ray_features_segm_2d(seg_fg,
                                                      center,
                                                      edge='down')
        ray_fc[ray_fc < min_diam] = min_diam
        points_fc = seg_fts.reconstruct_ray_features_2d(center, ray_fc)
        points_fc = seg_fts.reduce_close_points(points_fc, close_points)

        points_both = np.vstack((points_bg, points_fc))
        points_centers.append(points_both)
    return points_centers
def prepare_boundary_points_ray_mean(seg,
                                     centers,
                                     close_points=5,
                                     min_diam=MIN_ELLIPSE_DAIM,
                                     sel_bg=STRUC_ELEM_BG,
                                     sel_fg=STRUC_ELEM_FG):
    """ extract some point around foreground boundaries

    :param ndarray seg: input segmentation
    :param [(int, int)] centers: list of centers
    :param float close_points: remove closest point then a given threshold
    :param int min_diam: minimal size of expected objest
    :param int sel_bg: smoothing background with morphological operation
    :param int sel_fg: smoothing foreground with morphological operation
    :return [ndarray]:

    >>> seg = np.zeros((10, 20), dtype=int)
    >>> ell_params = 5, 10, 4, 6, np.deg2rad(30)
    >>> seg = add_overlap_ellipse(seg, ell_params, 1)
    >>> pts = prepare_boundary_points_ray_mean(seg, [(4, 9)], 5, 3,
    ...                                        sel_bg=1, sel_fg=0)
    >>> np.round(pts).tolist()  # doctest: +NORMALIZE_WHITESPACE
    [[[4.0, 16.0],
      [9.0, 6.0],
      [1.0, 9.0]]]
    """
    seg_bg, seg_fc = split_segm_background_foreground(seg, sel_bg, sel_fg)

    points_centers = []
    for center in centers:
        ray_bg = seg_fts.compute_ray_features_segm_2d(seg_bg, center)

        ray_fc = seg_fts.compute_ray_features_segm_2d(seg_fc,
                                                      center,
                                                      edge='down')

        # replace not found (-1) by large values
        rays = np.array([ray_bg, ray_fc], dtype=float)
        rays[rays < 0] = np.inf
        rays[rays < min_diam] = min_diam

        # take the smalles from both
        ray_min = np.min(rays, axis=0)
        ray_mean = np.mean(rays, axis=0)
        ray_mean[np.isinf(ray_mean)] = ray_min[np.isinf(ray_mean)]

        points_close = seg_fts.reconstruct_ray_features_2d(center, ray_mean)
        points_close = seg_fts.reduce_close_points(points_close, close_points)

        points_centers.append(points_close)
    return points_centers
def prepare_boundary_points_ray_dist(seg,
                                     centers,
                                     close_points=1,
                                     sel_bg=STRUC_ELEM_BG,
                                     sel_fg=STRUC_ELEM_FG):
    """ extract some point around foreground boundaries

    :param ndarray seg: input segmentation
    :param [(int, int)] centers: list of centers
    :param float close_points: remove closest point then a given threshold
    :param int sel_bg: smoothing background with morphological operation
    :param int sel_fg: smoothing foreground with morphological operation
    :return [ndarray]:

    >>> seg = np.zeros((10, 20), dtype=int)
    >>> ell_params = 5, 10, 4, 6, np.deg2rad(30)
    >>> seg = add_overlap_ellipse(seg, ell_params, 1)
    >>> pts = prepare_boundary_points_ray_dist(seg, [(4, 9)], 2,
    ...                                        sel_bg=0, sel_fg=0)
    >>> np.round(pts).tolist()  # doctest: +NORMALIZE_WHITESPACE
    [[[0.0, 2.0],
      [4.0, 16.0],
      [6.0, 15.0],
      [9.0, 6.0],
      [6.0, 5.0],
      [3.0, 7.0],
      [0.0, 10.0]]]
    """
    seg_bg, _ = split_segm_background_foreground(seg, sel_bg, sel_fg)

    points = np.array((0, np.asarray(centers).shape[1]))
    for center in centers:
        ray = seg_fts.compute_ray_features_segm_2d(seg_bg, center)
        points_bg = seg_fts.reconstruct_ray_features_2d(center, ray, 0)
        points_bg = seg_fts.reduce_close_points(points_bg, close_points)

        points = np.vstack((points, points_bg))

    dists = spatial.distance.cdist(points, centers, metric='euclidean')
    close_center = np.argmin(dists, axis=1)

    points_centers = []
    for i in range(close_center.max() + 1):
        pts = points[close_center == i]
        points_centers.append(pts)
    return points_centers