Python scipy.ndimage.binary_fill_holes() Examples
The following are 24
code examples of scipy.ndimage.binary_fill_holes().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
scipy.ndimage
, or try the search function
.
Example #1
Source File: test_ndimage.py From Computable with MIT License | 6 votes |
def test_binary_fill_holes02(self): expected = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) data = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) out = ndimage.binary_fill_holes(data) assert_array_almost_equal(out, expected)
Example #2
Source File: winston_lutz.py From pylinac with MIT License | 6 votes |
def _find_field_centroid(self) -> Tuple[Point, List]: """Find the centroid of the radiation field based on a 50% height threshold. Returns ------- p The CAX point location. edges The bounding box of the field, plus a small margin. """ min, max = np.percentile(self.array, [5, 99.9]) threshold_img = self.as_binary((max - min)/2 + min) filled_img = ndimage.binary_fill_holes(threshold_img) # clean single-pixel noise from outside field cleaned_img = ndimage.binary_erosion(threshold_img) [*edges] = bounding_box(cleaned_img) edges[0] -= 10 edges[1] += 10 edges[2] -= 10 edges[3] += 10 coords = ndimage.measurements.center_of_mass(filled_img) p = Point(x=coords[-1], y=coords[0]) return p, edges
Example #3
Source File: utils.py From lungmask with GNU General Public License v3.0 | 6 votes |
def simple_bodymask(img): maskthreshold = -500 oshape = img.shape img = ndimage.zoom(img, 128/np.asarray(img.shape), order=0) bodymask = img > maskthreshold bodymask = ndimage.binary_closing(bodymask) bodymask = ndimage.binary_fill_holes(bodymask, structure=np.ones((3, 3))).astype(int) bodymask = ndimage.binary_erosion(bodymask, iterations=2) bodymask = skimage.measure.label(bodymask.astype(int), connectivity=1) regions = skimage.measure.regionprops(bodymask.astype(int)) if len(regions) > 0: max_region = np.argmax(list(map(lambda x: x.area, regions))) + 1 bodymask = bodymask == max_region bodymask = ndimage.binary_dilation(bodymask, iterations=2) real_scaling = np.asarray(oshape)/128 return ndimage.zoom(bodymask, real_scaling, order=0)
Example #4
Source File: locate_tissue.py From tissueloc with MIT License | 6 votes |
def fill_tissue_holes(bw_img): """ Filling holes in tissue image Parameters ---------- bw_img : np.array 2D binary image. Returns ------- bw_fill: np.array Binary image with no holes """ # Fill holes bw_fill = binary_fill_holes(bw_img) return bw_fill
Example #5
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 6 votes |
def test_binary_fill_holes03(self): expected = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 1, 1], [0, 0, 1, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0]], bool) data = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 1, 1], [0, 1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 0, 1], [0, 0, 1, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0]], bool) out = ndimage.binary_fill_holes(data) assert_array_almost_equal(out, expected)
Example #6
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 6 votes |
def test_binary_fill_holes02(self): expected = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) data = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) out = ndimage.binary_fill_holes(data) assert_array_almost_equal(out, expected)
Example #7
Source File: test_ndimage.py From Computable with MIT License | 6 votes |
def test_binary_fill_holes01(self): expected = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) data = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) out = ndimage.binary_fill_holes(data) assert_array_almost_equal(out, expected)
Example #8
Source File: test_ndimage.py From Computable with MIT License | 6 votes |
def test_binary_fill_holes03(self): expected = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 1, 1], [0, 0, 1, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0]], bool) data = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 1, 1], [0, 1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 0, 1], [0, 0, 1, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0]], bool) out = ndimage.binary_fill_holes(data) assert_array_almost_equal(out, expected)
Example #9
Source File: test_ndimage.py From GraphicDesignPatternByPython with MIT License | 6 votes |
def test_binary_fill_holes01(self): expected = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) data = numpy.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]], bool) out = ndimage.binary_fill_holes(data) assert_array_almost_equal(out, expected)
Example #10
Source File: binary.py From pyem with GNU General Public License v3.0 | 5 votes |
def binarize_volume(vol, t, minvol=0, fill=False): mask = vol >= t if minvol != 0: mask = binary_volume_opening(mask, minvol) if fill: mask = binary_fill_holes(mask) return mask
Example #11
Source File: custom_transforms.py From BraTS2017 with Apache License 2.0 | 5 votes |
def create_brain_masks(data, seg): shp = list(data.shape) num_seg = seg.shape[1] shp[1] += num_seg seg_with_brain_mask = np.zeros(shp, dtype=np.float32) seg_with_brain_mask[:, :num_seg] = seg for b in range(data.shape[0]): for c in range(data.shape[1]): this_mask = data[b, c] != 0 this_mask = binary_fill_holes(this_mask) seg_with_brain_mask[b, c + num_seg] = this_mask return seg_with_brain_mask
Example #12
Source File: utils_validation.py From BraTS2017 with Apache License 2.0 | 5 votes |
def create_brain_masks(data): shp = list(data.shape) brain_mask = np.zeros(shp, dtype=np.float32) for b in range(data.shape[0]): for c in range(data.shape[1]): this_mask = data[b, c] != 0 this_mask = binary_fill_holes(this_mask) brain_mask[b, c] = this_mask return brain_mask
Example #13
Source File: helpers.py From kaggle_ndsb2017 with MIT License | 5 votes |
def get_segmented_lungs(im, plot=False): # Step 1: Convert into a binary image. binary = im < -400 # Step 2: Remove the blobs connected to the border of the image. cleared = clear_border(binary) # Step 3: Label the image. label_image = label(cleared) # Step 4: Keep the labels with 2 largest areas. areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2: for region in regionprops(label_image): if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0 # Step 5: Erosion operation with a disk of radius 2. This operation is seperate the lung nodules attached to the blood vessels. selem = disk(2) binary = binary_erosion(binary, selem) # Step 6: Closure operation with a disk of radius 10. This operation is to keep nodules attached to the lung wall. selem = disk(10) # CHANGE BACK TO 10 binary = binary_closing(binary, selem) # Step 7: Fill in the small holes inside the binary mask of lungs. edges = roberts(binary) binary = ndi.binary_fill_holes(edges) # Step 8: Superimpose the binary mask on the input image. get_high_vals = binary == 0 im[get_high_vals] = -2000 return im, binary
Example #14
Source File: ocrd_anybaseocr_tiseg.py From ocrd_anybaseocr with Apache License 2.0 | 5 votes |
def pixMorphSequence_mask_seed_fill_holes(self, I): Imask = self.reduction_T_1(I) Imask = self.reduction_T_1(Imask) Imask = ndimage.binary_fill_holes(Imask) Iseed = self.reduction_T_4(Imask) Iseed = self.reduction_T_3(Iseed) mask = array(ones((5, 5)), dtype=int) Iseed = ndimage.binary_opening(Iseed, mask) Iseed = self.expansion(Iseed, Imask.shape) return Imask, Iseed
Example #15
Source File: ct.py From pylinac with MIT License | 5 votes |
def get_regions(slice_or_arr, fill_holes=False, clear_borders=True, threshold='otsu'): """Get the skimage regions of a black & white image.""" if threshold == 'otsu': thresmeth = filters.threshold_otsu elif threshold == 'mean': thresmeth = np.mean if isinstance(slice_or_arr, Slice): edges = filters.scharr(slice_or_arr.image.array.astype(np.float)) center = slice_or_arr.image.center elif isinstance(slice_or_arr, np.ndarray): edges = filters.scharr(slice_or_arr.astype(np.float)) center = (int(edges.shape[1]/2), int(edges.shape[0]/2)) edges = filters.gaussian(edges, sigma=1) if isinstance(slice_or_arr, Slice): box_size = 100/slice_or_arr.mm_per_pixel thres_img = edges[int(center.y-box_size):int(center.y+box_size), int(center.x-box_size):int(center.x+box_size)] thres = thresmeth(thres_img) else: thres = thresmeth(edges) bw = edges > thres if clear_borders: segmentation.clear_border(bw, buffer_size=int(max(bw.shape)/50), in_place=True) if fill_holes: bw = ndimage.binary_fill_holes(bw) labeled_arr, num_roi = measure.label(bw, return_num=True) regionprops = measure.regionprops(labeled_arr, edges) return labeled_arr, regionprops, num_roi
Example #16
Source File: cropping.py From nnUNet with Apache License 2.0 | 5 votes |
def create_nonzero_mask(data): from scipy.ndimage import binary_fill_holes assert len(data.shape) == 4 or len(data.shape) == 3, "data must have shape (C, X, Y, Z) or shape (C, X, Y)" nonzero_mask = np.zeros(data.shape[1:], dtype=bool) for c in range(data.shape[0]): this_mask = data[c] != 0 nonzero_mask = nonzero_mask | this_mask nonzero_mask = binary_fill_holes(nonzero_mask) return nonzero_mask
Example #17
Source File: utils.py From SegWithDistMap with Apache License 2.0 | 5 votes |
def post_processing(prediction): prediction = nd.binary_fill_holes(prediction) label_cc, num_cc = measure.label(prediction,return_num=True) total_cc = np.sum(prediction) measure.regionprops(label_cc) for cc in range(1,num_cc+1): single_cc = (label_cc==cc) single_vol = np.sum(single_cc) if single_vol/total_cc<0.2: prediction[single_cc]=0 return prediction
Example #18
Source File: postprocessing.py From open-solution-data-science-bowl-2018 with MIT License | 5 votes |
def fill_holes_per_blob(image): image_cleaned = np.zeros_like(image) for i in range(1, image.max() + 1): mask = np.where(image == i, 1, 0) mask = ndi.morphology.binary_fill_holes(mask) image_cleaned = image_cleaned + mask * i return image_cleaned
Example #19
Source File: postprocessing.py From open-solution-data-science-bowl-2018 with MIT License | 5 votes |
def clean_mask(m, c): # threshold m_thresh = threshold_otsu(m) c_thresh = threshold_otsu(c) m_b = m > m_thresh c_b = c > c_thresh # combine contours and masks and fill the cells m_ = np.where(m_b | c_b, 1, 0) m_ = ndi.binary_fill_holes(m_) # close what wasn't closed before area, radius = mean_blob_size(m_b) struct_size = int(1.25 * radius) struct_el = morph.disk(struct_size) m_padded = pad_mask(m_, pad=struct_size) m_padded = morph.binary_closing(m_padded, selem=struct_el) m_ = crop_mask(m_padded, crop=struct_size) # open to cut the real cells from the artifacts area, radius = mean_blob_size(m_b) struct_size = int(0.75 * radius) struct_el = morph.disk(struct_size) m_ = np.where(c_b & (~m_b), 0, m_) m_padded = pad_mask(m_, pad=struct_size) m_padded = morph.binary_opening(m_padded, selem=struct_el) m_ = crop_mask(m_padded, crop=struct_size) # join the connected cells with what we had at the beginning m_ = np.where(m_b | m_, 1, 0) m_ = ndi.binary_fill_holes(m_) # drop all the cells that weren't present at least in 25% of area in the initial mask m_ = drop_artifacts(m_, m_b, min_coverage=0.25) return m_
Example #20
Source File: volume.py From pyAFQ with BSD 2-Clause "Simplified" License | 5 votes |
def patch_up_roi(roi): """ After being non-linearly transformed, ROIs tend to have holes in them. We perform a couple of computational geometry operations on the ROI to fix that up. Parameters ---------- roi : 3D binary array The ROI after it has been transformed. sigma : float The sigma for initial Gaussian smoothing. truncate : float The truncation for the Gaussian Returns ------- ROI after dilation and hole-filling """ hole_filled = ndim.binary_fill_holes(roi > 0) try: return convex_hull_image(hole_filled) except QhullError: return hole_filled
Example #21
Source File: utils.py From lungmask with GNU General Public License v3.0 | 4 votes |
def postrocessing(label_image, spare=[]): '''some post-processing mapping small label patches to the neighbout whith which they share the largest border. All connected components smaller than min_area will be removed ''' # merge small components to neighbours regionmask = skimage.measure.label(label_image) origlabels = np.unique(label_image) origlabels_maxsub = np.zeros((max(origlabels) + 1,), dtype=np.uint32) # will hold the largest component for a label regions = skimage.measure.regionprops(regionmask, label_image) regions.sort(key=lambda x: x.area) regionlabels = [x.label for x in regions] # will hold mapping from regionlabels to original labels region_to_lobemap = np.zeros((len(regionlabels) + 1,), dtype=np.uint8) for r in regions: if r.area > origlabels_maxsub[r.max_intensity]: origlabels_maxsub[r.max_intensity] = r.area region_to_lobemap[r.label] = r.max_intensity for r in tqdm(regions): if (r.area < origlabels_maxsub[r.max_intensity] or r.max_intensity in spare) and r.area>2: # area>2 improves runtime because small areas 1 and 2 voxel will be ignored bb = bbox_3D(regionmask == r.label) sub = regionmask[bb[0]:bb[1], bb[2]:bb[3], bb[4]:bb[5]] dil = ndimage.binary_dilation(sub == r.label) neighbours, counts = np.unique(sub[dil], return_counts=True) mapto = r.label maxmap = 0 myarea = 0 for ix, n in enumerate(neighbours): if n != 0 and n != r.label and counts[ix] > maxmap and n != spare: maxmap = counts[ix] mapto = n myarea = r.area regionmask[regionmask == r.label] = mapto # print(str(region_to_lobemap[r.label]) + ' -> ' + str(region_to_lobemap[mapto])) # for debugging if regions[regionlabels.index(mapto)].area == origlabels_maxsub[ regions[regionlabels.index(mapto)].max_intensity]: origlabels_maxsub[regions[regionlabels.index(mapto)].max_intensity] += myarea regions[regionlabels.index(mapto)].__dict__['_cache']['area'] += myarea outmask_mapped = region_to_lobemap[regionmask] outmask_mapped[outmask_mapped==spare] = 0 if outmask_mapped.shape[0] == 1: # holefiller = lambda x: ndimage.morphology.binary_fill_holes(x[0])[None, :, :] # This is bad for slices that show the liver holefiller = lambda x: skimage.morphology.area_closing(x[0].astype(int), area_threshold=64)[None, :, :] == 1 else: holefiller = fill_voids.fill outmask = np.zeros(outmask_mapped.shape, dtype=np.uint8) for i in np.unique(outmask_mapped)[1:]: outmask[holefiller(keep_largest_connected_component(outmask_mapped == i))] = i return outmask
Example #22
Source File: anatomical.py From mriqc with BSD 3-Clause "New" or "Revised" License | 4 votes |
def gradient_threshold(in_file, in_segm, thresh=1.0, out_file=None): """ Compute a threshold from the histogram of the magnitude gradient image """ import os.path as op import numpy as np import nibabel as nb from scipy import ndimage as sim struc = sim.iterate_structure(sim.generate_binary_structure(3, 2), 2) if out_file is None: fname, ext = op.splitext(op.basename(in_file)) if ext == '.gz': fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath(f'{fname}_gradmask{ext}') imnii = nb.load(in_file) hdr = imnii.header.copy() hdr.set_data_dtype(np.uint8) # pylint: disable=no-member data = imnii.get_data().astype(np.float32) mask = np.zeros_like(data, dtype=np.uint8) # pylint: disable=no-member mask[data > 15.] = 1 segdata = nb.load(in_segm).get_data().astype(np.uint8) segdata[segdata > 0] = 1 segdata = sim.binary_dilation( segdata, struc, iterations=2, border_value=1).astype(np.uint8) mask[segdata > 0] = 1 mask = sim.binary_closing(mask, struc, iterations=2).astype(np.uint8) # Remove small objects label_im, nb_labels = sim.label(mask) artmsk = np.zeros_like(mask) if nb_labels > 2: sizes = sim.sum(mask, label_im, list(range(nb_labels + 1))) ordered = list(reversed(sorted(zip(sizes, list(range(nb_labels + 1)))))) for _, label in ordered[2:]: mask[label_im == label] = 0 artmsk[label_im == label] = 1 mask = sim.binary_fill_holes(mask, struc).astype(np.uint8) # pylint: disable=no-member nb.Nifti1Image(mask, imnii.affine, hdr).to_filename(out_file) return out_file
Example #23
Source File: winston_lutz.py From pylinac with MIT License | 4 votes |
def _find_bb(self) -> Point: """Find the BB within the radiation field. Iteratively searches for a circle-like object by lowering a low-pass threshold value until found. Returns ------- Point The weighted-pixel value location of the BB. """ # get initial starting conditions hmin, hmax = np.percentile(self.array, [5, 99.9]) spread = hmax - hmin max_thresh = hmax lower_thresh = hmax - spread / 1.5 # search for the BB by iteratively lowering the low-pass threshold value until the BB is found. found = False while not found: try: binary_arr = np.logical_and((max_thresh > self), (self >= lower_thresh)) labeled_arr, num_roi = ndimage.measurements.label(binary_arr) roi_sizes, bin_edges = np.histogram(labeled_arr, bins=num_roi + 1) bw_bb_img = np.where(labeled_arr == np.argsort(roi_sizes)[-3], 1, 0) # we pick the 3rd largest one because the largest is the background, 2nd is rad field, 3rd is the BB bw_bb_img = ndimage.binary_fill_holes(bw_bb_img).astype(int) # fill holes for low energy beams like 2.5MV bb_regionprops = measure.regionprops(bw_bb_img)[0] if not is_round(bb_regionprops): raise ValueError if not is_modest_size(bw_bb_img, self.rad_field_bounding_box): raise ValueError if not is_symmetric(bw_bb_img): raise ValueError except (IndexError, ValueError): max_thresh -= 0.05 * spread if max_thresh < hmin: raise ValueError("Unable to locate the BB. Make sure the field edges do not obscure the BB and that there is no artifacts in the images.") else: found = True # determine the center of mass of the BB inv_img = image.load(self.array) # we invert so BB intensity increases w/ attenuation inv_img.check_inversion_by_histogram(percentiles=(99.99, 50, 0.01)) bb_rprops = measure.regionprops(bw_bb_img, intensity_image=inv_img)[0] return Point(bb_rprops.weighted_centroid[1], bb_rprops.weighted_centroid[0])
Example #24
Source File: masking.py From MDT with GNU Lesser General Public License v3.0 | 4 votes |
def create_median_otsu_brain_mask(dwi_info, protocol, mask_threshold=0, fill_holes=True, **kwargs): """Create a brain mask using the given volume. Args: dwi_info (string or tuple or image): The information about the volume, either: - the filename of the input file - or a tuple with as first index a ndarray with the DWI and as second index the header - or only the image as an ndarray protocol (string or :class:`~mdt.protocols.Protocol`): The filename of the protocol file or a Protocol object mask_threshold (float): everything below this b-value threshold is masked away (value in s/m^2) fill_holes (boolean): if we will fill holes after the median otsu algorithm and before the thresholding **kwargs: the additional arguments for median_otsu. Returns: ndarray: The created brain mask """ logger = logging.getLogger(__name__) logger.info('Starting calculating a brain mask') if isinstance(dwi_info, str): signal_img = load_nifti(dwi_info) dwi = signal_img.get_data() elif isinstance(dwi_info, (tuple, list)): dwi = dwi_info[0] else: dwi = dwi_info if isinstance(protocol, str): protocol = load_protocol(protocol) if len(dwi.shape) == 4: unweighted_ind = protocol.get_unweighted_indices() if len(unweighted_ind): unweighted = np.mean(dwi[..., unweighted_ind], axis=3) else: unweighted = np.mean(dwi, axis=3) else: unweighted = dwi.copy() brain_mask = median_otsu(unweighted, **kwargs) brain_mask = brain_mask > 0 if fill_holes: brain_mask = binary_fill_holes(brain_mask) if mask_threshold: brain_mask = np.mean(dwi[..., protocol.get_weighted_indices()], axis=3) * brain_mask > mask_threshold logger.info('Finished calculating a brain mask') return brain_mask