예제 #1
0
def get_cnn_centers(names, labels_names, balanced=True, neigh_width=15):
    rois = list(load_masks(names))
    rois_p = list(load_masks(labels_names))
    rois_p_neigh = [log_and(log_and(imdilate(roi_p, iterations=neigh_width), log_not(roi_p)), roi)
                    for roi, roi_p in izip(rois, rois_p)]
    rois_n_global = [log_and(roi, log_not(log_or(roi_pn, roi_p)))
                     for roi, roi_pn, roi_p in izip(rois, rois_p_neigh, rois_p)]
    rois = list()
    for roi_pn, roi_ng, roi_p in izip(rois_p_neigh, rois_n_global, rois_p):
        # The goal of this for is to randomly select the same number of nonlesion and lesion samples for each image.
        # We also want to make sure that we select the same number of boundary negatives and general negatives to
        # try to account for the variability in the brain.
        n_positive = np.count_nonzero(roi_p)
        if balanced:
            roi_pn[roi_pn] = np.random.permutation(xrange(np.count_nonzero(roi_pn))) < n_positive / 2
        roi_ng[roi_ng] = np.random.permutation(xrange(np.count_nonzero(roi_ng))) < n_positive / 2
        rois.append(log_or(log_or(roi_ng, roi_pn), roi_p))

    # In order to be able to permute the centers to randomly select them, or just shuffle them for training, we need
    # to keep the image reference with the center. That's why we are doing the next following lines of code.
    centers_list = [get_mask_voxels(roi) for roi in rois]
    idx_lesion_centers = np.concatenate([np.array([(i, c) for c in centers], dtype=object)
                                         for i, centers in enumerate(centers_list)])

    return idx_lesion_centers
