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