U
    ?h>                     @   s   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mZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZmZ dd Zdd ZejdddddddZdS )    N)Iterable)warn)random)kmeans2)pdist
squareform   )utils)gaussian)rgb2lab)img_as_floatregular_grid   )"_enforce_label_connectivity_cython_slic_cythonc                 C   s  t jt | tdj}td}t jt|t	d}t 
|j|t|t|dd}d}|rd| jd n| j}t	|| | }	t||	krt 
|j||	dd}
nt}
t||
 || dd\}}tt|}t |t j |d	}t|||d
d
f  d}||fS )a  Find regularly spaced centroids on a mask.

    Parameters
    ----------
    mask : 3D ndarray
        The mask within which the centroids must be positioned.
    n_centroids : int
        The number of centroids to be returned.

    Returns
    -------
    centroids : 2D ndarray
        The coordinates of the centroids with shape (n_centroids, 3).
    steps : 1D ndarray
        The approximate distance between two seeds in all dimensions.

    dtype{   F)replace
   r      )iterNr   )nparrayZnonzerofloatTr   ZRandomStateZarangelenintsortchoiceminndimEllipsisr   r   r   Zfill_diagonalinfZargminabsZmean)maskn_centroidsmultichannelZcoordrngZidx_fullidxZdense_factorZndim_spatialZn_denseZ	idx_dense	centroids_distZclosest_ptssteps r/   W/var/www/html/venv/lib/python3.8/site-packages/skimage/segmentation/slic_superpixels.py_get_mask_centroids   s,    

	


r1   c                 C   s   | j dd \}}}tjd|d|d|f \}}}t| j dd |}||  dtjf }	||  dtjf }
||  dtjf }tj|	|
|gdd}tdd |D }||fS )a  Find regularly spaced centroids on the image.

    Parameters
    ----------
    image : 2D, 3D or 4D ndarray
        Input image, which can be 2D or 3D, and grayscale or
        multichannel.
    n_centroids : int
        The (approximate) number of centroids to be returned.

    Returns
    -------
    centroids : 2D ndarray
        The coordinates of the centroids with shape (~n_centroids, 3).
    steps : 1D ndarray
        The approximate distance between two seeds in all dimensions.

    N   .r   Zaxisc                 S   s$   g | ]}|j d k	rt|j ndqS )N      ?)stepr   ).0sr/   r/   r0   
