
    1-Ph                        d dl Z d dlZd dlmZ d dlmZ d dlZddlm	Z	 d dl
mZ ddlmZ i Z ej        e j                            e j                            e          d                    ed<    ej        e j                            e j                            e          d	                    ed
<   d Zd*dZd Zej        dddZ eddd          ej        fddd            Zd+dZ eddd          ej        fddd            Zej        fdddZej        fdZdej        fdZej        fddddZej        fdZ ej        fd Z!ej        fddd!Z" eddd          ej        fddd"            Z#ej        fddd#Z$ej        fdddd$Z%ej        fddd%Z&ej        fd&Z'd' Z(dd(d)Z)dS ),    N)Sequence)Integral   )draw)
morphology)deprecate_funczdisk_decompositions.npyzball_decompositions.npy   c                     t          | d          rdS d t          | t                    r+t          fd| D                       st	          d          nt	          d          dS )N__array_interface__Fc                     t          | t                    oCt          |           dk    o0t          | d         d          ot          | d         t                    S )Nr   r   r      )
isinstancer   lenhasattrr   )ts    ]/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/skimage/morphology/footprints.py_validate_sequence_elementz:_footprint_is_sequence.<locals>._validate_sequence_element    sU    q(## +A!+!344+ 1Q4**		
    c              3   .   K   | ]} |          V  d S N ).0r   r   s     r   	<genexpr>z)_footprint_is_sequence.<locals>.<genexpr>)   s/      DDQ--a00DDDDDDr   zAll elements of footprint sequence must be a 2-tuple where the first element of the tuple is an ndarray and the second is an integer indicating the number of iterations.z/footprint must be either an ndarray or SequenceT)r   r   r   all
ValueError)	footprintr   s    @r   _footprint_is_sequencer      s    y/00 u
 
 
 )X&& LDDDD)DDDDD 	E  	 JKKK4r   Fc                    t          |           st          d          | d         d         j        }dg|z  }d }t          |          D ]}| d         \  }} ||j        |         |           |j        |         |dz
  |j        |         dz
  z  z   ||<   | dd         D ]=\  }} ||j        |         |           ||xx         ||j        |         dz
  z  z  cc<   >t          |          S )zDetermine the shape of composite footprint

    In the future if we only want to support odd-sized square, we may want to
    change this to require_odd_size
    z!expected a sequence of footprintsr   c                 >    |r| dz  dk    rt          d          d S d S )Nr   r   z0expected all footprint elements to have odd sizer   )sizerequire_odd_sizes     r   	_odd_sizez'_shape_from_sequence.<locals>._odd_size?   s6     	QqAOPPP	Q 	Qr   r   N)r   r   ndimrangeshapetuple)
footprintsr"   r$   r&   r#   dfpnrepss           r   _shape_from_sequencer,   4   s#    "*-- ><===a= DC$JEQ Q Q 4[[ 2 2qM	E	"(1+/0008A;%!)a!@@a#ABB 	2 	2IBIbhqk#3444!HHH!q11HHHH	2 <<r   c                     t          |           }t          j        |t                    }d|t	          d |D                       <   t          j        ||           S )a   Convert a footprint sequence into an equivalent ndarray.

    Parameters
    ----------
    footprints : tuple of 2-tuples
        A sequence of footprint tuples where the first element of each tuple
        is an array corresponding to a footprint and the second element is the
        number of times it is to be applied. Currently, all footprints should
        have odd size.

    Returns
    -------
    footprint : ndarray
        An single array equivalent to applying the sequence of ``footprints``.
    dtyper   c              3       K   | ]	}|d z  V  
dS )r   Nr   )r   ss     r   r   z*footprint_from_sequence.<locals>.<genexpr>a   s&      %%!qAv%%%%%%r   )r,   npzerosboolr'   r   binary_dilation)r(   r&   imags      r   footprint_from_sequencer7   M   sY    $ !,,E8E&&&D)*D%%u%%%	%	%&%dJ777r   r/   decompositionc                ~    t          d  D                       }|dk    r|rt          j        dd           d} fd|t          j         	          }n|d
v r)t          fdt                     D                       }n|dk    rt                     }t          |d          }t          j        dt                     z  	          |fg}t                     D ]4\  }}||k    r)||z
  dz   }	 ||	          }