예제 #2
0
def get_slices_boundary(masks, patch_size, rois=None, rate=0.1):
    patch_half = map(lambda p_length: p_length // 2, patch_size)
    boundaries = map(
        lambda m: map(lambda l: log_and(m == l, log_not(imerode(m == l))),
                      range(1,
                            m.max() + 1)), masks)

    max_shape = masks[0].shape
    mesh = get_mesh(max_shape)
    legal_mask = reduce(
        np.logical_and,
        map(
            lambda (m_j, p_ij, max_j): np.logical_and(m_j >= p_ij, m_j <= max_j
                                                      - p_ij),
            zip(mesh, patch_half, max_shape)))

    boundaries = map(
        lambda b: map(lambda b_i: np.logical_and(b_i, legal_mask), b),
        boundaries)

    centers = map(
        lambda b: np.concatenate(filter(
            lambda arr: arr.size > 0,
            map(
                lambda b_i: np.random.permutation(zip(*np.where(b_i)))[:int(
                    np.sum(b_i) * rate)], b)),
                                 axis=0), boundaries)

    patch_slices = map(lambda c: centers_to_slice(c, patch_half), centers)

    return patch_slices
예제 #3
0
    def __init__(self, cases, labels, rois, patch_size=32, flip=False):
        # Init
        # Image and mask should be numpy arrays
        self.cases = cases
        self.labels = labels
        self.flip = flip

        data_shape = self.cases[0].shape

        if type(patch_size) is not tuple:
            patch_size = (patch_size, ) * len(data_shape)
        self.patch_size = patch_size

        self.patch_slices_pos = get_slices_mask_bb(self.labels, patch_size,
                                                   patch_size[0] - 8)

        brains = map(
            lambda
            (l, r): log_and(log_not(l.astype(np.bool)), r.astype(np.bool)),
            zip(labels, rois))

        patch_slices_neg = get_slices_mask_bb(brains, patch_size,
                                              patch_size[0] - 8)
        self.patch_slices_neg = map(
            lambda (pos, neg): map(lambda idx: neg[idx],
                                   np.random.permutation(len(neg))[:len(pos)]),
            zip(self.patch_slices_pos, patch_slices_neg))

        self.max_slice = np.cumsum(map(len, self.patch_slices_pos))
def test_seg_validation(net_name):
    # Init
    c = color_codes()
    options = parse_inputs()
    depth = options['blocks']
    filters = options['filters']
    d_path = options['loo_dir']
    v_path = options['val_dir']
    seg_path = os.path.join(v_path, 'segmentation')
    if not os.path.isdir(seg_path):
        os.mkdir(seg_path)
    unc_path = os.path.join(v_path, 'uncertainty')
    if not os.path.isdir(unc_path):
        os.mkdir(unc_path)
    p = get_dirs(d_path)[0]
    test_patients = filter(lambda p: 'BraTS19' in p, get_dirs(v_path))
    _, test_x = get_images(test_patients, True)

    print(
        'Testing patients = %d' % (
            len(test_patients)
        )
    )

    # The sub-regions considered for evaluation are:
    #   1) the "enhancing tumor" (ET)
    #   2) the "tumor core" (TC)
    #   3) the "whole tumor" (WT)
    #
    # The provided segmentation labels have values of 1 for NCR & NET,
    # 2 for ED, 4 for ET, and 0 for everything else.
    # The participants are called to upload their segmentation labels
    # as a single multi-label file in nifti (.nii.gz) format.
    #
    # The participants are called to upload 4 nifti (.nii.gz) volumes
    # (3 uncertainty maps and 1 multi-class segmentation volume from
    # Task 1) onto CBICA's Image Processing Portal format. For example,
    # for each ID in the dataset, participants are expected to upload
    # following 4 volumes:
    # 1. {ID}.nii.gz (multi-class label map)
    # 2. {ID}_unc_whole.nii.gz (Uncertainty map associated with whole tumor)
    # 3. {ID}_unc_core.nii.gz (Uncertainty map associated with tumor core)
    # 4. {ID}_unc_enhance.nii.gz (Uncertainty map associated with enhancing tumor)
    for i, (p_i, test_i) in enumerate(zip(test_patients, test_x)):
        t_in = time.time()
        # unc_i = np.zeros((4,) + test_i.shape[1:])
        pred_i = np.zeros((4,) + test_i.shape[1:])
        for f in range(5):
            model_name = '%s-f%d.mdl' % (net_name, f)
            net = BratsSegmentationNet(depth=depth, filters=filters)
            net.load_model(os.path.join(d_path, model_name))
        #
        #     unc_i += net.uncertainty([test_i], steps=10)[0] * 0.2
            pred_i += net.segment([test_i])[0]

        seg_i = np.argmax(pred_i, axis=0)
        seg_i[seg_i == 3] = 4
        # seg_unc_i = np.argmax(unc_i, axis=0)
        # seg_unc_i[seg_unc_i == 3] = 4

        tumor_mask = remove_small_regions(
            seg_i.astype(np.bool), min_size=30
        )

        seg_i[log_not(tumor_mask)] = 0
        # seg_unc_i[log_not(tumor_mask)] = 0
        #
        # whole_i = np.sum(unc_i[1:]) * tumor_mask.astype(np.float32)
        # core_i = unc_i[1] + unc_i[-1] * tumor_mask.astype(np.float32)
        # enhance_i = unc_i[-1] * tumor_mask.astype(np.float32)
        #
        # seg_unc_i = np.argmax(unc_i, axis=0)
        # seg_unc_i[seg_unc_i == 3] = 4

        niiname = os.path.join(d_path, p, p + '_seg.nii.gz')
        nii = load_nii(niiname)
        nii.get_data()[:] = seg_i
        save_nii(nii, os.path.join(seg_path, p_i + '.nii.gz'))
        # nii.get_data()[:] = seg_unc_i
        # save_nii(nii, os.path.join(unc_path, p_i + '.nii.gz'))

        # niiname = os.path.join(v_path, p_i, p_i + '_flair.nii.gz')
        # nii = load_nii(niiname)
        # nii.get_data()[:] = whole_i
        # save_nii(
        #     nii, os.path.join(unc_path, p_i + '_unc_whole.nii.gz')
        # )
        # nii.get_data()[:] = core_i
        # save_nii(
        #     nii, os.path.join(unc_path, p_i + '_unc_core.nii.gz')
        # )
        # nii.get_data()[:] = enhance_i
        # save_nii(
        #     nii, os.path.join(unc_path, p_i + '_unc_enhance.nii.gz')
        # )

        t_s = time_to_string(time.time() - t_in)

        print(
            'Finished patient %s (%d/%d) %s' % (p_i, i + 1, len(test_x), t_s)
        )