
    0-Ph$                     :    d dl ZddlmZ ddlmZ ddlmZ d	dZdS )
    N   )_supported_float_type)
rank_order   )reconstruction_loopdilationc                 F
   t          | j                  t          |j                  k    sJ |dk    r't          j        | |k              rt	          d          |dk    r't          j        | |k               rt	          d          |%t          j        dg| j        z  t                    }n|                    t          d	          }|Qt          d
 |j        D                       st	          d          t          j
        d |j        D                       }nZ|j        |j        k    rt	          d          t          d t          ||j                  D                       st	          d          d|t          d |D                       <   t          j        | j        dz   t                    }t          j
        | j                  t          j
        |j                  dz
  z   |dd<   d|d<   t          d t          || j                  D                       }|dk    rt          j        |           }n.|dk    rt          j        |           }nt	          d| d          t!          |j                  }t          j        |||          }	| |	dg|R <   ||	dg|R <   |	j        }
t          j        t          j        |
           t          j                  }t          j        |j                                                  }t          j
        |	j        dd                   |	j        j        z  |	j        d         |	j        j        z  }t          j        d t          |j        |          D                      }|dd|f                                         }t          j
        fd|D             |          }|	                    d          }	t          j        |	                              |d	          }|dk    r|ddd         }t          j        |