|
                    |
           5t          |          }nt          d|           |S )a_	  Generate a rectangular or hyper-rectangular footprint.

    Generates, depending on the length and dimensions requested with `shape`,
    a square, rectangle, cube, cuboid, or even higher-dimensional versions
    of these shapes.

    Parameters
    ----------
    shape : tuple[int, ...]
        The length of the footprint in each dimension. The length of the
        sequence determines the number of dimensions of the footprint.
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'separable', 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        give an identical result to a single, larger footprint, but often with
        better computational performance. See Notes for more details.
        With 'separable', this function uses separable 1D footprints for each
        axis. Whether 'sequence' or 'separable' is computationally faster may
        be architecture-dependent.

    Returns
    -------
    footprint : array or tuple[tuple[ndarray, int], ...]
        A footprint consisting only of ones, i.e. every pixel belongs to the
        neighborhood. When `decomposition` is None, this is just an array.
        Otherwise, this will be a tuple whose length is equal to the number of
        unique structuring elements to apply (see Examples for more detail).

    Examples
    --------
    >>> import skimage as ski
    >>> ski.morphology.footprint_rectangle((3, 5))
    array([[1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1]], dtype=uint8)

    Decomposition will return multiple footprints that combine into a simple
    footprint of the requested shape.

    >>> ski.morphology.footprint_rectangle((9, 9), decomposition="sequence")
    ((array([[1, 1, 1],
             [1, 1, 1],
             [1, 1, 1]], dtype=uint8),
      4),)

    `"sequence"` makes sure that the decomposition only returns 1D footprints.

    >>> ski.morphology.footprint_rectangle((3, 5), decomposition="separable")
    ((array([[1],
             [1],
             [1]], dtype=uint8),
      1),
     (array([[1, 1, 1, 1, 1]], dtype=uint8), 1))

    Generate a 5-dimensional hypercube with 3 samples in each dimension

    >>> ski.morphology.footprint_rectangle((3,) * 5).shape
    (3, 3, 3, 3, 3)
    c              3   (   K   | ]}|d z  dk    V  dS )r   r   Nr   )r   widths     r   r   z&footprint_rectangle.<locals>.<genexpr>   s*      ;;Ea;;;;;;r   sequencezkdecomposition='sequence' is only supported for uneven footprints, falling back to decomposition='separable'r   )
stacklevelsequence_fallbackc                 |    d| z  |fz   dt                    | z
  dz
  z  z   }t          j        |          df}|S )Nr   r   r.   )r   r2   ones)dimr<   shape_r*   r/   r&   s       r   partial_footprintz.footprint_rectangle.<locals>.partial_footprint   sK    uh&Uc1AA1E)FFgfE***A.	r   Nr.   )	separabler?   c              3   6   K   | ]\  }} ||          V  d S r   r   )r   rC   r<   rE   s      r   r   z&footprint_rectangle.<locals>.<genexpr>   sF       
 
.8c5c5))
 
 
 
 
 
r   r	   r	   r   Unrecognized decomposition: )anywarningswarnr2   rB   r'   	enumeratemin_decompose_sizer   appendr   )r&   r/   r9   has_even_widthr   	min_widthsq_repsrC   r<   nextra	componentrE   s   ``         @r   footprint_rectanglerV   e   s   | ;;U;;;;;N
""~"8	
 	
 	
 	

 ,     
 GE///			<	<	< 
 
 
 
<Ee<L<L
 
 
 
 
		 
