def filter_regions_volume(input_mask, threshold=0.5, min_volume=10): """ Remove regions with region volume < min_volume. Optionally, an initial threshold is applied to binarize probabilities before filtering. Inputs: - mask: 3D np.ndarray - threshold: binarize parameter (def: 0.5) - min_volume: Minimum region size used for filtering (in voxels) (def: 10) Output: - mask: 3D np.ndarray mask > threshold where regions < 10 have been filtered """ mask = input_mask >= threshold regions, num_regions = label(mask) labels = np.arange(1, num_regions + 1) output_mask = np.zeros_like(mask) prob_mask = np.zeros(mask.shape) if num_regions > 0: region_vol = lc(mask, regions, labels, np.sum, int, 0) for l in labels: if region_vol[l - 1] > min_volume: current_voxels = np.stack(np.where(regions == l), axis=1) int_mean = np.median(input_mask[current_voxels[:, 0], current_voxels[:, 1], current_voxels[:, 2]]) output_mask[current_voxels[:, 0], current_voxels[:, 1], current_voxels[:, 2]] = 1 prob_mask[current_voxels[:, 0], current_voxels[:, 1], current_voxels[:, 2]] = int_mean return output_mask, prob_mask
def min_region(mask): """ compute the volume of the smallest region from an input mask Inputs: - mask: 3D np.ndarray, input MRI mask Output: - min_region: (int) the size of the minimum region volume. """ regions, num_regions = label(as_logical(mask)) labels = np.arange(1, num_regions + 1) mask = as_logical(mask) return np.min(lc(mask, regions, labels, np.sum, int, 0)) \ if num_regions > 0 else 0
def regionprops(mask): """ Get region properties Inputs: - mask: 3D np.ndarray, input MRI mask Output: - regions: 3D np.ndarray, labeled version of the input mask array where each region is labeled with a unique label - labels: list of unique labels - volumes: list with region volumes """ regions, num_regions = label(as_logical(mask)) labels = np.arange(1, num_regions + 1) volumes = lc(regions > 0, regions, labels, np.sum, int, 0) return regions, labels, volumes
def false_positive_det(gt, mask): """ compute the number of false positive regions between a input mask an a ground truth (GT) mask Inputs: - gt: 3D np.ndarray, reference image (ground truth) - mask: 3D np.ndarray, input MRI mask Output: - (int) number of false positive regions between the input and gt mask """ regions, num_regions = label(as_logical(mask)) labels = np.arange(1, num_regions + 1) gt = as_logical(gt) return np.sum(lc(gt, regions, labels, np.sum, int, 0) == 0) \ if num_regions > 0 else 0
def true_positive_det(gt, mask): """ compute the number of positive regions between a input mask an a ground truth (GT) mask Inputs: - gt: 3D np.ndarray, reference image (ground truth) - mask: 3D np.ndarray, input MRI mask Output: - (int) number of true positive regions between the input and gt mask """ regions, num_regions = label(as_logical(gt)) labels = np.arange(1, num_regions + 1) mask = as_logical(mask) tpr = lc(mask, regions, labels, np.sum, int, 0) return np.sum(tpr > 0)
def compute_lfp(gt, pred): """compute the number of false positive lesions between a input mask an a ground truth (GT) mask. By Sergi Valverde Parameters ---------- gt : numpy array Ground truth volume. Must have dtype=np.uint8 pred : numpy array Predicted segmentation. Must have dtype=np.uint8 Returns ------- int lesion-wise false positives """ regions, num_regions = label(pred.astype(np.bool)) labels = np.arange(1, num_regions+1) gt = gt.astype(np.bool) return np.sum(lc(gt, regions, labels, np.sum, int, 0) == 0) \ if num_regions > 0 else 0
def compute_ltp(gt, pred): """compute the number of positive regions between a input mask an a ground truth (GT) mask By Sergi Valverde Parameters ---------- gt : numpy array Ground truth volume. Must have dtype=np.uint8 pred : numpy array Predicted segmentation. Must have dtype=np.uint8 Returns ------- int lesion-wise true positives """ regions, num_regions = label(gt.astype(np.bool)) labels = np.arange(1, num_regions+1) pred = pred.astype(np.bool) tpr = lc(pred, regions, labels, np.sum, int, 0) return np.sum(tpr > 0)
def __post_process_skull(self, input_mask): """ post process input mask - fill holes in 2D - take the biggest region the final brainmask """ # fill holes in 2D for s in range(input_mask.shape[2]): input_mask[:, :, s] = fill_holes(input_mask[:, :, s]) # get the biggest region regions, num_regions = label(input_mask > 0) labels = np.arange(1, num_regions + 1) output_mask = np.zeros_like(input_mask) max_region = np.argmax( lc(input_mask > 0, regions, labels, np.sum, int, 0)) + 1 current_voxels = np.stack(np.where(regions == max_region), axis=1) output_mask[current_voxels[:, 0], current_voxels[:, 1], current_voxels[:, 2]] = 1 return output_mask