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
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
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) )