*	$	$JJ	!)Q//gdSZZ/u===wGH	#E** 	, 	,JCy  *Q.--c6::	  +++)$$		 GGGHHHr   z0.25z0.27z5Use `skimage.morphology.footprint_rectangle` instead.)deprecated_versionremoved_versionhintr9   c                .    t          | | f||          }|S )a  Generates a flat, square-shaped footprint.

    Every pixel along the perimeter has a chessboard distance
    no greater than radius (radius=floor(width/2)) pixels.

    Parameters
    ----------
    width : int
        The width and height of the square.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'separable', 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        give an identical result to a single, larger footprint, but often with
        better computational performance. See Notes for more details.
        With 'separable', this function uses separable 1D footprints for each
        axis. Whether 'sequence' or 'separable' is computationally faster may
        be architecture-dependent.

    Returns
    -------
    footprint : ndarray or tuple
        The footprint where elements of the neighborhood are 1 and 0 otherwise.
        When `decomposition` is None, this is just a numpy.ndarray. Otherwise,
        this will be a tuple whose length is equal to the number of unique
        structuring elements to apply (see Notes for more detail)

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    For binary morphology, using ``decomposition='sequence'`` or
    ``decomposition='separable'`` were observed to give better performance than
    ``decomposition=None``, with the magnitude of the performance increase
    rapidly increasing with footprint size. For grayscale morphology with
    square footprints, it is recommended to use ``decomposition=None`` since
    the internal SciPy functions that are called already have a fast
    implementation based on separable 1D sliding windows.

    The 'sequence' decomposition mode only supports odd valued `width`. If
    `width` is even, the sequence used will be identical to the 'separable'
    mode.
    r&   r/   r9   rV   r<   r/   r9   r   s       r   squarer_      s,    n $enE  I r   c                 N    |dz  dk    rt          d          d| |z
  |dz
  z  z   S )zDetermine number of repeated iterations for a `kernel_size` kernel.

    Returns how many repeated morphology operations with an element of size
    `kernel_size` is equivalent to a morphology with a single kernel of size
    `n`.

    r   r   z(only odd length kernel_size is supportedr    )r!   kernel_sizes     r   rO   rO     s;     Q!CDDD{"a888r   c                .    t          | |f||          }|S )aH	  Generates a flat, rectangular-shaped footprint.

    Every pixel in the rectangle generated for a given width and given height
    belongs to the neighborhood.

    Parameters
    ----------
    nrows : int
        The number of rows of the rectangle.
    ncols : int
        The number of columns of the rectangle.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'separable', 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given an identical result to a single, larger footprint, but often with
        better computational performance. See Notes for more details.
        With 'separable', this function uses separable 1D footprints for each
        axis. Whether 'sequence' or 'separable' is computationally faster may
        be architecture-dependent.

    Returns
    -------
    footprint : ndarray or tuple
        A footprint consisting only of ones, i.e. every pixel belongs to the
        neighborhood. When `decomposition` is None, this is just a
        numpy.ndarray. Otherwise, this will be a tuple whose length is equal to
        the number of unique structuring elements to apply (see Notes for more
        detail)

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    For binary morphology, using ``decomposition='sequence'``
    was observed to give better performance, with the magnitude of the
    performance increase rapidly increasing with footprint size. For grayscale
    morphology with rectangular footprints, it is recommended to use
    ``decomposition=None`` since the internal SciPy functions that are called
    already have a fast implementation based on separable 1D sliding windows.

    The `sequence` decomposition mode only supports odd valued `nrows` and
    `ncols`. If either `nrows` or `ncols` is even, the sequence used will be
    identical to ``decomposition='separable'``.

    - The use of ``width`` and ``height`` has been deprecated in
      version 0.18.0. Use ``nrows`` and ``ncols`` instead.
    r\   r]   )nrowsncolsr/   r9   r   s        r   	rectanglere     s,    x $enE  I r   c                   |{t          j        d| dz  dz             }t          j        ||          \  }}t          j        t          j        || z
            t          j        || z
            z   | k    |          }nQ|dk    r9t          d|d          }t          d| z  dz   |j        d                   }||ff}nt          d|           |S )	aD  Generates a flat, diamond-shaped footprint.

    A pixel is part of the neighborhood (i.e. labeled 1) if
    the city block/Manhattan distance between it and the center of
    the neighborhood is no greater than radius.

    Parameters
    ----------
    radius : int
        The radius of the diamond-shaped footprint.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given an identical result to a single, larger footprint, but with
        better computational performance. See Notes for more details.

    Returns
    -------
    footprint : ndarray or tuple
        The footprint where elements of the neighborhood are 1 and 0 otherwise.
        When `decomposition` is None, this is just a numpy.ndarray. Otherwise,
        this will be a tuple whose length is equal to the number of unique
        structuring elements to apply (see Notes for more detail)

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    For either binary or grayscale morphology, using
    ``decomposition='sequence'`` was observed to have a performance benefit,
    with the magnitude of the benefit increasing with increasing footprint
    size.

    Nr   r   r   r.   r=   r8   rI   )	r2   arangemeshgridarrayabsdiamondrO   r&   r   )	radiusr/   r9   LIJr   r*   r+   s	            r   rk   rk   V  s    T Ia!a(({1a  1HF1v:F
!3!33v=U
 
 
		 
*	$	$Qe4888F
Q<<%[N		GGGHHHr   c                 <   | dk    r<t          |dd          }|dk    rt          di |dffS |dk    rt          di |dffS |t          vrt	          d          t          |         }|j        d         }| |k    rt	          d	| d
|           ||          \  }}g dk    r t          ||          }fd|D              |dk    rt          j        d|z  |          }	t          dd          g|z  }
t          |          D ]9}t          d          |
|<   d|	t          |
          <   t          dd          |
