Example #1
0
def test_contingency_table():
    seg = np.array([0, 1, 1, 1, 2, 2, 2, 3])
    gt = np.array([1, 1, 1, 2, 2, 2, 2, 0])
    ct = ev.contingency_table(seg, gt, ignore_seg=[], ignore_gt=[])
    ct0 = ev.contingency_table(seg, gt, ignore_seg=[0], ignore_gt=[0])
    ctd = ct.todense()
    assert_equal(
        ctd,
        np.array([[0., 0.125, 0.], [0., 0.25, 0.125], [0., 0., 0.375],
                  [0.125, 0., 0.]]))
    assert ct.shape == ct0.shape
Example #2
0
def test_contingency_table():
    seg = np.array([0, 1, 1, 1, 2, 2, 2, 3])
    gt = np.array([1, 1, 1, 2, 2, 2, 2, 0])
    ct = ev.contingency_table(seg, gt, ignore_seg=[], ignore_gt=[])
    ct0 = ev.contingency_table(seg, gt, ignore_seg=[0], ignore_gt=[0])
    ctd = ct.todense()
    assert_equal(ctd, np.array([[0.   , 0.125, 0.   ],
                                [0.   , 0.25 , 0.125],
                                [0.   , 0.   , 0.375],
                                [0.125, 0.   , 0.   ]]))
    assert ct.shape == ct0.shape
Example #3
0
def show_greatest_vi(seg, gt):
    (worst_false_merges, merge_ents, worst_false_splits, split_ents) = evaluate.sorted_vi_components(seg, gt)

    print "Total entropy of false merges: %f" % sum(merge_ents)
    print "Total entropy of false splits: %f" % sum(split_ents)

    worst_false_splits = worst_false_splits[:LIST_CAP]
    split_ents = split_ents[:LIST_CAP]
    worst_false_merges = worst_false_merges[:LIST_CAP]
    merge_ents = merge_ents[:LIST_CAP]

    # for label, entropies in [("merges", merge_ents), ("splits", split_ents)]:
    #     print "For worst false %s, top %d biggest entropies:" % (label, len(entropies))
    #     for rank, entropy in enumerate(entropies):
    #         print "    %d. %f" % (rank, entropy)

    # handle worst false splits
    print worst_false_splits
    cont_table = evaluate.contingency_table(seg, gt)
    # view_biggest_cross_section(gt, [worst_false_splits[0]])

    # for bad_merge_id_in_seg in worst_false_merges[1:3]:
    #     overlaps = evaluate.split_components(bad_merge_id_in_seg, cont_table, axis=0)
    #     print "bad_merge_id_in_seg:",bad_merge_id_in_seg
    #     print overlaps
    #     overlap_ids = [gt_id for gt_id, perc_of_bad_split, perc_in_bad_split in overlaps]
    #     view_bad_merge(seg, gt, bad_merge_id_in_seg, overlap_ids)

    for bad_split_id_in_gt in worst_false_splits[:1]:
        overlaps = evaluate.split_components(bad_split_id_in_gt, cont_table, axis=1)
        print "bad_split_id_in_gt:", bad_split_id_in_gt
        print overlaps
        overlap_ids = [seg_id for seg_id, perc_of_bad_split, perc_in_bad_split in overlaps]
        view_bad_split(seg, gt, bad_split_id_in_gt, overlap_ids)
