Beispiel #1
0
    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)
Beispiel #2
0
def add_overlap_ellipse(segm, ellipse_params, label, thr_overlap=1.):
    """ add to existing image ellipse with specific label
    if the new ellipse does not ouvelap with already existing object / ellipse

    :param ndarray segm: segmentation
    :param tuple ellipse_params: parameters
    :param int label: selected label
    :param float thr_overlap: relative overlap with existing objects
    :return ndarray:

    >>> seg = np.zeros((15, 20), dtype=int)
    >>> ell_params = 7, 10, 5, 8, np.deg2rad(30)
    >>> ell = add_overlap_ellipse(seg, ell_params, 1)
    >>> ell
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
    >>> ell2_params = 4, 5, 2, 3, np.deg2rad(-30)
    >>> add_overlap_ellipse(ell, ell2_params, 2)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
    """
    if not ellipse_params:
        return segm
    mask = np.zeros(segm.shape)
    c1, c2, h, w, phi = ellipse_params
    rr, cc = ellipse(int(c1),
                     int(c2),
                     int(h),
                     int(w),
                     orientation=phi,
                     shape=segm.shape)
    mask[rr, cc] = 1

    # filter overlapping ellipses
    for lb in range(1, int(np.max(segm) + 1)):
        overlap = np.sum(np.logical_and(segm == lb, mask == 1))
        # together = np.sum(np.logical_or(segm == lb, mask == 1))
        # ratio = float(overlap) / float(together)
        sizes = [s for s in [np.sum(segm == lb), np.sum(mask == 1)] if s > 0]
        if not sizes:
            return segm
        ratio = float(overlap) / float(min(sizes))
        # if there is already ellipse with such size, return just the segment
        if ratio > thr_overlap:
            return segm
    segm[mask == 1] = label
    return segm