U
    ?h+&                     @   s   d dl Zd dlZd dlmZ ddlmZ ddlm	Z	m
Z
 ddd	Zed
diddddddddZdd Zdd Zdd Zdd ZdS )    N)linalg   )deprecate_kwarg   )_ncut_ncut_cyTc                    s   |s|  } fdd|jddD }|| t|}tj|  d | jd}t	|D ].\}}|D ] }	|j
|	 d D ]}
|||
< qxqfqZ||  S )a  Combine regions separated by weight less than threshold.

    Given an image's labels and its RAG, output new labels by
    combining regions whose nodes are separated by a weight less
    than the given threshold.

    Parameters
    ----------
    labels : ndarray
        The array of labels.
    rag : RAG
        The region adjacency graph.
    thresh : float
        The threshold. Regions connected by edges with smaller weights are
        combined.
    in_place : bool
        If set, modifies `rag` in place. The function will remove the edges
        with weights less that `thresh`. If set to `False` the function
        makes a copy of `rag` before proceeding.

    Returns
    -------
    out : ndarray
        The new labelled array.

    Examples
    --------
    >>> from skimage import data, segmentation, graph
    >>> img = data.astronaut()
    >>> labels = segmentation.slic(img)
    >>> rag = graph.rag_mean_color(img, labels)
    >>> new_labels = graph.cut_threshold(labels, rag, 10)

    References
    ----------
    .. [1] Alain Tremeau and Philippe Colantoni
           "Regions Adjacency Graph Applied To Color Image Segmentation"
           :DOI:`10.1109/83.841950`

    c                    s&   g | ]\}}}|d   kr||fqS weight ).0xydthreshr
   J/var/www/html/venv/lib/python3.8/site-packages/skimage/graph/_graph_cut.py
<listcomp>6   s    z!cut_threshold.<locals>.<listcomp>Tdatar   dtypelabels)copyedgesZremove_edges_fromnxZconnected_componentsnpZarangemaxr   	enumeratenodes)r   ragr   in_placeZ	to_removecomps	map_arrayir   nodelabelr
   r   r   cut_threshold	   s    )

r&   Zrandom_staterngz0.21z0.23)Zdeprecated_versionZremoved_versionMbP?
         ?)r'   c                C   s   t j|}|s| }| D ]}|j|||d q t|||| t j|  d | j	d}|jddD ]\}	}
|
d ||
d < qh||  S )a  Perform Normalized Graph cut on the Region Adjacency Graph.

    Given an image's labels and its similarity RAG, recursively perform
    a 2-way normalized cut on it. All nodes belonging to a subgraph
    that cannot be cut further are assigned a unique label in the
    output.

    Parameters
    ----------
    labels : ndarray
        The array of labels.
    rag : RAG
        The region adjacency graph.
    thresh : float
        The threshold. A subgraph won't be further subdivided if the
        value of the N-cut exceeds `thresh`.
    num_cuts : int
        The number or N-cuts to perform before determining the optimal one.
    in_place : bool
        If set, modifies `rag` in place. For each node `n` the function will
        set a new attribute ``rag.nodes[n]['ncut label']``.
    max_edge : float, optional
        The maximum possible value of an edge in the RAG. This corresponds to
        an edge between identical regions. This is used to put self
        edges in the RAG.
    rng : {`numpy.random.Generator`, int}, optional
        Pseudo-random number generator.
        By default, a PCG64 generator is used (see :func:`numpy.random.default_rng`).
        If `rng` is an int, it is used to seed the generator.

        The `rng` is used to determine the starting point
        of `scipy.sparse.linalg.eigsh`.

    Returns
    -------
    out : ndarray
        The new labeled array.

    Examples
    --------
    >>> from skimage import data, segmentation, graph
    >>> img = data.astronaut()
    >>> labels = segmentation.slic(img)
    >>> rag = graph.rag_mean_color(img, labels, mode='similarity')
    >>> new_labels = graph.cut_normalized(labels, rag)

    References
    ----------
    .. [1] Shi, J.; Malik, J., "Normalized cuts and image segmentation",
           Pattern Analysis and Machine Intelligence,
           IEEE Transactions on, vol. 22, no. 8, pp. 888-905, August 2000.

    r   r   r   Tr   