<listcomp>j   s   z'_get_grid_centroids.<locals>.<listcomp>)shaper   Zmgridr   Zravelnewaxisconcatenateasarray)imager'   dhwZgrid_zZgrid_yZgrid_xZslicesZcentroids_zZcentroids_yZcentroids_xr+   r.   r/   r/   r0   _get_grid_centroidsK   s    "
rA   F)Zmultichannel_outputd         $@r   T      ?r2   r   )channel_axisc          "      C   s  | j dkr"|dk	r"td| dt| } t| j}| j|dd} |dk	rtj|t	d}|dk	rtj
||d}t|| j}n|}| | }n| }| }| }t|rtd	t|st|rtd
| |8 } ||kr| ||  } |dk	}| j}d}|dk	}| j dkr*| tjdtjf } d}nF| j dkrP|rP| tjdf } d}n | j dkrp|sp| dtjf } |r|s|dkr| j| dkr|rtdn| j| dkrt| } |dkrtdd}|r8|d}|j dkrt|tjdf }|j| jdd kr"tdt|||\}}d}nt| |\}}|dkr`tjd|d}nt|trtj||d}|r|jdkr|jdkrtdtdd ntd|j dnt|dd}n|jdkrtd|j dtj||d}ntdt|r,tj |||g|d}|| }nt|trtj||d}|r|jdkr|jdkrttdtdd ntd|j dnt|dd}n|jdkrtd|j d|dk! rt"|dg }t#| |dd } |jd }tjtj$|t%|| jd fgd!d|d}t|}d"| }tj| | |d} |rXt&| ||||||
d|d#	 t&| ||||||
d|d#	}|r|r|' | }nt()| jdd | }t*|| } t*|	| }!t+|| |!|d$}|r|d }|S )%u  Segments image using k-means clustering in Color-(x,y,z) space.

    Parameters
    ----------
    image : 2D, 3D or 4D ndarray
        Input image, which can be 2D or 3D, and grayscale or multichannel
        (see `channel_axis` parameter).
        Input image must either be NaN-free or the NaN's must be masked out
    n_segments : int, optional
        The (approximate) number of labels in the segmented output image.
    compactness : float, optional
        Balances color proximity and space proximity. Higher values give
        more weight to space proximity, making superpixel shapes more
        square/cubic. In SLICO mode, this is the initial compactness.
        This parameter depends strongly on image contrast and on the
        shapes of objects in the image. We recommend exploring possible
        values on a log scale, e.g., 0.01, 0.1, 1, 10, 100, before
        refining around a chosen value.
    max_num_iter : int, optional
        Maximum number of iterations of k-means.
    sigma : float or array-like of floats, optional
        Width of Gaussian smoothing kernel for pre-processing for each
        dimension of the image. The same sigma is applied to each dimension in
        case of a scalar value. Zero means no smoothing.
        Note that `sigma` is automatically scaled if it is scalar and
        if a manual voxel spacing is provided (see Notes section). If
        sigma is array-like, its size must match ``image``'s number
        of spatial dimensions.
    spacing : array-like of floats, optional
        The voxel spacing along each spatial dimension. By default,
        `slic` assumes uniform spacing (same voxel resolution along
        each spatial dimension).
        This parameter controls the weights of the distances along the
        spatial dimensions during k-means clustering.
    convert2lab : bool, optional
        Whether the input should be converted to Lab colorspace prior to
        segmentation. The input image *must* be RGB. Highly recommended.
        This option defaults to ``True`` when ``channel_axis` is not None *and*
        ``image.shape[-1] == 3``.
    enforce_connectivity : bool, optional
        Whether the generated segments are connected or not
    min_size_factor : float, optional
        Proportion of the minimum segment size to be removed with respect
        to the supposed segment size ```depth*width*height/n_segments```
    max_size_factor : float, optional
        Proportion of the maximum connected segment size. A value of 3 works
        in most of the cases.
    slic_zero : bool, optional
        Run SLIC-zero, the zero-parameter mode of SLIC. [2]_
    start_label : int, optional
        The labels' index start. Should be 0 or 1.

        .. versionadded:: 0.17
           ``start_label`` was introduced in 0.17
    mask : ndarray, optional
        If provided, superpixels are computed only where mask is True,
        and seed points are homogeneously distributed over the mask
        using a k-means clustering strategy. Mask number of dimensions
        must be equal to image number of spatial dimensions.

        .. versionadded:: 0.17
           ``mask`` was introduced in 0.17
    channel_axis : int or None, optional
        If None, the image is assumed to be a grayscale (single channel) image.
        Otherwise, this parameter indicates which axis of the array corresponds
        to channels.

        .. versionadded:: 0.19
           ``channel_axis`` was added in 0.19.

    Returns
    -------
    labels : 2D or 3D array
        Integer mask indicating segment labels.

    Raises
    ------
    ValueError
        If ``convert2lab`` is set to ``True`` but the last array
        dimension is not of length 3.
    ValueError
        If ``start_label`` is not 0 or 1.
    ValueError
        If ``image`` contains unmasked NaN values.
    ValueError
        If ``image`` contains unmasked infinite values.
    ValueError
        If ``image`` is 2D but ``channel_axis`` is -1 (the default).

    Notes
    -----
    * If `sigma > 0`, the image is smoothed using a Gaussian kernel prior to
      segmentation.

    * If `sigma` is scalar and `spacing` is provided, the kernel width is
      divided along each dimension by the spacing. For example, if ``sigma=1``
      and ``spacing=[5, 1, 1]``, the effective `sigma` is ``[0.2, 1, 1]``. This
      ensures sensible smoothing for anisotropic images.

    * The image is rescaled to be in [0, 1] prior to processing (masked
      values are ignored).

    * Images of shape (M, N, 3) are interpreted as 2D RGB images by default. To
      interpret them as 3D with the last dimension having length 3, use
      `channel_axis=None`.

    * `start_label` is introduced to handle the issue [4]_. Label indexing
      starts at 1 by default.

    References
    ----------
    .. [1] Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi,
        Pascal Fua, and Sabine Süsstrunk, SLIC Superpixels Compared to
        State-of-the-art Superpixel Methods, TPAMI, May 2012.
        :DOI:`10.1109/TPAMI.2012.120`
    .. [2] https://www.epfl.ch/labs/ivrl/research/slic-superpixels/#SLICO
    .. [3] Irving, Benjamin. "maskSLIC: regional superpixel generation with
           application to local pathology characterisation in medical images.",
           2016, :arXiv:`1606.09518`
    .. [4] https://github.com/scikit-image/scikit-image/issues/3722

    Examples
    --------
    >>> from skimage.segmentation import slic
    >>> from skimage.data import astronaut
    >>> img = astronaut()
    >>> segments = slic(img, n_segments=100, compactness=10)

    Increasing the compactness parameter yields more square regions:

    >>> segments = slic(img, n_segments=100, compactness=20)

    r   Nzchannel_axis=z| indicates multichannel, which is not supported for a two-dimensional image; use channel_axis=None if the image is grayscaleT)copyr   r3   z.unmasked NaN values in image are not supportedz3unmasked infinite values in image are not supportedF.r2   z/Lab colorspace conversion requires a RGB image.)r   r   zstart_label should be 0 or 1.Zuint8z*image and mask should have the same shape.zdInput image is 2D: spacing number of elements must be 2. In the future, a ValueError will be raised.)
stacklevelz#Input image is 2D, but spacing has z elements (expected 2).r   r   z#Input image is 3D, but spacing has z elements (expected 3).z!spacing must be None or iterable.zbInput image is 2D: sigma number of elements must be 2. In the future, a ValueError will be raised.z!Input image is 2D, but sigma has z!Input image is 3D, but sigma has Zreflect)moder   r4   )Zignore_colorstart_label)rI   ),r"   
ValueErrorr   r	   Z_supported_float_typer   Zastyper   ZascontiguousarrayboolZexpand_dimsZbroadcast_tor9   r!   maxisnanisinfr:   r   viewr1   rA   Zones
isinstancer   r<   sizer   FutureWarninginsert	TypeErrorZisscalarr   anylistr
   r;   Zzerosr   summathprodr   r   )"r=   Z
n_segmentsZcompactnessZmax_num_itersigmaspacingZconvert2labZenforce_connectivityZmin_size_factorZmax_size_factorZ	slic_zerorI   r&   rE   Zfloat_dtypeZmask_Zimage_valuesZiminZimaxZuse_maskr   Zis_2dr(   Zupdate_centroidsr+   r.   r'   segmentsr5   ratiolabelsZsegment_sizeZmin_sizemax_sizer/   r/   r0   slico   s     






 
 
      r`   )rB   rC   r   r   NNTrD   r2   Fr   N)rX   collections.abcr   warningsr   numpyr   r   Zscipy.cluster.vqr   Zscipy.spatial.distancer   r   Z_sharedr	   Z_shared.filtersr
   colorr   utilr   r   Z_slicr   r   r1   rA   Zchannel_as_last_axisr`   r/   r/   r/   r0   <module>   s4   :$
              