Beispiel #1
0
def compute_maximum_label_overlap(seg_a, seg_b, ignore_zeros=False):
    """ For each node in seg_a, compute the node in seg_b with
    the biggest overalp.
    """
    ids_a = np.unique(seg_a)
    overlaps = np.zeros(int(ids_a.max() + 1), dtype=seg_b.dtype)

    ovlp = ngt.overlap(seg_a, seg_b)
    ovlp = [ovlp.overlapArrays(id_a, True)[0] for id_a in ids_a]
    if ignore_zeros:
        ovlp = np.array([
            ovl[1] if (ovl[0] == 0 and len(ovl) > 1) else ovl[0]
            for ovl in ovlp
        ])
    else:
        ovlp = np.array([ovl[0] for ovl in ovlp])

    overlaps[ids_a] = ovlp
    return overlaps
Beispiel #2
0
def assign_superpixels_to_boutons():
    from nifty.ground_truth import overlap
    with h5py.File('./test_data.h5', 'r') as f:
        ws = f['watershed'][:]
        # boutons = f['boutons_corrected'][:]
        boutons = f['boutons'][:]
    boutons, _, _ = vigra.analysis.relabelConsecutive(boutons)

    ws_ids = np.unique(ws)
    ovlp = overlap(ws, boutons)
    ovlp = np.array([
        ovlp.overlapArrays(ws_id, True)[0][0] if ws_id in ws_ids else 0
        for ws_id in range(int(ws.max() + 1))
    ],
                    dtype='uint32')

    with h5py.File('./test_data.h5', 'a') as f:
        if 'bouton_overlaps' in f:
            del f['bouton_overlaps']
        f.create_dataset('bouton_overlaps', data=ovlp)
    def compute_overlaps(seg_a, seg_b, max_overlap=True):

        seg_ids = np.unique(seg_a)
        comp = ngt.overlap(seg_a, seg_b)
        overlaps = [comp.overlapArrays(ida, True) for ida in seg_ids]

        if max_overlap:
            # the max overlap can be ambiguous, need to filtr for this
            mask = np.array([
                ovlp[1][0] != ovlp[1][1] if ovlp[1].size > 1 else True
                for ovlp in overlaps
            ])
            overlaps = np.array([ovlp[0][0] for ovlp in overlaps])
            assert mask.shape == overlaps.shape
            return overlaps, mask
        else:
            overlaps = {
                seg_id: ovlp
                for seg_id, ovlp in zip(seg_ids, overlaps)
            }
            return overlaps
Beispiel #4
0
def lifted_problem_from_segmentation(rag,
                                     watershed,
                                     input_segmentation,
                                     overlap_threshold,
                                     graph_depth,
                                     same_segment_cost,
                                     different_segment_cost,
                                     mode='all',
                                     n_threads=None):
    """ Compute lifted problem from segmentation by mapping segments to
        watershed superpixels.

    Arguments:
        rag [RegionAdjacencyGraph] - the region adjacency graph
        watershed [np.ndarray] - the watershed over segmentation
        input_segmentation [np.ndarray] - Segmentation used to determine node attribution.
        overlap_threshold [float] - minimal overlap to assign a segment id to node
        graph_depth [int] - maximal graph depth up to which
            lifted edges will be included
        same_segment_cost [float] - costs for edges between nodes with same segment id attribution
        different_segment_cost [float] - costs for edges between nodes with different segment id attribution
        mode [str] - mode for insertion of lifted edges. Can be
            "all" - lifted edges will be inserted in between all nodes with attribution
            "different" - lifted edges will only be inserted in between nodes attributed to different classes
            "same" - lifted edges will only be inserted in between nodes attribted to the same class
            (default: "different")
        n_threads [int] - number of threads used for the calculation (default: None)
    """
    n_threads = multiprocessing.cpu_count() if n_threads is None else n_threads
    assert input_segmentation.shape == watershed.shape

    # compute the overlaps
    ovlp_comp = ngt.overlap(watershed, input_segmentation)
    ws_ids = np.unique(watershed)
    n_labels = ws_ids[-1] + 1
    assert n_labels == rag.numberOfNodes, "%i, %i" % (n_labels,
                                                      rag.numberOfNodes)

    # initialise the arrays for node labels, to be
    # dense in the watershed id space (even if some ws-ids are not present)
    node_labels = np.zeros(n_labels, dtype='uint64')

    # extract the overlap values and node labels from the overlap
    # computation results
    overlaps = [
        ovlp_comp.overlapArraysNormalized(ws_id, sorted=False)
        for ws_id in ws_ids
    ]
    node_label_vals = np.array([ovlp[0][0] for ovlp in overlaps])
    overlap_values = np.array([ovlp[1][0] for ovlp in overlaps])
    node_label_vals[overlap_values < overlap_threshold] = 0
    assert len(node_label_vals) == len(ws_ids)
    node_labels[ws_ids] = node_label_vals

    # find all lifted edges up to the graph depth between mapped nodes
    # NOTE we need to convert to the different graph type for now, but
    # it would be nice to support all nifty graphs at some type
    uv_ids = rag.uvIds()
    g_temp = ndist.Graph(uv_ids)

    lifted_uvs = ndist.liftedNeighborhoodFromNodeLabels(
        g_temp,
        node_labels,
        graph_depth,
        mode=mode,
        numberOfThreads=n_threads,
        ignoreLabel=0)
    # make sure that the lifted uv ids are in range of the node labels
    assert lifted_uvs.max() < rag.numberOfNodes, "%i, %i" % (int(
        lifted_uvs.max()), rag.numberOfNodes)
    lifted_labels = node_labels[lifted_uvs]
    lifted_costs = np.zeros_like(lifted_labels, dtype='float32')

    same_mask = lifted_labels[:, 0] == lifted_labels[:, 1]
    lifted_costs[same_mask] = same_segment_cost
    lifted_costs[~same_mask] = different_segment_cost

    return lifted_uvs, lifted_costs
