Python skimage.morphology.ball() Examples
The following are 18
code examples of skimage.morphology.ball().
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
skimage.morphology
, or try the search function
.
Example #1
Source File: math.py From spinalcordtoolbox with MIT License | 7 votes |
def dilate(data, size, shape, dim=None): """ Dilate data using ball structuring element :param data: Image or numpy array: 2d or 3d array :param size: int: If shape={'square', 'cube'}: Corresponds to the length of an edge (size=1 has no effect). If shape={'disk', 'ball'}: Corresponds to the radius, not including the center element (size=0 has no effect). :param shape: {'square', 'cube', 'disk', 'ball'} :param dim: {0, 1, 2}: Dimension of the array which 2D structural element will be orthogonal to. For example, if you wish to apply a 2D disk kernel in the X-Y plane, leaving Z unaffected, parameters will be: shape=disk, dim=2. :return: numpy array: data dilated """ if isinstance(data, Image): im_out = data.copy() im_out.data = dilate(data.data, size, shape, dim) return im_out else: return dilation(data, selem=_get_selem(shape, size, dim), out=None)
Example #2
Source File: math.py From spinalcordtoolbox with MIT License | 6 votes |
def erode(data, size, shape, dim=None): """ Dilate data using ball structuring element :param data: Image or numpy array: 2d or 3d array :param size: int: If shape={'square', 'cube'}: Corresponds to the length of an edge (size=1 has no effect). If shape={'disk', 'ball'}: Corresponds to the radius, not including the center element (size=0 has no effect). :param shape: {'square', 'cube', 'disk', 'ball'} :param dim: {0, 1, 2}: Dimension of the array which 2D structural element will be orthogonal to. For example, if you wish to apply a 2D disk kernel in the X-Y plane, leaving Z unaffected, parameters will be: shape=disk, dim=2. :return: numpy array: data dilated """ if isinstance(data, Image): im_out = data.copy() im_out.data = erode(data.data, size, shape, dim) return im_out else: return erosion(data, selem=_get_selem(shape, size, dim), out=None)
Example #3
Source File: freesurfer.py From niworkflows with BSD 3-Clause "New" or "Revised" License | 6 votes |
def refine_aseg(aseg, ball_size=4): """ Refine the ``aseg.mgz`` mask of Freesurfer. First step to reconcile ANTs' and FreeSurfer's brain masks. Here, the ``aseg.mgz`` mask from FreeSurfer is refined in two steps, using binary morphological operations: 1. With a binary closing operation the sulci are included into the mask. This results in a smoother brain mask that does not exclude deep, wide sulci. 2. Fill any holes (typically, there could be a hole next to the pineal gland and the corpora quadrigemina if the great cerebral brain is segmented out). """ # Read aseg data bmask = aseg.copy() bmask[bmask > 0] = 1 bmask = bmask.astype(np.uint8) # Morphological operations selem = sim.ball(ball_size) newmask = sim.binary_closing(bmask, selem) newmask = binary_fill_holes(newmask.astype(np.uint8), selem).astype(np.uint8) return newmask.astype(np.uint8)
Example #4
Source File: pyramid_augmentations.py From nnUNet with Apache License 2.0 | 6 votes |
def __call__(self, **data_dict): data = data_dict.get(self.key) for b in range(data.shape[0]): if np.random.uniform() < self.p_per_sample: ch = deepcopy(self.channel_idx) np.random.shuffle(ch) for c in ch: if np.random.uniform() < self.p_per_label: operation = np.random.choice(self.any_of_these) selem = ball(np.random.uniform(*self.strel_size)) workon = np.copy(data[b, c]).astype(int) res = operation(workon, selem).astype(workon.dtype) data[b, c] = res # if class was added, we need to remove it in ALL other channels to keep one hot encoding # properties # we modify data other_ch = [i for i in ch if i != c] if len(other_ch) > 0: was_added_mask = (res - workon) > 0 for oc in other_ch: data[b, oc][was_added_mask] = 0 # if class was removed, leave it at background data_dict[self.key] = data return data_dict
Example #5
Source File: pyramid_augmentations.py From nnUNet with Apache License 2.0 | 6 votes |
def __call__(self, **data_dict): data = data_dict.get(self.key) for b in range(data.shape[0]): if np.random.uniform() < self.p_per_sample: ch = deepcopy(self.channel_idx) np.random.shuffle(ch) for c in ch: if np.random.uniform() < self.p_per_label: operation = np.random.choice(self.any_of_these) selem = ball(np.random.uniform(*self.strel_size)) workon = np.copy(data[b, c]).astype(int) res = operation(workon, selem).astype(workon.dtype) data[b, c] = res # if class was added, we need to remove it in ALL other channels to keep one hot encoding # properties # we modify data other_ch = [i for i in ch if i != c] if len(other_ch) > 0: was_added_mask = (res - workon) > 0 for oc in other_ch: data[b, oc][was_added_mask] = 0 # if class was removed, leave it at backgound data_dict[self.key] = data return data_dict
Example #6
Source File: __funcs__.py From porespy with MIT License | 6 votes |
def ps_ball(radius): r""" Creates spherical ball structuring element for morphological operations Parameters ---------- radius : float or int The desired radius of the structuring element Returns ------- strel : 3D-array A 3D numpy array of the structuring element """ rad = int(np.ceil(radius)) other = np.ones((2 * rad + 1, 2 * rad + 1, 2 * rad + 1), dtype=bool) other[rad, rad, rad] = False ball = spim.distance_transform_edt(other) < radius return ball
Example #7
Source File: test_filters.py From porespy with MIT License | 5 votes |
def test_morphology_fft_closing_3D(self): im = self.im truth = spim.binary_closing(im, structure=ball(3)) test = ps.tools.fftmorphology(im, strel=ball(3), mode='closing') assert np.all(truth == test)
Example #8
Source File: math.py From spinalcordtoolbox with MIT License | 5 votes |
def _get_selem(shape, size, dim): """ Create structuring element of desired shape and radius :param shape: str: Shape of the structuring element. See available options below in the code :param size: int: size of the element. :param dim: {0, 1, 2}: Dimension of the array which 2D structural element will be orthogonal to. For example, if you wish to apply a 2D disk kernel in the X-Y plane, leaving Z unaffected, parameters will be: shape=disk, dim=2. :return: numpy array: structuring element """ # TODO: enable custom selem if shape == 'square': selem = square(size) elif shape == 'cube': selem = cube(size) elif shape == 'disk': selem = disk(size) elif shape == 'ball': selem = ball(size) else: ValueError("This shape is not a valid entry: {}".format(shape)) if not (len(selem.shape) in [2, 3] and selem.shape[0] == selem.shape[1]): raise ValueError("Invalid shape") # If 2d kernel, replicate it along the specified dimension if len(selem.shape) == 2: selem3d = np.zeros([selem.shape[0]]*3) imid = np.floor(selem.shape[0] / 2).astype(int) if dim == 0: selem3d[imid, :, :] = selem elif dim == 1: selem3d[:, imid, :] = selem elif dim == 2: selem3d[:, :, imid] = selem else: raise ValueError("dim can only take values: {0, 1, 2}") selem = selem3d return selem
Example #9
Source File: test_filters.py From porespy with MIT License | 5 votes |
def test_morphology_fft_opening_3D(self): im = self.im truth = spim.binary_opening(im, structure=ball(3)) test = ps.tools.fftmorphology(im, strel=ball(3), mode='opening') assert np.all(truth == test)
Example #10
Source File: test_filters.py From porespy with MIT License | 5 votes |
def test_morphology_fft_erode_3D(self): im = self.im truth = spim.binary_erosion(im, structure=ball(3)) test = ps.tools.fftmorphology(im, strel=ball(3), mode='erosion') assert np.all(truth == test)
Example #11
Source File: test_filters.py From porespy with MIT License | 5 votes |
def test_morphology_fft_dilate_3D(self): im = self.im truth = spim.binary_dilation(im, structure=ball(3)) test = ps.tools.fftmorphology(im, strel=ball(3), mode='dilation') assert np.all(truth == test)
Example #12
Source File: __funcs__.py From porespy with MIT License | 5 votes |
def trim_small_clusters(im, size=1): r""" Remove isolated voxels or clusters smaller than a given size Parameters ---------- im : ND-array The binary image from which voxels are to be removed size : scalar The threshold size of clusters to trim. As clusters with this many voxels or fewer will be trimmed. The default is 1 so only single voxels are removed. Returns ------- im : ND-image A copy of ``im`` with clusters of voxels smaller than the given ``size`` removed. """ if im.dims == 2: strel = disk(1) elif im.ndims == 3: strel = ball(1) else: raise Exception('Only 2D or 3D images are accepted') filtered_array = np.copy(im) labels, N = spim.label(filtered_array, structure=strel) id_sizes = np.array(spim.sum(im, labels, range(N + 1))) area_mask = (id_sizes <= size) filtered_array[area_mask[labels]] = 0 return filtered_array
Example #13
Source File: freesurfer.py From niworkflows with BSD 3-Clause "New" or "Revised" License | 5 votes |
def grow_mask(anat, aseg, ants_segs=None, ww=7, zval=2.0, bw=4): """ Grow mask including pixels that have a high likelihood. GM tissue parameters are sampled in image patches of ``ww`` size. This is inspired on mindboggle's solution to the problem: https://github.com/nipy/mindboggle/blob/master/mindboggle/guts/segment.py#L1660 """ selem = sim.ball(bw) if ants_segs is None: ants_segs = np.zeros_like(aseg, dtype=np.uint8) aseg[aseg == 42] = 3 # Collapse both hemispheres gm = anat.copy() gm[aseg != 3] = 0 refined = refine_aseg(aseg) newrefmask = sim.binary_dilation(refined, selem) - refined indices = np.argwhere(newrefmask > 0) for pixel in indices: # When ATROPOS identified the pixel as GM, set and carry on if ants_segs[tuple(pixel)] == 2: refined[tuple(pixel)] = 1 continue window = gm[ pixel[0] - ww:pixel[0] + ww, pixel[1] - ww:pixel[1] + ww, pixel[2] - ww:pixel[2] + ww, ] if np.any(window > 0): mu = window[window > 0].mean() sigma = max(window[window > 0].std(), 1.0e-5) zstat = abs(anat[tuple(pixel)] - mu) / sigma refined[tuple(pixel)] = int(zstat < zval) refined = sim.binary_opening(refined, selem) return refined
Example #14
Source File: white_tophat.py From starfish with MIT License | 5 votes |
def _white_tophat(self, image: xr.DataArray) -> xr.DataArray: if self.is_volume: structuring_element = ball(self.masking_radius) else: structuring_element = disk(self.masking_radius) return white_tophat(image, selem=structuring_element)
Example #15
Source File: __funcs__.py From porespy with MIT License | 4 votes |
def mesh_region(region: bool, strel=None): r""" Creates a tri-mesh of the provided region using the marching cubes algorithm Parameters ---------- im : ND-array A boolean image with ``True`` values indicating the region of interest strel : ND-array The structuring element to use when blurring the region. The blur is perfomed using a simple convolution filter. The point is to create a greyscale region to allow the marching cubes algorithm some freedom to conform the mesh to the surface. As the size of ``strel`` increases the region will become increasingly blurred and inaccurate. The default is a spherical element with a radius of 1. Returns ------- mesh : tuple A named-tuple containing ``faces``, ``verts``, ``norm``, and ``val`` as returned by ``scikit-image.measure.marching_cubes`` function. """ im = region if im.ndim != im.squeeze().ndim: warnings.warn('Input image conains a singleton axis:' + str(im.shape) + ' Reduce dimensionality with np.squeeze(im) to avoid' + ' unexpected behavior.') if strel is None: if region.ndim == 3: strel = ball(1) if region.ndim == 2: strel = disk(1) pad_width = np.amax(strel.shape) if im.ndim == 3: padded_mask = np.pad(im, pad_width=pad_width, mode='constant') padded_mask = spim.convolve(padded_mask * 1.0, weights=strel) / np.sum(strel) else: padded_mask = np.reshape(im, (1,) + im.shape) padded_mask = np.pad(padded_mask, pad_width=pad_width, mode='constant') verts, faces, norm, val = marching_cubes_lewiner(padded_mask) result = namedtuple('mesh', ('verts', 'faces', 'norm', 'val')) result.verts = verts - pad_width result.faces = faces result.norm = norm result.val = val return result
Example #16
Source File: __funcs__.py From porespy with MIT License | 4 votes |
def find_peaks(dt, r_max=4, footprint=None): r""" Returns all local maxima in the distance transform Parameters ---------- dt : ND-array The distance transform of the pore space. This may be calculated and filtered using any means desired. r_max : scalar The size of the structuring element used in the maximum filter. This controls the localness of any maxima. The default is 4 voxels. footprint : ND-array Specifies the shape of the structuring element used to define the neighborhood when looking for peaks. If none is specified then a spherical shape is used (or circular in 2D). Returns ------- image : ND-array An array of booleans with ``True`` values at the location of any local maxima. Notes ----- It is also possible ot the ``peak_local_max`` function from the ``skimage.feature`` module as follows: ``peaks = peak_local_max(image=dt, min_distance=r, exclude_border=0, indices=False)`` This automatically uses a square structuring element which is significantly faster than using a circular or spherical element. """ im = dt > 0 if im.ndim != im.squeeze().ndim: warnings.warn('Input image conains a singleton axis:' + str(im.shape) + ' Reduce dimensionality with np.squeeze(im) to avoid' + ' unexpected behavior.') if footprint is None: if im.ndim == 2: footprint = disk elif im.ndim == 3: footprint = ball else: raise Exception("only 2-d and 3-d images are supported") mx = spim.maximum_filter(dt + 2*(~im), footprint=footprint(r_max)) peaks = (dt == mx)*im return peaks
Example #17
Source File: __funcs__.py From porespy with MIT License | 4 votes |
def find_outer_region(im, r=0): r""" Finds regions of the image that are outside of the solid matrix. This function uses the rolling ball method to define where the outer region ends and the void space begins. This function is particularly useful for samples that do not fill the entire rectangular image, such as cylindrical cores or samples with non- parallel faces. Parameters ---------- im : ND-array Image of the porous material with 1's for void and 0's for solid r : scalar The radius of the rolling ball to use. If not specified then a value is calculated as twice maximum of the distance transform. The image size is padded by this amount in all directions, so the image can become quite large and unwieldy if too large a value is given. Returns ------- image : ND-array A boolean mask the same shape as ``im``, containing True in all voxels identified as *outside* the sample. """ if r == 0: dt = spim.distance_transform_edt(input=im) r = int(np.amax(dt)) * 2 im_padded = np.pad(array=im, pad_width=r, mode='constant', constant_values=True) dt = spim.distance_transform_edt(input=im_padded) seeds = (dt >= r) + get_border(shape=im_padded.shape) # Remove seeds not connected to edges labels = spim.label(seeds)[0] mask = labels == 1 # Assume label of 1 on edges, assured by adding border dt = spim.distance_transform_edt(~mask) outer_region = dt < r outer_region = extract_subsection(im=outer_region, shape=im.shape) return outer_region
Example #18
Source File: nilearn.py From niworkflows with BSD 3-Clause "New" or "Revised" License | 4 votes |
def _run_interface(self, runtime): in_files = self.inputs.in_files if self.inputs.enhance_t2: in_files = [_enhance_t2_contrast(f, newpath=runtime.cwd) for f in in_files] masknii = compute_epi_mask( in_files, lower_cutoff=self.inputs.lower_cutoff, upper_cutoff=self.inputs.upper_cutoff, connected=self.inputs.connected, opening=self.inputs.opening, exclude_zeros=self.inputs.exclude_zeros, ensure_finite=self.inputs.ensure_finite, target_affine=self.inputs.target_affine, target_shape=self.inputs.target_shape, ) if self.inputs.closing: closed = sim.binary_closing( np.asanyarray(masknii.dataobj).astype(np.uint8), sim.ball(1) ).astype(np.uint8) masknii = masknii.__class__(closed, masknii.affine, masknii.header) if self.inputs.fill_holes: filled = binary_fill_holes( np.asanyarray(masknii.dataobj).astype(np.uint8), sim.ball(6) ).astype(np.uint8) masknii = masknii.__class__(filled, masknii.affine, masknii.header) if self.inputs.no_sanitize: in_file = self.inputs.in_files if isinstance(in_file, list): in_file = in_file[0] nii = nb.load(in_file) qform, code = nii.get_qform(coded=True) masknii.set_qform(qform, int(code)) sform, code = nii.get_sform(coded=True) masknii.set_sform(sform, int(code)) self._results["out_mask"] = fname_presuffix( self.inputs.in_files[0], suffix="_mask", newpath=runtime.cwd ) masknii.to_filename(self._results["out_mask"]) return runtime