|<   :                    |	|f           |dk    r0t          j        d|z  |          }                    ||f           t                    S )a  Generate a sequence of footprints approximating an n-sphere.

    Morphological operations with an n-sphere (hypersphere) footprint can be
    approximated by applying a series of smaller footprints of extent 3 along
    each axis. Specific solutions for this are given in [1]_ for the case of
    2D disks with radius 2 through 10.

    Here we used n-dimensional extensions of the "square", "diamond" and
    "t-shaped" elements from that publication. All of these elementary elements
    have size ``(3,) * ndim``. We numerically computed the number of
    repetitions of each element that gives the closest match to the disk
    (in 2D) or ball (in 3D) computed with ``decomposition=None``.

    The approach can be extended to higher dimensions, but we have only stored
    results for 2D and 3D at this point.

    Empirically, the shapes at large radius approach a hexadecagon
    (16-sides [2]_) in 2D and a rhombicuboctahedron (26-faces, [3]_) in 3D.

    References
    ----------
    .. [1] Park, H and Chin R.T. Decomposition of structuring elements for
           optimal implementation of morphological operations. In Proceedings:
           1997 IEEE Workshop on Nonlinear Signal and Image Processing, London,
           UK.
           https://www.iwaenc.org/proceedings/1997/nsip97/pdf/scan/ns970226.pdf
    .. [2] https://en.wikipedia.org/wiki/Hexadecagon
    .. [3] https://en.wikipedia.org/wiki/Rhombicuboctahedron
    r   FN)r/   strict_radiusr9   r   r	   zMsequence decompositions are only currently available for 2d disks or 3d ballsr   zprecomputed z)D decomposition unavailable for radius > r$   r/   c                 >    g | ]}                     |f          S r   )rP   )r   r   num_t_seriesr=   s     r   
<listcomp>z1_nsphere_series_decomposition.<locals>.<listcomp>  s*    ;;;!\*	+	+;;;r   rH   r.   rA   )dictdiskball_nsphere_decompositionsr   r&   _t_shaped_element_seriesr2   r3   slicer%   r'   rP   rB   )rl   r$   r/   kwargsprecomputed_decompositions
max_radiusnum_diamond
num_squareall_tr)   slaxsqrt   r=   s                @@r   _nsphere_series_decompositionr     s   > {{EdKKK199&&v&&*,,QYY&&v&&*,, ***#
 
 	
 "9!>+1!4J
%4 % %"% %
 
 	
 -Gv,N)L+zHa(d%@@@;;;;;U;;;;QHTD[...Aqkk]T!++ 	! 	!B4[[BrFAeBiiL1a[[BrFFK()))A~~WTD[...Z()))??r   c                 h   | dk    rdt          j        g dg dg dg|          }t          j        |d          }t          j        |d          }t          j        |d          }||||fS g }t          |           D ]}dD ]}t          j        d| z  |          }	t          d	          g| z  }
t          ||dz             |
|<   d|	t          |
          <   t          dd          g| z  }
t          d	          |
|<   d|	t          |
          <   |                    |	           t          |          S )
