
    9i)A                        S r SSKrSSKrSSKJr  SSKJr  SSK	J
r
  SSKJr  S	r\ V s0 s H  o S
U -   _M
     sn rSr\R                  \ V s0 s H  o U _M     sn 5        S rS rSSS.S jjrSSS.S jjrSSSSS.S jrgs  sn f s  sn f )z#Miscellaneous morphology functions.    N)ndimage)cKDTree   )warn   )_remove_objects_by_distance)erosiondilationopeningclosinggrey_)binary_erosionbinary_dilationbinary_openingbinary_closingblack_tophatwhite_tophatc                 J   ^  [         R                  " T 5      SU 4S jj5       nU$ )a_  Decorator to add a default footprint to morphology functions.

Parameters
----------
func : function
    A morphology function such as erosion, dilation, opening, closing,
    white_tophat, or black_tophat.

Returns
-------
func_out : function
    The function, using a default footprint of same dimension
    as the input image with connectivity 1.

c                 h   > Uc!  [         R                  " U R                  S5      nT" U /UQ7SU0UD6$ )Nr   	footprint)ndigenerate_binary_structurendim)imager   argskwargsfuncs       W/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/skimage/morphology/misc.pyfunc_out#default_footprint.<locals>.func_out.   s9    55ejj!DIE@@Y@@@    N)	functoolswraps)r   r   s   ` r   default_footprintr%      s)    " __TA A
 Or!   c                     U R                   [        :X  dN  [        R                  " U R                   [        R                  5      (       d  [        SU R                    S35      eg g )Nz4Only bool or integer image types are supported. Got .)dtypeboolnp
issubdtypeinteger	TypeError)ars    r   _check_dtype_supportedr/   7   sL    HHbhh

 C CEbhhZqQ
 	
 !Dr!   outc                ,   [        U 5        Uc  U R                  5       nOXSS& US:X  a  U$ UR                  [        :X  aZ  [        R
                  " U R                  U5      n[        R                  " U [        R                  S9n[        R                  " XUS9  OUn [        R                  " UR                  5       5      n[        U5      S:X  a  UR                  [        :w  a  [        S5        Xa:  nXu   nSX8'   U$ ! [         a    [        S5      ef = f)a  Remove objects smaller than the specified size.

Expects ar to be an array with labeled objects, and removes objects
smaller than min_size. If `ar` is bool, the image is first labeled.
This leads to potentially different behavior for bool and 0-and-1
arrays.

Parameters
----------
ar : ndarray (arbitrary shape, int or bool type)
    The array containing the objects of interest. If the array type is
    int, the ints must be non-negative.
min_size : int, optional (default: 64)
    The smallest allowable object size.
connectivity : int, {1, 2, ..., ar.ndim}, optional (default: 1)
    The connectivity defining the neighborhood of a pixel. Used during
    labelling if `ar` is bool.
out : ndarray
    Array of the same shape as `ar`, into which the output is
    placed. By default, a new array is created.

Raises
------
TypeError
    If the input array is of an invalid type, such as float or string.
ValueError
    If the input array contains negative values.

Returns
-------
out : ndarray, same shape and type as input `ar`
    The input array with small connected components removed.

See Also
--------
skimage.morphology.remove_objects_by_distance

Examples
--------
>>> from skimage import morphology
>>> a = np.array([[0, 0, 0, 1, 0],
...               [1, 1, 1, 0, 0],
...               [1, 1, 1, 0, 1]], bool)
>>> b = morphology.remove_small_objects(a, 6)
>>> b
array([[False, False, False, False, False],
       [ True,  True,  True, False, False],
       [ True,  True,  True, False, False]])
>>> c = morphology.remove_small_objects(a, 7, connectivity=2)
>>> c
array([[False, False, False,  True, False],
       [ True,  True,  True, False, False],
       [ True,  True,  True, False, False]])
>>> d = morphology.remove_small_objects(a, 6, out=a)
>>> d is a
True

Nr   r(   )outputz{Negative value labels are not supported. Try relabeling the input with `scipy.ndimage.label` or `skimage.morphology.label`.r   z[Only one label was provided to `remove_small_objects`. Did you mean to use a boolean array?)r/   copyr(   r)   r   r   r   r*   
zeros_likeint32labelbincountravel
ValueErrorlenr   )	r.   min_sizeconnectivityr1   r   ccscomponent_sizes	too_smalltoo_small_masks	            r   remove_small_objectsrC   ?   s    x 2
{ggiA1}

yyD11"''<H	mmBbhh/		",
++ciik2 ?q SYY$%63	

  *I^NCJ#  
*
 	

s   $C= =Dc                6   [        U 5        U R                  [        :w  a  [        S[        5        Ub   UR                  [        :w  a  [        S5      eOU R                  [        SS9n[        R                  " XS9  [        X1X#S9n[        R                  " X3S9  U$ )a  Remove contiguous holes smaller than the specified size.

Parameters
----------
ar : ndarray (arbitrary shape, int or bool type)
    The array containing the connected components of interest.
area_threshold : int, optional (default: 64)
    The maximum area, in pixels, of a contiguous hole that will be filled.
    Replaces `min_size`.
connectivity : int, {1, 2, ..., ar.ndim}, optional (default: 1)
    The connectivity defining the neighborhood of a pixel.
out : ndarray
    Array of the same shape as `ar` and bool dtype, into which the
    output is placed. By default, a new array is created.

Raises
------
TypeError
    If the input array is of an invalid type, such as float or string.
ValueError
    If the input array contains negative values.

Returns
-------
out : ndarray, same shape and type as input `ar`
    The input array with small holes within connected components removed.

Examples
--------
>>> from skimage import morphology
>>> a = np.array([[1, 1, 1, 1, 1, 0],
...               [1, 1, 1, 0, 1, 0],
...               [1, 0, 0, 1, 1, 0],
...               [1, 1, 1, 1, 1, 0]], bool)
>>> b = morphology.remove_small_holes(a, 2)
>>> b
array([[ True,  True,  True,  True,  True, False],
       [ True,  True,  True,  True,  True, False],
       [ True, False, False,  True,  True, False],
       [ True,  True,  True,  True,  True, False]])
>>> c = morphology.remove_small_holes(a, 2, connectivity=2)
>>> c
array([[ True,  True,  True,  True,  True, False],
       [ True,  True,  True, False,  True, False],
       [ True, False, False,  True,  True, False],
       [ True,  True,  True,  True,  True, False]])
>>> d = morphology.remove_small_holes(a, 2, out=a)
>>> d is a
True

Notes
-----
If the array type is int, it is assumed that it contains already-labeled
objects. The labels are not kept in the output image (this function always
outputs a bool image). It is suggested that labeling is completed after
using this function.

z\Any labeled images will be returned as a boolean array. Did you mean to use a boolean array?zout dtype must be boolTr5   r0   )
r/   r(   r)   r   UserWarningr-   astyper*   logical_notrC   )r.   area_thresholdr>   r1   s       r   remove_small_holesrJ      s    v 2 
xx43	
 99455  ii4i( NN2 sL
JCNN3 Jr!   )priorityp_normspacingr1   c          
        ^^ US:  a  [        SU 35      e[        R                  " U R                  [        R                  5      (       d  [        SU R                   35      eUc  U R                  SS9nOXPLa  XSS& UR                  SS9nTbP  [        R                  " T5      mTR                  UR                  4:w  d  TR                  5       S::  a  [        S5      e[        R                  " U5      nTb!  [        R                  " TS   T:H  5      (       a(  US::  a"  [        R                  " UR                  S	5      nO+[        R                  " UR                  UR                  5      n[        R                  " XXS
9[        R                   " XXS
9:g  R                  5       U   n	Xy   n
Xy)    nU
R"                  S:X  a  U$ U
[        R$                  " Xj   5         n
U[        R$                  " Xk   5         nUc|  [        R&                  " UR                  [        R(                  SS9(       d3  [        R*                  " UR-                  [        R(                  SS95      nO[        R*                  " U5      nXjS      nUS:  a  [        SU< 35      e U
[        R$                  " X&U
      SS9SSS2      n
[        R2                  " XR                  5      mTb)  [5        UU4S j[7        UR                  5       5       5      m[9        [        R:                  " T[        R<                  S9R>                  S9n[A        UU
UUUUU R                  S9  URB                  ULa  URE                  UR                  5      USS& U$ ! [.         aM  n[        R0                  " U5      S	-   4nUR                  U:w  a  [        SU SUR                   S35      Uee SnAff = f)a  Remove objects, in specified order, until remaining are a minimum distance apart.

Remove labeled objects from an image until the remaining ones are spaced
more than a given distance from one another. By default, smaller objects
are removed first.

Parameters
----------
label_image : ndarray of integers
    An n-dimensional array containing object labels, e.g. as returned by
    :func:`~.label`. A value of zero is considered background, all other
    object IDs must be positive integers.
min_distance : int or float
    Remove objects whose distance to other objects is not greater than this
    positive value. Objects with a lower `priority` are removed first.
priority : ndarray, optional
    Defines the priority with which objects are removed. Expects a
    1-dimensional array of length
    :func:`np.amax(label_image) + 1 <numpy.amax>` that contains the priority
    for each object's label at the respective index. Objects with a lower value
    are removed first until all remaining objects fulfill the distance
    requirement. If not given, priority is given to objects with a higher
    number of samples and their label value second.
p_norm : int or float, optional
    The Minkowski distance of order p, used to calculate the distance
    between objects. The default ``2`` corresponds to the Euclidean
    distance, ``1`` to the "Manhattan" distance, and ``np.inf`` to the
    Chebyshev distance.
spacing : sequence of float, optional
    The pixel spacing along each axis of `label_image`. If not specified,
    a grid spacing of unity (1) is implied.
out : ndarray, optional
    Array of the same shape and dtype as `image`, into which the output is
    placed. By default, a new array is created.

Returns
-------
out : ndarray
    Array of the same shape as `label_image`, for which objects that violate
    the `min_distance` condition were removed.

See Also
--------
skimage.morphology.remove_small_objects
    Remove objects smaller than the specified size.

Notes
-----
The basic steps of this algorithm work as follows:

1. Find the indices for of all given objects and separate them depending on
   if they point to an object's border or not.
2. Sort indices by their label value, ensuring that indices which point to
   the same object are next to each other. This optimization allows finding
   all parts of an object, simply by stepping to the neighboring indices.
3. Sort boundary indices by `priority`. Use a stable-sort to preserve the
   ordering from the previous sorting step. If `priority` is not given,
   use :func:`numpy.bincount` as a fallback.
4. Construct a :class:`scipy.spatial.cKDTree` from the boundary indices.
5. Iterate across boundary indices in priority-sorted order, and query the
   kd-tree for objects that are too close. Remove ones that are and don't
   take them into account when evaluating other objects later on.

The performance of this algorithm depends on the number of samples in
`label_image` that belong to an object's border.

Examples
--------
>>> import skimage as ski
>>> ski.morphology.remove_objects_by_distance(np.array([2, 0, 1, 1]), 2)
array([0, 0, 1, 1])
>>> ski.morphology.remove_objects_by_distance(
...     np.array([2, 0, 1, 1]), 2, priority=np.array([0, 1, 9])
... )
array([2, 0, 0, 0])
>>> label_image = np.array(
...     [[8, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9],
...      [8, 8, 8, 0, 0, 0, 0, 0, 0, 9, 9],
...      [0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0],
...      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
...      [0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0],
...      [2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
...      [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
...      [0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7]]
... )
>>> ski.morphology.remove_objects_by_distance(
...     label_image, min_distance=3
... )
array([[8, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9],
       [8, 8, 8, 0, 0, 0, 0, 0, 0, 9, 9],
       [0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7]])
r   zmin_distance must be >= 0, was z,`label_image` must be of integer dtype, got NC)orderzV`spacing` must contain exactly one positive factor for each dimension of `label_image`r   r   )r   safe)castingFrE   zfound object with negative ID stable)kindzBshape of `priority` must be (np.amax(label_image) + 1,), expected z, got z insteadc              3   :   >#    U  H  nTU   TU   -  v   M     g 7fr"    ).0dimrM   unraveled_indicess     r   	<genexpr>-remove_objects_by_distance.<locals>.<genexpr>  s#      "
=Lcc"WS\1_s   r3   )data)r1   border_indicesinner_indiceskdtreemin_distancerL   shape)#r;   r*   r+   r(   r,   r5   r:   arrayrb   r   minflatnonzeroallr   r   maximum_filterminimum_filtersizeargsortcan_castintpr9   rG   
IndexErroramaxunravel_indextupleranger   asarrayfloat64Tr   basereshape)label_imagera   rK   rL   rM   r1   out_raveledindicesr   borderr^   r_   smallest_iderrorexpected_shaper`   rZ   s       `           @r   remove_objects_by_distancer~      s   T a:<.IJJ==**BJJ77:;;L;L:MN
 	
 {S)		A))#)&K((7#==SXXK'7;;=A+=6 
 nn[)G
 	266'!*"788fk 11#((A>	11#((CHHE	34c7	8eggF _NG$Ma

 $BJJ{/J$KLN!"**[-G"HIM{{399bggv>{{;#5#5bggE#5#JKH{{;/H Q/0KQ9+IJJ (JJxN ;<8LTrTR
 ((C! "
=B388_"
 
 "**%6bjjIKKLF%#! s"$$SYY/AJA  	''+.24>>^+*+6(..1AK 
 	s   #M? ?
O	AOO)@   r   )__doc__numpyr*   r#   scipyr   r   scipy.spatialr   _shared.utilsr   _misc_cyr   funcsskimage2ndimageupdater%   r/   rC   rJ   r~   )xs   0r   <module>r      s    )     !   1
 	6+015agk>51	   e,e1e, -4
` `FST St NS 2 -s   BB