o
    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 ]}
|||
< q<q3q-||  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
   S/var/www/html/scripts/venv/lib/python3.10/site-packages/skimage/graph/_graph_cut.py
<listcomp>6   s    z!cut_threshold.<locals>.<listcomp>Tdatar   dtypelabels)copyedgesremove_edges_fromnxconnected_componentsnparangemaxr   	enumeratenodes)r   ragr   in_place	to_removecomps	map_arrayir!   nodelabelr
   r   r   cut_threshold	   s   )


r*   random_staterngz0.21z0.23)deprecated_version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 < q4||  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   randomdefault_rngr   r!   add_edge_ncut_relabelzerosr   r   )r   r"   r   num_cutsr#   max_edger,   r(   r&   nr   r
   r
   r   cut_normalizedH   s   <r;   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          z$partition_by_cut.<locals>.<listcomp>c                    s   g | ]
\}} | s|qS r
   r
   r<   r=   r
   r   r      r?   )r    r!   subgraph)r>   r"   nodes1nodes2sub1sub2r
   r=   r   partition_by_cut   s
   

rE   c                 C   s~   t j}|  }|  }t j| td}t ||r||fS t j|||ddD ]}| |k}	t	|	||}
|
|k r:|	}|
}q%||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)endpoint)
r   infminr   
zeros_likeboolallcloselinspacer   	ncut_cost)evr   wr8   mcutmnmxmin_masktmaskcostr
   r
   r   get_min_ncut   s   rW   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)rH   r!   )r"   	attr_namer(   	new_labelr:   r   r
   r
   r   
_label_all   s
   
rZ   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 rt|| \}}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   )outSMd   )whichv0kNr2   )r   DW_matricesshaper   r   
reciprocalsqrtr   r3   r   eigshrH   realr   argmin2rW   rE   r6   rZ   )r"   r   r8   random_generatorr   rO   md2Ar_   valsvectorsindex2rN   cut_maskrP   rC   rD   r
   r
   r   r6      s(   
 


r6   )T)r/   r0   Tr1   )networkxr   numpyr   scipy.sparser   _shared.utilsr    r   r   r*   r;   rE   rW   rZ   r6   r
   r
   r
   r   <module>   s$    

?K#,