ncut labelr   )
r   randomZdefault_rngr   r   Zadd_edge_ncut_relabelZzerosr   r   )r   r   r   num_cutsr    Zmax_edger'   r$   r"   nr   r
   r
   r   cut_normalizedH   s    <r0   c                    sP    fddt | D } fddt | D }||}||}||fS )aR  Compute resulting subgraphs from given bi-partition.

    Parameters
    ----------
    cut : array
        A array of booleans. Elements set to `True` belong to one
        set.
    rag : RAG
        The Region Adjacency Graph.

    Returns
    -------
    sub1, sub2 : RAG
        The two resulting subgraphs from the bi-partition.
    c                    s   g | ]\}} | r|qS r
   r
   r   r#   r/   cutr
   r   r      s      z$partition_by_cut.<locals>.<listcomp>c                    s   g | ]\}} | s|qS r
   r
   r1   r2   r
   r   r      s      )r   r   Zsubgraph)r3   r   Znodes1Znodes2sub1sub2r
   r2   r   partition_by_cut   s
    

r6   c                 C   s~   t j}|  }|  }t j| td}t ||r8||fS t j|||ddD ]*}| |k}	t	|	||}
|
|k rJ|	}|
}qJ||fS )a  Threshold an eigenvector evenly, to determine minimum ncut.

    Parameters
    ----------
    ev : array
        The eigenvector to threshold.
    d : ndarray
        The diagonal matrix of the graph.
    w : ndarray
        The weight matrix of the graph.
    num_cuts : int
        The number of evenly spaced thresholds to check for.

    Returns
    -------
    mask : array
        The array of booleans which denotes the bi-partition.
    mcut : float
        The value of the minimum ncut.
    r   F)Zendpoint)
r   infminr   Z
zeros_likeboolZallcloseZlinspacer   Z	ncut_cost)evr   wr.   mcutZmnZmxZmin_masktmaskZcostr
   r
   r   get_min_ncut   s    r?   c                 C   s@   t |  }| j| d d }| jddD ]\}}|||< q*dS )aq  Assign a unique integer to the given attribute in the RAG.

    This function assumes that all labels in `rag` are unique. It
    picks up a random label from them and assigns it to the `attr_name`
    attribute of all the nodes.

    rag : RAG
        The Region Adjacency Graph.
    attr_name : string
        The attribute to which a unique integer is assigned.
    r   r   Tr   N)r8   r   )r   	attr_namer$   Z	new_labelr/   r   r
   r
   r   
_label_all   s    rA   c                 C   s  t | \}}|jd }|dkr| }tjtj|j|jd|jd|_|||  | }||jd }	t	j
|d|	td|d d\}
}t|
t| }
}t|
}|dd|f }t||||\}}||k rt|| \}}t|||| t|||| dS t| d dS )	a  Perform Normalized Graph cut on the Region Adjacency Graph.

    Recursively partition the graph into 2, until further subdivision
    yields a cut greater than `thresh` or such a cut cannot be computed.
    For such a subgraph, indices to labels of all its nodes map to a single
    unique value.

    Parameters
    ----------
    rag : RAG
        The region adjacency graph.
    thresh : float
        The threshold. A subgraph won't be further subdivided if the
        value of the N-cut exceeds `thresh`.
    num_cuts : int
        The number or N-cuts to perform before determining the optimal one.
    random_generator : `numpy.random.Generator`
        Provides initial values for eigenvalue solver.
    r   r   )outZSMd   )whichv0kNr+   )r   ZDW_matricesshaper   r   Z
reciprocalsqrtr   r,   r   Zeigshr8   realr   Zargmin2r?   r6   r-   rA   )r   r   r.   Zrandom_generatorr   r;   mZd2ArE   valsZvectorsindex2r:   Zcut_maskr<   r4   r5   r
   r
   r   r-      s(    

 



r-   )T)r(   r)   Tr*   )Znetworkxr   numpyr   Zscipy.sparser   Z_shared.utilsr    r   r   r&   r0   r6   r?   rA   r-   r
   r
   r
   r   <module>   s"   
?
  K#,