Exemple #1
0
def seg_to_small_seg(seg, thres=25, rr=2):
    # rr: z/x-y resolution ratio
    sz = seg.shape
    mask = np.zeros(sz, np.uint8)
    for z in np.where(seg.max(axis=1).max(axis=1) > 0)[0]:
        tmp = label_cc(seg[z])
        ui, uc = np.unique(tmp, return_counts=True)
        rl = np.zeros(ui[-1] + 1, np.uint8)
        rl[ui[uc < thres]] = 1
        rl[0] = 0
        mask[z] += rl[tmp]
    for y in np.where(seg.max(axis=2).max(axis=0) > 0)[0]:
        tmp = label_cc(seg[:, y])
        ui, uc = np.unique(tmp, return_counts=True)
        rl = np.zeros(ui[-1] + 1, np.uint8)
        rl[ui[uc < thres // rr]] = 1
        rl[0] = 0
        mask[:, y] += rl[tmp]
    for x in np.where(seg.max(axis=0).max(axis=0) > 0)[0]:
        tmp = label_cc(seg[:, :, x])
        ui, uc = np.unique(tmp, return_counts=True)
        rl = np.zeros(ui[-1] + 1, np.uint8)
        rl[ui[uc < thres // rr]] = 1
        rl[0] = 0
        mask[:, :, x] += rl[tmp]
    return mask
def distance_transform(label: np.ndarray,
                       bg_value: float = -1.0,
                       relabel: bool = True,
                       padding: bool = False,
                       resolution: Tuple[float] = (1.0, 1.0)):
    """Euclidean distance transform (DT or EDT) for instance masks.
    """
    eps = 1e-6
    pad_size = 2

    if relabel:
        label = label_cc(label)

    if padding:
        # The distance_transform_edt function does not treat image border
        # as background. If image border needs to be considered as background
        # in distance calculation, set padding to True.
        label = np.pad(label, pad_size, mode='constant', constant_values=0)

    label_shape = label.shape
    all_bg_sample = False
    distance = np.zeros(label_shape, dtype=np.float32) + bg_value
    semantic = np.zeros(label_shape, dtype=np.uint8)

    indices = np.unique(label)
    if indices[0] == 0:
        if len(indices) > 1:  # exclude background
            indices = indices[1:]
        else:  # all-background sample
            all_bg_sample = True

    if not all_bg_sample:
        for idx in indices:
            temp1 = label.copy() == idx
            temp2 = remove_small_holes(temp1, 16, connectivity=1)

            semantic += temp2.astype(np.uint8)
            boundary_edt = distance_transform_edt(temp2, resolution)
            energy = boundary_edt / (boundary_edt.max() + eps)  # normalize
            distance = np.maximum(distance, energy * temp2.astype(np.float32))

    if padding:
        # Unpad the output array to preserve original shape.
        distance = array_unpad(distance, get_padsize(
            pad_size, ndim=distance.ndim))
        semantic = array_unpad(semantic, get_padsize(
            pad_size, ndim=distance.ndim))

    return distance, semantic
def syn_sem2inst(label: np.array):
    # For synaptic polarity, convert semantic annotation to instance
    # annotation. It assumes the pre- and post-synaptic masks are
    # closely in touch with their parteners.
    indices = np.unique(label)
    assert list(indices) == [0, 1, 2]

    fg = (label != 0).astype(bool)
    struct = disk(2, dtype=bool)[np.newaxis, :, :]  # only for xy plane
    fg = binary_dilation(fg, struct)
    segm = label_cc(fg).astype(int)

    seg_pos = (label == 1).astype(segm.dtype)
    seg_neg = (label == 2).astype(segm.dtype)

    seg_pos = seg_pos * (segm * 2 - 1)
    seg_neg = seg_neg * (segm * 2)
    instance_label = np.maximum(seg_pos, seg_neg)

    # Cast the mask to the best dtype to save storage.
    max_id = np.amax(np.unique(instance_label))
    m_type = getSegType(int(max_id))
    return instance_label.astype(m_type)