def test_ellipse_fitting(self, name='insitu7545', table_prob=TABLE_FB_PROBA): """ """ img, _ = tl_data.load_image_2d(os.path.join(PATH_IMAGES, name + '.jpg')) seg, _ = tl_data.load_image_2d(os.path.join(PATH_SEGM, name + '.png')) annot, _ = tl_data.load_image_2d( os.path.join(PATH_ANNOT, name + '.png')) path_center = os.path.join(PATH_CENTRE, name + '.csv') centers = pd.read_csv(path_center, index_col=0).values[:, [1, 0]] slic, points_all, labels = seg_fit.get_slic_points_labels( seg, slic_size=20, slic_regul=0.3) weights = np.bincount(slic.ravel()) points_centers = seg_fit.prepare_boundary_points_ray_edge( seg, centers, close_points=5) segm = np.zeros(seg.shape) ellipses, crits = [], [] for i, points in enumerate(points_centers): model, _ = seg_fit.ransac_segm(points, seg_fit.EllipseModelSegm, points_all, weights, labels, table_prob, min_samples=0.6, residual_threshold=15, max_trials=50) if model is None: continue ellipses.append(model.params) crit = model.criterion(points_all, weights, labels, table_prob) crits.append(np.round(crit)) logging.info('model params: %s', repr(model.params)) logging.info('-> crit: %f', crit) c1, c2, h, w, phi = model.params rr, cc = tl_visu.ellipse(int(c1), int(c2), int(h), int(w), phi, segm.shape) segm[rr, cc] = (i + 1) if img.ndim == 3: img = img[:, :, 0] fig = tl_visu.figure_ellipse_fitting(img, seg, ellipses, centers, crits) fig_name = 'ellipse-fitting_%s.pdf' % name fig.savefig(os.path.join(PATH_OUTPUT, fig_name), bbox_inches='tight', pad_inches=0) plt.close(fig) score = adjusted_rand_score(annot.ravel(), segm.ravel()) self.assertGreaterEqual(score, 0.5)
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