d|          }t          j        |
d|          }|dd         ||dd         <   |dd         ||dd         <   |dk    rt?          |	          \  }}n|dk    rt?          |	           \  }}| }|d         }|                    |d	          }tA          ||||||           ||d|                  }t          j
        | j                  t          j
        |j                  dz
  z   |_        ||         S )a  Perform a morphological reconstruction of an image.

    Morphological reconstruction by dilation is similar to basic morphological
    dilation: high-intensity values will replace nearby low-intensity values.
    The basic dilation operator, however, uses a footprint to
    determine how far a value in the input image can spread. In contrast,
    reconstruction uses two images: a "seed" image, which specifies the values
    that spread, and a "mask" image, which gives the maximum allowed value at
    each pixel. The mask image, like the footprint, limits the spread
    of high-intensity values. Reconstruction by erosion is simply the inverse:
    low-intensity values spread from the seed image and are limited by the mask
    image, which represents the minimum allowed value.

    Alternatively, you can think of reconstruction as a way to isolate the
    connected regions of an image. For dilation, reconstruction connects
    regions marked by local maxima in the seed image: neighboring pixels
    less-than-or-equal-to those seeds are connected to the seeded region.
    Local maxima with values larger than the seed image will get truncated to
    the seed value.

    Parameters
    ----------
    seed : ndarray
        The seed image (a.k.a. marker image), which specifies the values that
        are dilated or eroded.
    mask : ndarray
        The maximum (dilation) / minimum (erosion) allowed value at each pixel.
    method : {'dilation'|'erosion'}, optional
        Perform reconstruction by dilation or erosion. In dilation (or
        erosion), the seed image is dilated (or eroded) until limited by the
        mask image. For dilation, each seed value must be less than or equal
        to the corresponding mask value; for erosion, the reverse is true.
        Default is 'dilation'.
    footprint : ndarray, optional
        The neighborhood expressed as an n-D array of 1's and 0's.
        Default is the n-D square of radius equal to 1 (i.e. a 3x3 square
        for 2D images, a 3x3x3 cube for 3D images, etc.)
    offset : ndarray, optional
        The coordinates of the center of the footprint.
        Default is located on the geometrical center of the footprint, in that
        case footprint dimensions must be odd.

    Returns
    -------
    reconstructed : ndarray
        The result of morphological reconstruction.

    Examples
    --------
    >>> import numpy as np
    >>> from skimage.morphology import reconstruction

    First, we create a sinusoidal mask image with peaks at middle and ends.

    >>> x = np.linspace(0, 4 * np.pi)
    >>> y_mask = np.cos(x)

    Then, we create a seed image initialized to the minimum mask value (for
    reconstruction by dilation, min-intensity values don't spread) and add
    "seeds" to the left and right peak, but at a fraction of peak value (1).

    >>> y_seed = y_mask.min() * np.ones_like(x)
    >>> y_seed[0] = 0.5
    >>> y_seed[-1] = 0
    >>> y_rec = reconstruction(y_seed, y_mask)

    The reconstructed image (or curve, in this case) is exactly the same as the
    mask image, except that the peaks are truncated to 0.5 and 0. The middle
    peak disappears completely: Since there were no seed values in this peak
    region, its reconstructed value is truncated to the surrounding value (-1).

    As a more practical example, we try to extract the bright features of an
    image by subtracting a background image created by reconstruction.

    >>> y, x = np.mgrid[:20:0.5, :20:0.5]
    >>> bumps = np.sin(x) + np.sin(y)

    To create the background image, set the mask image to the original image,
    and the seed image to the original image with an intensity offset, `h`.

    >>> h = 0.3
    >>> seed = bumps - h
    >>> background = reconstruction(seed, bumps)

    The resulting reconstructed image looks exactly like the original image,
    but with the peaks of the bumps cut off. Subtracting this reconstructed
    image from the original image leaves just the peaks of the bumps

    >>> hdome = bumps - background

    This operation is known as the h-dome of the image and leaves features
    of height `h` in the subtracted image.

    Notes
    -----
    The algorithm is taken from [1]_. Applications for grayscale reconstruction
    are discussed in [2]_ and [3]_.

    References
    ----------
    .. [1] Robinson, "Efficient morphological reconstruction: a downhill
           filter", Pattern Recognition Letters 25 (2004) 1759-1767.
    .. [2] Vincent, L., "Morphological Grayscale Reconstruction in Image
           Analysis: Applications and Efficient Algorithms", IEEE Transactions
           on Image Processing (1993)
    .. [3] Soille, P., "Morphological Image Analysis: Principles and
           Applications", Chapter 6, 2nd edition (2003), ISBN 3540429883.
    r   z`Intensity of seed image must be less than that of the mask image for reconstruction by dilation.erosionzbIntensity of seed image must be greater than that of the mask image for reconstruction by erosion.N   )dtypeT)copyc                      g | ]}|d z  dk    S )r   r    .0ds     b/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/skimage/morphology/grayreconstruct.py
<listcomp>z"reconstruction.<locals>.<listcomp>   s     8881AEQJ888    z$Footprint dimensions must all be oddc                     g | ]}|d z  S )r   r   r   s     r   r   z"reconstruction.<locals>.<listcomp>   s    ;;;a16;;;r   z)Offset and footprint ndims must be equal.c                 4    g | ]\  }}d |cxk    o|k     nc S )r   r   )r   or   s      r   r   z"reconstruction.<locals>.<listcomp>   s0    JJJTQQ!ZZZZaZZZZJJJr   z(Offset must be included inside footprintFc              3   <   K   | ]}t          ||d z             V  dS )r   Nslicer   s     r   	<genexpr>z!reconstruction.<locals>.<genexpr>   s.      44E!QUOO444444r   r   r   r   c              3   B   K   | ]\  }}t          |||z             V  d S )Nr   )r   r   ss      r   r   z!reconstruction.<locals>.<genexpr>   s2      NNda%1q5//NNNNNNr   zBReconstruction method can be one of 'erosion' or 'dilation'. Got 'z'.c                 <    g | ]\  }}t          | ||z
            S r   r   )r   r   r   s      r   r   z"reconstruction.<locals>.<listcomp>   s,    CCCdar1q5		CCCr   c                 >    g | ]}t          j        |z            S r   )npsum)r   footprint_offsetvalue_strides     r   r   z"reconstruction.<locals>.<listcomp>   s9     	
 	
 	
  F<"2233	
 	
 	
r   )!tupleshaper!   any
ValueErroronesndimboolastypeallarrayzipzerosintminmaxr   r   fullsizeresult_typemin_scalar_typeint32charupperstridesitemsizemgrid	transposereshapeargsortr   r   )seedmaskmethod	footprintoffsetdimsinside_slices	pad_valuefloat_dtypeimagesisizesigned_int_dtypeunsigned_int_dtypeimage_stridefootprint_mgridfootprint_offsets
nb_stridesindex_sortedprevnext
value_rank	value_mapstartrec_imgr$   s                           @r   reconstructionrZ      sa   Z dj 1 11111td{ 3 3@
 
 	
 
9		t!4!4	?
 
 	

 GQC$)O4888		$$T$55	~88	88899 	ECDDD;;9?;;;<<;).((HIIIJJS-I-IJJJKK 	IGHHH 9>Ie44V444445 8DIM---Dx
##rx	'@'@1'DEDHDGNNc&$*6M6MNNNNNM F4LL			9		F4LL		.#). . .
 
 	
 (
33KWT9K888F"&FA"&FA KE~b&8%&@&@"(KK"2"7"="="?"?@@ 8FN122.//6<3HHL>!$(==LhCCc)/6&B&BCCCO (95??AA	
 	
 	
 	
$5	
 	
 	
 	 J ^^BF :f%%,,-=E,JJL#DDbD) 75".//D75".//D)#2#.Dabb	*122.Dcrc	  *6 2 2
II	9		 *F7 3 3
IJ	OE""#5E"BBJ
D$
E<PPP 
=L=12GHTZ((BHY_,E,E,IJGM=!!r   )r   NN)	numpyr!   _shared.utilsr   filters._rank_orderr   _grayreconstructr   rZ   r   r   r   <module>r_      sk        1 1 1 1 1 1 , , , , , , 1 1 1 1 1 1Q" Q" Q" Q" Q" Q"r   