Example #4
0
def view_all_join(gt, automated_seg, num_elem=6, axis=None):
    """Generate an interactive figure highlighting the VI error.

    Parameters
    ----------
    gt: nd-array with shape M*N.
        This corresponds to the 'ground truth'.
    auto: nd-array with same shape as gt. This
        corresponds to the automated segmentation.
    num_elem: Int, optional.
        This parameter determines the number of comps
        shown upon click. Set to output '4' by default.

    Returns
    -------
    A window with six panels - the top middle image corresponds to the
    components that are the worst false merges in the automated
    segmentation, which share significant area with the clicked-upon segment.
    Likewise, the top middle image shows the worst false splits.
    """
    if gt.shape != automated_seg.shape:
        return "Input arrays are not of the same shape."
    elif (type(gt) or type(automated_seg)) != np.ndarray:
        return "Input arrays not of valid type."
    vint = np.vectorize(int)
    # Compute the join seg of the automatic seg and the ground truth.
    joint_seg = join_segmentations(automated_seg, gt)
    # Contingency table for merges
    cont_table_m = ev.contingency_table(automated_seg, joint_seg)
    # Contingency table for splits
    cont_table_s = ev.contingency_table(joint_seg, gt)
    # Sort the VI according to the largest false merge components.
    merge_idxs_m, merge_errs_m = ev.sorted_vi_components(
        joint_seg, automated_seg)[0:2]  #merges
    #Sort the VI according to the largest false split components.
    split_idxs_s, split_errs_s = ev.sorted_vi_components(joint_seg,
                                                         gt)[0:2]  #split
    #Find the indices of these largest false merge components, and largest false splits, in descending order.
    merge_idxs_sorted, split_idxs_sorted = np.argsort(
        merge_idxs_m), np.argsort(split_idxs_s)
    #Sort the errors according to the indices.
    merge_unsorted, split_unsorted = merge_errs_m[
        merge_idxs_sorted], split_errs_s[split_idxs_sorted]
    # Color both the seg and gt according to the intensity of the split VI error.
    merge_err_img, split_err_img = merge_unsorted[
        automated_seg], split_unsorted[gt]

    if axis is None:
        fig, ax = plt.subplots(nrows=2, ncols=3, sharex=True, sharey=True)
        plt.setp(ax.flat, adjustable='box-forced')
    else:
        fig, ax = plt.subplots(nrows=len(axis) // 2,
                               ncols=len(axis) // 2,
                               sharex=True,
                               sharey=True)
        for i in range(len(axis) // 2):
            ax[0, i] = ax[i]
        for i in range(0, (len(axis) // 2)):
            ax[1, i] = ax[i + 2]

    ax[0, 0].imshow(RAW)
    viz.imshow_magma(merge_err_img, alpha=0.4, axis=ax[0, 0])
    ax[0, 1].imshow(RAW)
    axes_image_1 = viz.imshow_rand(joint_seg, alpha=0.4, axis=ax[0, 1])
    ax[0, 2].imshow(RAW)
    viz.imshow_rand(gt, alpha=0.4, axis=ax[0, 2])
    ax[1, 0].imshow(RAW)
    viz.imshow_magma(split_err_img, alpha=0.4, axis=ax[1, 0])
    ax[1, 1].imshow(RAW)
    axes_image = viz.imshow_rand(joint_seg, alpha=0.4, axis=ax[1, 1])
    ax[1, 2].imshow(RAW)
    viz.imshow_rand(automated_seg, alpha=0.4, axis=ax[1, 2])
    ax[0, 0].set_title(
        "Worst merge comps colored by VI error: click to show them on second panel."
    )
    ax[0, 1].set_title("Worst merge comps.")
    ax[0, 2].set_title("Ground Truth.")
    ax[1, 0].set_title(
        "Worst split comps colored by VI error: click to show them on second panel."
    )
    ax[1, 1].set_title("Worst split comps.")
    ax[1, 2].set_title("Automated Seg.")

    @jit
    def drawer(seg, comps, limit=True):
        """Dynamically redraw the worst split/merge comps."""
        a_seg = np.zeros_like(seg.astype('float64'))
        factor = (seg.max() // num_elem)
        lim = 0.0
        for i, (j, k, z) in enumerate(comps):
            lim += k
            if z < 0.01:
                continue
            a_seg += (seg == j) * ((i + 1) * factor)
            if limit:
                if lim >= 0.98:
                    break
        return a_seg

    @jit
    def _onpress(event):
        """Matplotlib 'onpress' event handler."""

        if not (event.inaxes == ax[1, 0] or event.inaxes == ax[0, 0]
                or event.inaxes == ax[0, 2] or event.inaxes == ax[1, 2]):
            fig.text(0.5,
                     0.5,
                     s="Must click on left or right axes to show comps!",
                     ha="center")
            fig.canvas.draw_idle()
        if event.inaxes == ax[0, 0] or event.inaxes == ax[0, 2]:
            if event.button != 1:
                return
            for txt in fig.texts:
                txt.set_visible(False)
            fig.canvas.draw()
            x, y = vint(event.xdata), vint(event.ydata)
            # Find the indices of the false merge bodies overlapping with the coordinates of the mouse click.
            worst_merge_comps_m = ev.split_components(automated_seg[y, x],
                                                      num_elems=None,
                                                      cont=cont_table_m,
                                                      axis=0)
            new_seg_m = drawer(joint_seg, worst_merge_comps_m, limit=False)
            axes_image_1.set_array(new_seg_m)

            fig.canvas.draw()

        if event.inaxes == ax[1, 0] or event.inaxes == ax[1, 2]:
            if event.button != 1:
                return
            for txt in fig.texts:
                txt.set_visible(False)
            fig.canvas.draw()
            x, y = vint(event.xdata), vint(event.ydata)
            # Find the indices of the false split bodies overlapping with the coordinates of the mouse click.
            worst_split_comps_s = ev.split_components(gt[y, x],
                                                      num_elems=None,
                                                      cont=cont_table_s,
                                                      axis=1)
            new_seg_s = drawer(joint_seg, worst_split_comps_s)
            axes_image.set_array(new_seg_s)

            fig.canvas.draw()

    fig.canvas.mpl_connect('button_press_event', _onpress)
    plt.ioff()
    plt.show()
Example #5
0
def view_all(gt, automated_seg, num_elem=6, axis=None):
    """Generate an interactive figure highlighting the VI error.

    Parameters
    ----------
    gt: nd-array with shape M*N.
        This corresponds to the 'ground truth'.
    auto: nd-array with same shape as gt. This
        corresponds to the automated segmentation.
    num_elem: Int, optional.
        This parameter determines the number of comps
        shown upon click. Set to output '6' by default.

    Returns
    -------
    A panel with six images - the top middle image corresponds to the
    components that are the worst false merges in the automated
    segmentation, which share significant area with the clicked-upon segment.
    Likewise, the top middle image shows the worst false splits.
    """
    if gt.shape != automated_seg.shape:
        return "Input arrays are not of the same shape."
    elif (type(gt) or type(automated_seg)) != np.ndarray:
        return "Input arrays not of valid type."
    vint = np.vectorize(int)

    cont = ev.contingency_table(automated_seg, gt)
    ii1, err1, ii2, err2 = ev.sorted_vi_components(automated_seg, gt)
    idxs1, idxs2 = np.argsort(ii1), np.argsort(ii2)
    err_unsorted, err_unsorted_2 = err1[idxs1], err2[idxs2]
    err_img, err_img_1 = err_unsorted[gt], err_unsorted_2[automated_seg]

    if axis is None:
        fig, ax = plt.subplots(nrows=2, ncols=3, sharex=True, sharey=True)
        plt.setp(ax.flat, adjustable='box-forced')
    else:
        fig, ax = plt.subplots(nrows=len(axis) // 2,
                               ncols=len(axis) // 2,
                               sharex=True,
                               sharey=True)
        for i in range(len(axis) // 2):
            ax[0, i] = ax[i]
        for i in range(0, (len(axis) // 2)):
            ax[1, i] = ax[i + 2]

    ax[0, 0].imshow(RAW)
    viz.imshow_magma(err_img_1, alpha=0.4, axis=ax[0, 0])
    ax[0, 1].imshow(RAW)
    axes_image_1 = viz.imshow_rand(automated_seg, alpha=0.4, axis=ax[0, 1])
    ax[0, 2].imshow(RAW)
    viz.imshow_rand(gt, alpha=0.4, axis=ax[0, 2])
    ax[1, 0].imshow(RAW)
    viz.imshow_magma(err_img, alpha=0.4, axis=ax[1, 0])
    ax[1, 1].imshow(RAW)
    axes_image = viz.imshow_rand(automated_seg, alpha=0.4, axis=ax[1, 1])
    ax[1, 2].imshow(RAW)
    viz.imshow_rand(automated_seg, alpha=0.4, axis=ax[1, 2])
    ax[0, 0].set_title(
        "Worst merge comps colored by VI error: click to show them on second panel."
    )
    ax[0, 1].set_title("Worst merge comps.")
    ax[0, 2].set_title("Ground Truth.")
    ax[1, 0].set_title(
        "Worst split comps colored by VI error: click to show them on second panel."
    )
    ax[1, 1].set_title("Worst split comps.")
    ax[1, 2].set_title("Automated Seg.")

    @jit
    def drawer(seg, comps, limit=True):
        """Dynamically redraw the worst split/merge comps."""
        a_seg = np.zeros_like(seg.astype('float64'))
        factor = (seg.max() // num_elem)
        lim = 0.0
        for i, (j, k, z) in enumerate(comps):
            lim += k
            # if the area of the component is too small, we don't want to show it.
            if z < 0.01:
                continue
            a_seg += (seg == j) * ((i + 1) * factor)
            if limit:
                # Limit the number of components that are shown.
                if lim >= 0.98:
                    break
        return a_seg

    @jit
    def _onpress(event):
        """Matplotlib 'onpress' event handler."""

        if not (event.inaxes == ax[1, 0] or event.inaxes == ax[0, 0]
                or event.inaxes == ax[0, 2] or event.inaxes == ax[1, 2]):
            fig.text(0.5,
                     0.5,
                     s="Must click on left or right axes to show comps!",
                     ha="center")
            fig.canvas.draw_idle()
        if event.inaxes == ax[0, 0] or event.inaxes == ax[0, 2]:
            if event.button != 1:
                return
            for txt in fig.texts:
                txt.set_visible(False)
            fig.canvas.draw()
            x, y = vint(event.xdata), vint(event.ydata)
            # Identify the worst merge components that are being pointed at by the mouse click.
            comps = ev.split_components(automated_seg[y, x],
                                        cont,
                                        axis=0,
                                        num_elems=None)
            # Create the image containing only the identified components.
            new_seg_1 = drawer(gt, comps, limit=False)
            # Update the image with the drawn components
            axes_image_1.set_array(new_seg_1)
            # Draw this new image with the highlighted components onto the screen.
            fig.canvas.draw()

        if event.inaxes == ax[1, 0] or event.inaxes == ax[1, 2]:
            if event.button != 1:
                return
            for txt in fig.texts:
                txt.set_visible(False)
            fig.canvas.draw()
            x, y = vint(event.xdata), vint(event.ydata)
            # Identify the worst split components that are being pointed at by the mouse click.
            comps = ev.split_components(gt[y, x], cont, axis=1, num_elems=None)
            # Create the image containing only the identified components.
            new_seg = drawer(automated_seg, comps)
            # Update the image with the drawn components
            axes_image.set_array(new_seg)
            # Draw this new image with the highlighted components onto the screen.
            fig.canvas.draw()

    fig.canvas.mpl_connect('button_press_event', _onpress)
    plt.ioff()
    plt.show()