def segment_fit_ellipse(seg,
                        centers,
                        fn_preproc_points,
                        thr_overlap=SEGM_OVERLAP):
    """ segment eggs using ellipse fitting

    :param ndarray seg: input image / segmentation
    :param [[int, int]] centers: position of centres / seeds
    :param fn_preproc_points: function for detection boundary points
    :param float thr_overlap: threshold for removing overlapping segmentation
    :return ndarray, [[int, int]]: resulting segmentation, updated centres
    """
    points_centers = fn_preproc_points(seg, centers)

    centres_new, ell_params = [], []
    segm = np.zeros_like(seg)
    for i, points in enumerate(points_centers):
        lb = i + 1
        ellipse = EllipseModel()
        ellipse.estimate(points)
        if ellipse is None:
            continue
        logging.debug('ellipse params: %s', repr(ellipse.params))
        segm = ell_fit.add_overlap_ellipse(segm, ellipse.params, lb,
                                           thr_overlap)

        if np.any(segm == lb):
            centres_new.append(centers[i])
            ell_params.append(ellipse.params)

    dict_export = {
        'ellipses.csv':
        pd.DataFrame(ell_params, columns=['xc', 'yc', 'a', 'b', 'theta'])
    }
    return segm, np.array(centres_new), dict_export
def segment_fit_ellipse_ransac(seg, centers, fn_preproc_points, nb_inliers=0.6,
                               thr_overlap=SEGM_OVERLAP):
    """ segment eggs using ellipse fitting and RANDSAC strategy

    :param ndarray seg: input image / segmentation
    :param [[int, int]] centers: position of centres / seeds
    :param fn_preproc_points: function for detection boundary points
    :param float nb_inliers: ratio of inliers for RANSAC
    :param float thr_overlap: threshold for removing overlapping segmentations
    :return ndarray, [[int, int]]: resulting segmentation, updated centres
    """
    points_centers = fn_preproc_points(seg, centers)

    centres_new = []
    segm = np.zeros_like(seg)
    for i, points in enumerate(points_centers):
        lb = i + 1
        nb_min = int(len(points) * nb_inliers)
        ransac_model, _ = measure.ransac(points, EllipseModel,
                                         min_samples=nb_min,
                                         residual_threshold=15,
                                         max_trials=250)
        if ransac_model is None:
            continue
        logging.debug('ellipse params: %s', repr(ransac_model.params))
        segm = ell_fit.add_overlap_ellipse(segm, ransac_model.params, lb,
                                           thr_overlap)

        if np.any(segm == lb):
            centres_new.append(centers[i])
    return segm, np.array(centres_new)
def segment_fit_ellipse_ransac_segm(seg,
                                    centers,
                                    fn_preproc_points,
                                    table_p,
                                    nb_inliers=0.35,
                                    thr_overlap=SEGM_OVERLAP):
    """ segment eggs using ellipse fitting and RANDSAC strategy on segmentation

    :param ndarray seg: input image / segmentation
    :param [[int, int]] centers: position of centres / seeds
    :param fn_preproc_points: function for detection boundary points
    :param [[float]] table_p: table of probabilities being foreground / background
    :param float nb_inliers: ratio of inliers for RANSAC
    :param float thr_overlap: threshold for removing overlapping segmentations
    :return ndarray, [[int, int]]: resulting segmentation, updated centres
    """
    slic, points_all, labels = ell_fit.get_slic_points_labels(seg,
                                                              slic_size=15,
                                                              slic_regul=0.1)
    points_centers = fn_preproc_points(seg, centers)
    weights = np.bincount(slic.ravel())

    centres_new, ell_params = [], []
    segm = np.zeros_like(seg)
    for i, points in enumerate(points_centers):
        lb = i + 1
        ransac_model, _ = ell_fit.ransac_segm(points,
                                              ell_fit.EllipseModelSegm,
                                              points_all,
                                              weights,
                                              labels,
                                              table_p,
                                              min_samples=nb_inliers,
                                              residual_threshold=25,
                                              max_trials=250)
        if ransac_model is None:
            continue
        logging.debug('ellipse params: %s', repr(ransac_model.params))
        segm = ell_fit.add_overlap_ellipse(segm, ransac_model.params, lb,
                                           thr_overlap)

        if np.any(segm == lb):
            centres_new.append(centers[i])
            ell_params.append(ransac_model.params)

    dict_export = {
        'ellipses.csv':
        pd.DataFrame(ell_params, columns=['xc', 'yc', 'a', 'b', 'theta'])
    }
    return segm, np.array(centres_new), dict_export