a  A series of T-shaped structuring elements.

    In the 2D case this is a T-shaped element and its rotation at multiples of
    90 degrees. This series is used in efficient decompositions of disks of
    various radius as published in [1]_.

    The generalization to the n-dimensional case can be performed by having the
    "top" of the T to extend in (ndim - 1) dimensions and then producing a
    series of rotations such that the bottom end of the T points along each of
    ``2 * ndim`` orthogonal directions.
    r   )r   r   r   )r   r   r   r.   r   r	   )r   r   rH   N)r2   ri   rot90r%   r3   r{   r'   rP   )r$   r/   t0t90t180t270r   r   idxr   r   s              r   rz   rz     sC    qyy Xyyy)))YYY7uEEEhr1ooxAxA3d"" ++ 		  		 B    HTD[666Dkk]T)sC!G,,2 %))Aqkk]T)t2 %))Q  <<r   Trq   r9   c                H   |^t          j        |  | dz             }t          j        ||          \  }}|s| dz  } t          j        |dz  |dz  z   | dz  k    |          S |dk    rt	          | d|          }n(|dk    r"t          | ||d	          }t          |          }|S )
u  Generates a flat, disk-shaped footprint.

    A pixel is within the neighborhood if the Euclidean distance between
    it and the origin is no greater than radius (This is only approximately
    True, when `decomposition == 'sequence'`).

    Parameters
    ----------
    radius : int
        The radius of the disk-shaped footprint.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    strict_radius : bool, optional
        If False, extend the radius by 0.5. This allows the circle to expand
        further within a cube that remains of size ``2 * radius + 1`` along
        each axis. This parameter is ignored if decomposition is not None.
    decomposition : {None, 'sequence', 'crosses'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given a result equivalent to a single, larger footprint, but with
        better computational performance. For disk footprints, the 'sequence'
        or 'crosses' decompositions are not always exactly equivalent to
        ``decomposition=None``. See Notes for more details.

    Returns
    -------
    footprint : ndarray
        The footprint where elements of the neighborhood are 1 and 0 otherwise.

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    The disk produced by the ``decomposition='sequence'`` mode may not be
    identical to that with ``decomposition=None``. A disk footprint can be
    approximated by applying a series of smaller footprints of extent 3 along
    each axis. Specific solutions for this are given in [1]_ for the case of
    2D disks with radius 2 through 10. Here, we numerically computed the number
    of repetitions of each element that gives the closest match to the disk
    computed with kwargs ``strict_radius=False, decomposition=None``.

    Empirically, the series decomposition at large radius approaches a
    hexadecagon (a 16-sided polygon [2]_). In [3]_, the authors demonstrate
    that a hexadecagon is the closest approximation to a disk that can be
    achieved for decomposition with footprints of shape (3, 3).

    The disk produced by the ``decomposition='crosses'`` is often but not
    always  identical to that with ``decomposition=None``. It tends to give a
    closer approximation than ``decomposition='sequence'``, at a performance
    that is fairly comparable. The individual cross-shaped elements are not
    limited to extent (3, 3) in size. Unlike the 'seqeuence' decomposition, the
    'crosses' decomposition can also accurately approximate the shape of disks
    with ``strict_radius=True``. The method is based on an adaption of
    algorithm 1 given in [4]_.

    References
    ----------
    .. [1] Park, H and Chin R.T. Decomposition of structuring elements for
           optimal implementation of morphological operations. In Proceedings:
           1997 IEEE Workshop on Nonlinear Signal and Image Processing, London,
           UK.
           https://www.iwaenc.org/proceedings/1997/nsip97/pdf/scan/ns970226.pdf
    .. [2] https://en.wikipedia.org/wiki/Hexadecagon
    .. [3] Vanrell, M and Vitrià, J. Optimal 3 × 3 decomposable disks for
           morphological transformations. Image and Vision Computing, Vol. 15,
           Issue 11, 1997.
           :DOI:`10.1016/S0262-8856(97)00026-7`
    .. [4] Li, D. and Ritter, G.X. Decomposition of Separable and Symmetric
           Convex Templates. Proc. SPIE 1350, Image Algebra and Morphological
           Image Processing, (1 November 1990).
           :DOI:`10.1117/12.23608`
    Nr         ?r   r.   r=   rr   crossesr   )r2   rg   rh   ri   r   rw   _cross_decomposition)	rl   r/   rq   r9   rm   XYr=   r*   s	            r   rw   rw     s    \ Ivgvz**{1a  1 	cMFxA12%@@@@	*	$	$0auMMM	)	#	#&%}DQQQ'++Or   c                     t          d| z  dz             }t          d|z  dz             }t          j        ||f|          }|dk    r	d|| ddf<   | dk    r	d|dd|f<   |S )zgCross-shaped structuring element of shape (r0, r1).

    Only the central row and column are ones.
    r   r   r.   r   N)intr2   r3   )r0r1r/   s0s1cs         r   _crossr   X  s{    
 
QVaZB	QVaZB
"b'''A	Qww"aaa%	Qww!!!R%Hr   c                    | | j         d         dz  d| j         d         dz  df         }|                    dt                    }t          j        |t          j        dgt                    f          }d}i }d}t          |j        dz
            D ][}||         ||dz            k    rD|dk    r||         ||         z
  ||z
  f}||d         z  }||vrd||<   n||xx         dz  cc<   |}\|j         d         dz
  |z
  }	|	dk    r |	df}|                    |d          dz   ||<   t          fd|
                                D                       S )aK  Decompose a symmetric convex footprint into cross-shaped elements.

    This is a decomposition of the footprint into a sequence of
    (possibly asymmetric) cross-shaped elements. This technique was proposed in
    [1]_ and corresponds roughly to algorithm 1 of that publication (some
    details had to be modified to get reliable operation).

    .. [1] Li, D. and Ritter, G.X. Decomposition of Separable and Symmetric
           Convex Templates. Proc. SPIE 1350, Image Algebra and Morphological
           Image Processing, (1 November 1990).
           :DOI:`10.1117/12.23608`
    r   r   Nr   r.   c                 B    g | ]\  \  }}}t          ||          |fS r   )r   )r   r   r   nr/   s       r   ru   z(_cross_decomposition.<locals>.<listcomp>  s2    LLL"b16"b%((!,LLLr   )r&   sumr   r2   concatenateasarrayr%   r!   getr'   items)
r   r/   quadrantcol_sumsi_prevr   sum0ikeyr   s
    `        r   r   r   g  s    +q022IOA4F!4K4M4MMNH||AS|))H~xQCs)C)C)CDEEHF
CD8=1$%% 
 
A;!a%((AvvF#hqk11v:>CCFND#~~CCAFqA$A1uu!f773??Q&CLLLL		LLLMMMr   c                    |Mt          j        d|z  dz   d| z  dz   f|          }t          j        || |dz   | dz             \  }}d|||f<   |S |dk    r"t          | ||d          }t	          |          }|S )aq  Generates a flat, ellipse-shaped footprint.

    Every pixel along the perimeter of ellipse satisfies
    the equation ``(x/width+1)**2 + (y/height+1)**2 = 1``.

    Parameters
    ----------
    width : int
        The width of the ellipse-shaped footprint.
    height : int
        The height of the ellipse-shaped footprint.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'crosses'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given an identical result to a single, larger footprint, but with
        better computational performance. See Notes for more details.

    Returns
    -------
    footprint : ndarray
        The footprint where elements of the neighborhood are 1 and 0 otherwise.
        The footprint will have shape ``(2 * height + 1, 2 * width + 1)``.

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    The ellipse produced by the ``decomposition='crosses'`` is often but not
    always  identical to that with ``decomposition=None``. The method is based
    on an adaption of algorithm 1 given in [1]_.

    References
    ----------
    .. [1] Li, D. and Ritter, G.X. Decomposition of Separable and Symmetric
           Convex Templates. Proc. SPIE 1350, Image Algebra and Morphological
           Image Processing, (1 November 1990).
           :DOI:`10.1117/12.23608`

    Examples
    --------
    >>> from skimage.morphology import footprints
    >>> footprints.ellipse(5, 3)
    array([[0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
           [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]], dtype=uint8)

    Nr   r   r.   r   rZ   )r2   r3   r   ellipser   )	r<   heightr/   r9   r   rowscolsr*   r=   s	            r   r   r     s    v Ha&j1na%i!m<EJJJ	\&%!UQYGG
d !	$*	)	#	#UFE>>>'++Or   c                0    t          | | | f||          }|S )a  Generates a cube-shaped footprint.

    This is the 3D equivalent of a square.
    Every pixel along the perimeter has a chessboard distance
    no greater than radius (radius=floor(width/2)) pixels.

    Parameters
    ----------
    width : int
        The width, height and depth of the cube.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'separable', 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given an identical result to a single, larger footprint, but often with
        better computational performance. See Notes for more details.

    Returns
    -------
    footprint : ndarray or tuple
        The footprint where elements of the neighborhood are 1 and 0 otherwise.
        When `decomposition` is None, this is just a numpy.ndarray. Otherwise,
        this will be a tuple whose length is equal to the number of unique
        structuring elements to apply (see Notes for more detail)

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    For binary morphology, using ``decomposition='sequence'``
    was observed to give better performance, with the magnitude of the
    performance increase rapidly increasing with footprint size. For grayscale
    morphology with square footprints, it is recommended to use
    ``decomposition=None`` since the internal SciPy functions that are called
    already have a fast implementation based on separable 1D sliding windows.

    The 'sequence' decomposition mode only supports odd valued `width`. If
    `width` is even, the sequence used will be identical to the 'separable'
    mode.
    r\   r]   r^   s       r   cuber     s/    h $eU#5  I r   c                   |d| z  dz   }t           j        |  | |dz  |  | |dz  |  | |dz  f         \  }}}t          j        |          t          j        |          z   t          j        |          z   }t          j        || k    |          }nQ|dk    r9t	          d|d          }	t          d| z  dz   |	j        d                   }
|	|
ff}nt          d	|           |S )
ao  Generates a octahedron-shaped footprint.

    This is the 3D equivalent of a diamond.
    A pixel is part of the neighborhood (i.e. labeled 1) if
    the city block/Manhattan distance between it and the center of
    the neighborhood is no greater than radius.

    Parameters
    ----------
    radius : int
        The radius of the octahedron-shaped footprint.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given an identical result to a single, larger footprint, but with
        better computational performance. See Notes for more details.

    Returns
    -------
    footprint : ndarray or tuple
        The footprint where elements of the neighborhood are 1 and 0 otherwise.
        When `decomposition` is None, this is just a numpy.ndarray. Otherwise,
        this will be a tuple whose length is equal to the number of unique
        structuring elements to apply (see Notes for more detail)

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    For either binary or grayscale morphology, using
    ``decomposition='sequence'`` was observed to have a performance benefit,
    with the magnitude of the benefit increasing with increasing footprint
    size.
    Nr   r                 ?r.   r=   r8   r   rI   )r2   mgridrj   ri   
octahedronrO   r&   r   )rl   r/   r9   r   Zr   r   r1   r   r*   r+   s              r   r   r     s   V JN(Gfq2v%Gfq2v%Gfq2v%'
1a
 F1IIq		!BF1II-HQ&[666			*	$	$d;;;F
Q<<%[N		GGGHHHr   c                6   |kd| z  dz   }t           j        |  | |dz  |  | |dz  |  | |dz  f         \  }}}|dz  |dz  z   |dz  z   }|s| dz  } t          j        || | z  k    |          S |dk    rt          | d|	          }	nt	          d
|           |	S )ab	  Generates a ball-shaped footprint.

    This is the 3D equivalent of a disk.
    A pixel is within the neighborhood if the Euclidean distance between
    it and the origin is no greater than radius.

    Parameters
    ----------
    radius : float
        The radius of the ball-shaped footprint.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    strict_radius : bool, optional
        If False, extend the radius by 0.5. This allows the circle to expand
        further within a cube that remains of size ``2 * radius + 1`` along
        each axis. This parameter is ignored if decomposition is not None.
    decomposition : {None, 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given a result equivalent to a single, larger footprint, but with
        better computational performance. For ball footprints, the sequence
        decomposition is not exactly equivalent to decomposition=None.
        See Notes for more details.

    Returns
    -------
    footprint : ndarray or tuple
        The footprint where elements of the neighborhood are 1 and 0 otherwise.

    Notes
    -----
    The disk produced by the decomposition='sequence' mode is not identical
    to that with decomposition=None. Here we extend the approach taken in [1]_
    for disks to the 3D case, using 3-dimensional extensions of the "square",
    "diamond" and "t-shaped" elements from that publication. All of these
    elementary elements have size ``(3,) * ndim``. We numerically computed the
    number of repetitions of each element that gives the closest match to the
    ball computed with kwargs ``strict_radius=False, decomposition=None``.

    Empirically, the equivalent composite footprint to the sequence
    decomposition approaches a rhombicuboctahedron (26-faces [2]_).

    References
    ----------
    .. [1] Park, H and Chin R.T. Decomposition of structuring elements for
           optimal implementation of morphological operations. In Proceedings:
           1997 IEEE Workshop on Nonlinear Signal and Image Processing, London,
           UK.
           https://www.iwaenc.org/proceedings/1997/nsip97/pdf/scan/ns970226.pdf
    .. [2] https://en.wikipedia.org/wiki/Rhombicuboctahedron
    Nr   r   r   r   r.   r=   r	   rr   rI   )r2   r   ri   r   r   )
rl   r/   rq   r9   r   r   r   r   r1   r=   s
             r   rx   rx   I  s    n JN(Gfq2v%Gfq2v%Gfq2v%'
1a
 qD1a4K!Q$ 	cMFxVf_,E::::	*	$	$0auMMMGGGHHHOr   c                   | |cxk    rdk    rn nt          d          |ddlm} t          j        | d|z  z   | d|z  z   f          }d|d|f<   d||df<   d|d| |z   dz
  f<   d|| |z   dz
  df<   d|d|f<   d||df<   d|d| |z   dz
  f<   d|| |z   dz
  df<    ||                              |          }n|dk    r| dk    r|dk    rt          | ||d	          dffS | dk    rd} |dz  }g }| dk    r$|t          t          | | f|d	                    z  }|dk    r|t          d|d	          |fgz  }t          |          }nt          d
|           |S )a  Generates an octagon shaped footprint.

    For a given size of (m) horizontal and vertical sides
    and a given (n) height or width of slanted sides octagon is generated.
    The slanted sides are 45 or 135 degrees to the horizontal axis
    and hence the widths and heights are equal. The overall size of the
    footprint along a single axis will be ``m + 2 * n``.

    Parameters
    ----------
    m : int
        The size of the horizontal and vertical sides.
    n : int
        The height or width of the slanted sides.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.
    decomposition : {None, 'sequence'}, optional
        If None, a single array is returned. For 'sequence', a tuple of smaller
        footprints is returned. Applying this series of smaller footprints will
        given an identical result to a single, larger footprint, but with
        better computational performance. See Notes for more details.

    Returns
    -------
    footprint : ndarray or tuple
        The footprint where elements of the neighborhood are 1 and 0 otherwise.
        When `decomposition` is None, this is just a numpy.ndarray. Otherwise,
        this will be a tuple whose length is equal to the number of unique
        structuring elements to apply (see Notes for more detail)

    Notes
    -----
    When `decomposition` is not None, each element of the `footprint`
    tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
    footprint array and the number of iterations it is to be applied.

    For either binary or grayscale morphology, using
    ``decomposition='sequence'`` was observed to have a performance benefit,
    with the magnitude of the benefit increasing with increasing footprint
    size.
    r   zm and n cannot both be zeroNr   convex_hull_imager   r=   r8   rI   )r    r   r2   r3   astypeoctagonlistrV   rk   r'   )mr   r/   r9   r   r   r=   s          r   r   r     s   Z 	A{{{{{{{{{6777 ''''''Ha!a%iQU344		!Q$	!Q$"#	!QUQY,"#	!a%!)Q,	"a%	!R%#$	"a!eai- #$	!a%!)R- %%i0077>>			*	$	$66a1ffQdCCCQGII 66AFAq55#QF%zRRR  H q55'!5EEEqIJJH(OO		GGGHHHr   c                    ddl m} | dk    rt          j        d|          }d|dd<   |S d| z  dz   }| dz  }t          j        |d|z  z   |d|z  z   f          }d||||z   |||z   f<   |d|z  z   dz
  dz  }t          j        |d|z  z   |d|z  z   f          }dx|d|f<   |d|f<   dx||df<   ||df<    ||                              t
                    }||z   }	d|	|	dk    <   |	                    |          S )a  Generates a star shaped footprint.

    Start has 8 vertices and is an overlap of square of size `2*a + 1`
    with its 45 degree rotated version.
    The slanted sides are 45 or 135 degrees to the horizontal axis.

    Parameters
    ----------
    a : int
        Parameter deciding the size of the star structural element. The side
        of the square array returned is `2*a + 1 + 2*floor(a / 2)`.

    Other Parameters
    ----------------
    dtype : data-type, optional
        The data type of the footprint.

    Returns
    -------
    footprint : ndarray
        The footprint where elements of the neighborhood are 1 and 0 otherwise.

    r   r   )r	   r	   Nr   r   r   )r   r   r2   r3   r   r   )
ar/   r   bfilterr   r   footprint_squarer   footprint_rotatedr   s
             r   starr     sa   0 $#####Avv(65))
	A	A	QAxQUAAI 677-.QQYAE	)*	
QUQ1A!a!e)QQY!7889::ad/A69::ad/26))*;<<CCCHH #44I Ii!mE"""r   c                     t          |           rt          d | D                       S t          j        |           } | t	          ddd          f| j        z           S )a'  Mirror each dimension in the footprint.

    Parameters
    ----------
    footprint : ndarray or tuple
        The input footprint or sequence of footprints

    Returns
    -------
    inverted : ndarray or tuple
        The footprint, mirrored along each dimension.

    Examples
    --------
    >>> footprint = np.array([[0, 0, 0],
    ...                       [0, 1, 1],
    ...                       [0, 1, 1]], np.uint8)
    >>> mirror_footprint(footprint)
    array([[1, 1, 0],
           [1, 1, 0],
           [0, 0, 0]], dtype=uint8)

    c              3   >   K   | ]\  }}t          |          |fV  d S r   )mirror_footprint)r   r*   r   s      r   r   z#mirror_footprint.<locals>.<genexpr>0  s4      FF52q&r**A.FFFFFFr   Nr   )r   r'   r2   r   r{   r$   )r   s    r   r   r     sb    0 i(( GFFIFFFFFF
9%%IeD$++-	>??r   pad_endc                
   t          |           rt          fd| D                       S t          j        |           } g }| j        D ]&}|                    |dz  dk    rrdndnd           't          j        | |          S )a  Pad the footprint to an odd size along each dimension.

    Parameters
    ----------
    footprint : ndarray or tuple
        The input footprint or sequence of footprints
    pad_end : bool, optional
        If ``True``, pads at the end of each dimension (right side), otherwise
        pads on the front (left side).

    Returns
    -------
    padded : ndarray or tuple
        The footprint, padded to an odd size along each dimension.

    Examples
    --------
    >>> footprint = np.array([[0, 0],
    ...                       [1, 1],
    ...                       [1, 1]], np.uint8)
    >>> pad_footprint(footprint)
    array([[0, 0, 0],
           [1, 1, 0],
           [1, 1, 0]], dtype=uint8)

    c              3   D   K   | ]\  }}t          |           |fV  dS )r   N)pad_footprint)r   r*   r   r   s      r   r   z pad_footprint.<locals>.<genexpr>Q  s9      TTQmB888!<TTTTTTr   r   r   )r   r   )r   r   )r   r   )r   r'   r2   r   r&   rP   pad)r   r   paddingszs    `  r   r   r   5  s    6 i(( UTTTT)TTTTTT
9%%IGo S S"q&A++'5vv6RRRR6)W%%%r   )FrH   )*osrK   collections.abcr   numbersr   numpyr2   r   r   skimager   _shared.utilsr   ry   loadpathjoindirname__file__r   r,   r7   uint8rV   r_   rO   re   rk   r   rz   rw   r   r   r   r   r   rx   r   r   r   r   r   r   r   <module>r      s9   				  $ $ $ $ $ $                       * * * * * *  $RWGLL**,EFF    %RWGLL**,EFF   
  0   28 8 80 )+ b b b b bJ 	@  
  54 5 5 5 5 
5p
9 
9 
9 
9 	@  
 #%( :T : : : : 
:z ( 6T 6 6 6 6 6r 79h F F F FR #$28 ! ! ! !H x Y$d Y Y Y Y Yx      +-( "N "N "N "NJ "$ CD C C C C CL 	@  
 h 2 2 2 2 2 
2j  X : : : : : :z x F$d F F F F FR  R4 R R R R Rj ( -# -# -# -#`@ @ @< )- !& !& !& !& !& !& !&r   