def max_overlaps(a, b):
    ovlp = ngt.overlap(a, b)
    max_ols = [ovlp.overlapArrays(seg_id, sorted=True) for seg_id in range(int(a.max()) + 1)]
    max_ols = [max_ol[0][0] if len(max_ol[0]) > 0 else 0 for max_ol in max_ols]
    return np.array(max_ols, dtype='uint64')
Beispiel #6
0
def _stitch_face(offsets, overlap_prefix, block_a, block_b, face_a, face_b,
                 overlap_threshold, ignore_label):
    off_a = offsets[block_a]
    off_b = offsets[block_b]

    path_a = '%s_%i_%i.npy' % (overlap_prefix, block_a, block_b)
    path_b = '%s_%i_%i.npy' % (overlap_prefix, block_b, block_a)

    # overlaps might not exist because they are empty
    if (not os.path.exists(path_a)) or (not os.path.exists(path_b)):
        return None

    ovlp_a = np.load(path_a)
    ovlp_b = np.load(path_b)
    assert ovlp_a.shape == ovlp_b.shape, "%s, %s" % (str(
        ovlp_a.shape), str(ovlp_b.shape))

    # find the block face and the ids on the block face
    axis = vu.faces_to_ovlp_axis(face_a, face_b)
    face = tuple(
        slice(None) if dim != axis else slice(fa.stop - 1, fa.stop + 1)
        for dim, fa in enumerate(face_a))

    # find the ids ON the actual block boundary
    segments_a = np.unique(ovlp_a[face])
    segments_b = np.unique(ovlp_b[face])

    # 0 is ignore label, so we don't consider it here
    if segments_a[0] == 0:
        segments_a = segments_a[1:]
    if segments_b[0] == 0:
        segments_b = segments_b[1:]

    # measure all overlaps
    overlaps_ab = ngt.overlap(ovlp_a, ovlp_b)
    overlaps_ba = ngt.overlap(ovlp_b, ovlp_a)

    assignments = []
    # iterate over all segments on the face of block a
    for seg_a in segments_a:

        # get the segments of block b overlapping with seg_a
        ovlp_seg_a, counts_seg_a = overlaps_ab.overlapArraysNormalized(
            seg_a, sorted=True)
        if ignore_label is not None:
            ovlp_seg_a, counts_seg_a = _filter_ignore_label(
                ovlp_seg_a, counts_seg_a, ignore_label)

        seg_b = ovlp_seg_a[0]
        # continue if the max overlapping object is not on the face of block b
        if seg_b not in segments_b:
            continue

        # continue if the max overlapping objects do not agree
        ovlp_seg_b, counts_seg_b = overlaps_ba.overlapArraysNormalized(
            seg_b, sorted=True)
        if ignore_label is not None:
            ovlp_seg_b, counts_seg_b = _filter_ignore_label(
                ovlp_seg_b, counts_seg_b, ignore_label)
        if ovlp_seg_b[0] != seg_a:
            continue

        # merge the two ids if their mean overlap is larger than the overlap threshold
        ovlp_measure = (counts_seg_a[0] + counts_seg_b[0]) / 2.
        if ovlp_measure > overlap_threshold:
            assignments.append([seg_a + off_a, seg_b + off_b])

    if assignments:
        return np.array(assignments, dtype='uint64')
    else:
        return None