Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
289
venv/Lib/site-packages/skimage/morphology/_flood_fill.py
Normal file
289
venv/Lib/site-packages/skimage/morphology/_flood_fill.py
Normal file
|
@ -0,0 +1,289 @@
|
|||
"""flood_fill.py - in place flood fill algorithm
|
||||
|
||||
This module provides a function to fill all equal (or within tolerance) values
|
||||
connected to a given seed point with a different value.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from warnings import warn
|
||||
|
||||
from ._util import (_resolve_neighborhood, _set_border_values,
|
||||
_fast_pad, _offsets_to_raveled_neighbors)
|
||||
from ._flood_fill_cy import _flood_fill_equal, _flood_fill_tolerance
|
||||
|
||||
|
||||
def flood_fill(image, seed_point, new_value, *, selem=None, connectivity=None,
|
||||
tolerance=None, in_place=False, inplace=None):
|
||||
"""Perform flood filling on an image.
|
||||
|
||||
Starting at a specific `seed_point`, connected points equal or within
|
||||
`tolerance` of the seed value are found, then set to `new_value`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : ndarray
|
||||
An n-dimensional array.
|
||||
seed_point : tuple or int
|
||||
The point in `image` used as the starting point for the flood fill. If
|
||||
the image is 1D, this point may be given as an integer.
|
||||
new_value : `image` type
|
||||
New value to set the entire fill. This must be chosen in agreement
|
||||
with the dtype of `image`.
|
||||
selem : ndarray, optional
|
||||
A structuring element used to determine the neighborhood of each
|
||||
evaluated pixel. It must contain only 1's and 0's, have the same number
|
||||
of dimensions as `image`. If not given, all adjacent pixels are
|
||||
considered as part of the neighborhood (fully connected).
|
||||
connectivity : int, optional
|
||||
A number used to determine the neighborhood of each evaluated pixel.
|
||||
Adjacent pixels whose squared distance from the center is less than or
|
||||
equal to `connectivity` are considered neighbors. Ignored if `selem` is
|
||||
not None.
|
||||
tolerance : float or int, optional
|
||||
If None (default), adjacent values must be strictly equal to the
|
||||
value of `image` at `seed_point` to be filled. This is fastest.
|
||||
If a tolerance is provided, adjacent points with values within plus or
|
||||
minus tolerance from the seed point are filled (inclusive).
|
||||
in_place : bool, optional
|
||||
If True, flood filling is applied to `image` in place. If False, the
|
||||
flood filled result is returned without modifying the input `image`
|
||||
(default).
|
||||
inplace : bool, optional
|
||||
This parameter is deprecated and will be removed in version 0.19.0
|
||||
in favor of in_place. If True, flood filling is applied to `image`
|
||||
inplace. If False, the flood filled result is returned without
|
||||
modifying the input `image` (default).
|
||||
|
||||
Returns
|
||||
-------
|
||||
filled : ndarray
|
||||
An array with the same shape as `image` is returned, with values in
|
||||
areas connected to and equal (or within tolerance of) the seed point
|
||||
replaced with `new_value`.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The conceptual analogy of this operation is the 'paint bucket' tool in many
|
||||
raster graphics programs.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from skimage.morphology import flood_fill
|
||||
>>> image = np.zeros((4, 7), dtype=int)
|
||||
>>> image[1:3, 1:3] = 1
|
||||
>>> image[3, 0] = 1
|
||||
>>> image[1:3, 4:6] = 2
|
||||
>>> image[3, 6] = 3
|
||||
>>> image
|
||||
array([[0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 2, 2, 0],
|
||||
[0, 1, 1, 0, 2, 2, 0],
|
||||
[1, 0, 0, 0, 0, 0, 3]])
|
||||
|
||||
Fill connected ones with 5, with full connectivity (diagonals included):
|
||||
|
||||
>>> flood_fill(image, (1, 1), 5)
|
||||
array([[0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[5, 0, 0, 0, 0, 0, 3]])
|
||||
|
||||
Fill connected ones with 5, excluding diagonal points (connectivity 1):
|
||||
|
||||
>>> flood_fill(image, (1, 1), 5, connectivity=1)
|
||||
array([[0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[1, 0, 0, 0, 0, 0, 3]])
|
||||
|
||||
Fill with a tolerance:
|
||||
|
||||
>>> flood_fill(image, (0, 0), 5, tolerance=1)
|
||||
array([[5, 5, 5, 5, 5, 5, 5],
|
||||
[5, 5, 5, 5, 2, 2, 5],
|
||||
[5, 5, 5, 5, 2, 2, 5],
|
||||
[5, 5, 5, 5, 5, 5, 3]])
|
||||
"""
|
||||
if inplace is not None:
|
||||
warn('The `inplace` parameter is depreciated and will be removed '
|
||||
'in version 0.19.0. Use `in_place` instead.',
|
||||
stacklevel=2,
|
||||
category=FutureWarning)
|
||||
in_place = inplace
|
||||
|
||||
mask = flood(image, seed_point, selem=selem, connectivity=connectivity,
|
||||
tolerance=tolerance)
|
||||
|
||||
if not in_place:
|
||||
image = image.copy()
|
||||
|
||||
image[mask] = new_value
|
||||
return image
|
||||
|
||||
|
||||
def flood(image, seed_point, *, selem=None, connectivity=None, tolerance=None):
|
||||
"""Mask corresponding to a flood fill.
|
||||
|
||||
Starting at a specific `seed_point`, connected points equal or within
|
||||
`tolerance` of the seed value are found.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : ndarray
|
||||
An n-dimensional array.
|
||||
seed_point : tuple or int
|
||||
The point in `image` used as the starting point for the flood fill. If
|
||||
the image is 1D, this point may be given as an integer.
|
||||
selem : ndarray, optional
|
||||
A structuring element used to determine the neighborhood of each
|
||||
evaluated pixel. It must contain only 1's and 0's, have the same number
|
||||
of dimensions as `image`. If not given, all adjacent pixels are
|
||||
considered as part of the neighborhood (fully connected).
|
||||
connectivity : int, optional
|
||||
A number used to determine the neighborhood of each evaluated pixel.
|
||||
Adjacent pixels whose squared distance from the center is larger or
|
||||
equal to `connectivity` are considered neighbors. Ignored if
|
||||
`selem` is not None.
|
||||
tolerance : float or int, optional
|
||||
If None (default), adjacent values must be strictly equal to the
|
||||
initial value of `image` at `seed_point`. This is fastest. If a value
|
||||
is given, a comparison will be done at every point and if within
|
||||
tolerance of the initial value will also be filled (inclusive).
|
||||
|
||||
Returns
|
||||
-------
|
||||
mask : ndarray
|
||||
A Boolean array with the same shape as `image` is returned, with True
|
||||
values for areas connected to and equal (or within tolerance of) the
|
||||
seed point. All other values are False.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The conceptual analogy of this operation is the 'paint bucket' tool in many
|
||||
raster graphics programs. This function returns just the mask
|
||||
representing the fill.
|
||||
|
||||
If indices are desired rather than masks for memory reasons, the user can
|
||||
simply run `numpy.nonzero` on the result, save the indices, and discard
|
||||
this mask.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from skimage.morphology import flood
|
||||
>>> image = np.zeros((4, 7), dtype=int)
|
||||
>>> image[1:3, 1:3] = 1
|
||||
>>> image[3, 0] = 1
|
||||
>>> image[1:3, 4:6] = 2
|
||||
>>> image[3, 6] = 3
|
||||
>>> image
|
||||
array([[0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 2, 2, 0],
|
||||
[0, 1, 1, 0, 2, 2, 0],
|
||||
[1, 0, 0, 0, 0, 0, 3]])
|
||||
|
||||
Fill connected ones with 5, with full connectivity (diagonals included):
|
||||
|
||||
>>> mask = flood(image, (1, 1))
|
||||
>>> image_flooded = image.copy()
|
||||
>>> image_flooded[mask] = 5
|
||||
>>> image_flooded
|
||||
array([[0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[5, 0, 0, 0, 0, 0, 3]])
|
||||
|
||||
Fill connected ones with 5, excluding diagonal points (connectivity 1):
|
||||
|
||||
>>> mask = flood(image, (1, 1), connectivity=1)
|
||||
>>> image_flooded = image.copy()
|
||||
>>> image_flooded[mask] = 5
|
||||
>>> image_flooded
|
||||
array([[0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[0, 5, 5, 0, 2, 2, 0],
|
||||
[1, 0, 0, 0, 0, 0, 3]])
|
||||
|
||||
Fill with a tolerance:
|
||||
|
||||
>>> mask = flood(image, (0, 0), tolerance=1)
|
||||
>>> image_flooded = image.copy()
|
||||
>>> image_flooded[mask] = 5
|
||||
>>> image_flooded
|
||||
array([[5, 5, 5, 5, 5, 5, 5],
|
||||
[5, 5, 5, 5, 2, 2, 5],
|
||||
[5, 5, 5, 5, 2, 2, 5],
|
||||
[5, 5, 5, 5, 5, 5, 3]])
|
||||
"""
|
||||
# Correct start point in ravelled image - only copy if non-contiguous
|
||||
image = np.asarray(image)
|
||||
if image.flags.f_contiguous is True:
|
||||
order = 'F'
|
||||
elif image.flags.c_contiguous is True:
|
||||
order = 'C'
|
||||
else:
|
||||
image = np.ascontiguousarray(image)
|
||||
order = 'C'
|
||||
|
||||
seed_value = image[seed_point]
|
||||
|
||||
# Shortcut for rank zero
|
||||
if 0 in image.shape:
|
||||
return np.zeros(image.shape, dtype=np.bool)
|
||||
|
||||
# Convenience for 1d input
|
||||
try:
|
||||
iter(seed_point)
|
||||
except TypeError:
|
||||
seed_point = (seed_point,)
|
||||
|
||||
selem = _resolve_neighborhood(selem, connectivity, image.ndim)
|
||||
|
||||
# Must annotate borders
|
||||
working_image = _fast_pad(image, image.min(), order=order)
|
||||
|
||||
# Stride-aware neighbors - works for both C- and Fortran-contiguity
|
||||
ravelled_seed_idx = np.ravel_multi_index([i+1 for i in seed_point],
|
||||
working_image.shape, order=order)
|
||||
neighbor_offsets = _offsets_to_raveled_neighbors(
|
||||
working_image.shape, selem, center=((1,) * image.ndim), order=order)
|
||||
|
||||
# Use a set of flags; see _flood_fill_cy.pyx for meanings
|
||||
flags = np.zeros(working_image.shape, dtype=np.uint8, order=order)
|
||||
_set_border_values(flags, value=2)
|
||||
|
||||
try:
|
||||
if tolerance is not None:
|
||||
# Check if tolerance could create overflow problems
|
||||
try:
|
||||
max_value = np.finfo(working_image.dtype).max
|
||||
min_value = np.finfo(working_image.dtype).min
|
||||
except ValueError:
|
||||
max_value = np.iinfo(working_image.dtype).max
|
||||
min_value = np.iinfo(working_image.dtype).min
|
||||
|
||||
high_tol = min(max_value, seed_value + tolerance)
|
||||
low_tol = max(min_value, seed_value - tolerance)
|
||||
|
||||
_flood_fill_tolerance(working_image.ravel(order),
|
||||
flags.ravel(order),
|
||||
neighbor_offsets,
|
||||
ravelled_seed_idx,
|
||||
seed_value,
|
||||
low_tol,
|
||||
high_tol)
|
||||
else:
|
||||
_flood_fill_equal(working_image.ravel(order),
|
||||
flags.ravel(order),
|
||||
neighbor_offsets,
|
||||
ravelled_seed_idx,
|
||||
seed_value)
|
||||
except TypeError:
|
||||
if working_image.dtype == np.float16:
|
||||
# Provide the user with clearer error message
|
||||
raise TypeError("dtype of `image` is float16 which is not "
|
||||
"supported, try upcasting to float32")
|
||||
else:
|
||||
raise
|
||||
|
||||
# Output what the user requested; view does not create a new copy.
|
||||
return flags[(slice(1, -1),) * image.ndim].view(np.bool)
|
Loading…
Add table
Add a link
Reference in a new issue