
    8j(                     t    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Z	 	 	 	 ddddZd Zd Zd Zd ZdS )    N)linalg)SCIPY_GE_1_17_0_DEV0   )_ncut_ncut_cyTc                    |s|                                 }fd|                    d          D             }|                    |           t          j        |          }t          j        |                                 dz   | j                  }t          |          D ]%\  }}|D ]}	|j
        |	         d         D ]}
|||
<   &||          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                 8    g | ]\  }}}|d          k    ||fS weight ).0xydthreshs       [/var/www/html/Carbon-Document/venv/lib/python3.11/site-packages/skimage/graph/_graph_cut.py
<listcomp>z!cut_threshold.<locals>.<listcomp>6   s1    UUUGAq!q{f?T?T!Q?T?T?T    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labels     `        r   cut_thresholdr,   	   s    R  hhjj VUUUsyydy';';UUUI)$$$#C((E
 	&**,,*&,???Ie$$ % %5 	% 	%D42 % %#$	%  %	% Vr   MbP?
         ?)rngc                   t           j                            |          }|s|                                }|                                D ]}|                    |||           t          ||||           t          j        |                                 dz   | j	                  }|                    d          D ]\  }	}
|
d         ||
d         <   ||          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_edger0   r*   r(   nr   s              r   cut_normalizedr;   G   s    ~ )


$
$C hhjj		 2 2T41111#vx---)>>>I		t	$$ 1 11!"<	!H+Vr   c                      fdt          |                                          D             } f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                 *    g | ]\  }}|         |S r   r   r   r)   r:   cuts      r   r   z$partition_by_cut.<locals>.<listcomp>   s&    ===DAqc!f=a===r   c                 *    g | ]\  }}|         |S r   r   r>   s      r   r   z$partition_by_cut.<locals>.<listcomp>   s&    AAADAq#a&AaAAAr   )r"   r#   subgraph)r?   r$   nodes1nodes2sub1sub2s   `     r   partition_by_cutrF      s    4 >===Iciikk22===FAAAAIciikk22AAAF<<D<<D:r   c                 \   t           j        }|                                 }|                                 }t          j        | t
                    }t          j        ||          r||fS t          j        |||d          D ](}| |k    }	t          j	        |	||          }
|
|k     r|	}|
})||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costs              r   get_min_ncutrY      s    * 6D	B	B
 }Rt,,,H	{2r ~ [RE:::  AvtQ**$;;HDT>r   c                     t          |                                           }| j        |         d         d         }|                     d          D ]
\  }}|||<   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)rJ   r#   )r$   	attr_namer*   	new_labelr:   r   s         r   
_label_allr]      sd     syy{{D	$)!,I		t	$$ ! !1 )! !r   c           
      <   t          j        |           \  }}|j        d         }|dk    r`||k    j        dk    rP|                                }t          j        t          j        |j        |j                  |j                  |_        |||z
  z  |z  }|	                    |j        d                   }	t          rd|ini }
t          j        |fd|	t          d|dz
            d|
\  }}t          j        |          t          j        |          }}t          j        |          }|dd|f         }t#          ||||          \  }}||k     r9t%          ||           \  }}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      )outr0   SMd   )whichv0kNr2   )r   DW_matricesshapennzr   r   
reciprocalsqrtr   r3   r   r   eigshrJ   realr   argmin2rY   rF   r6   r]   )r$   r   r8   random_generatorr   rQ   md2Ard   rng_kwvalsvectorsindex2rP   cut_maskrR   rD   rE   s                      r   r6   r6      s   ( S!!DAq	
A	AAF<!## VVXX -RW = = =27KKK !a%L2$$QWQZ00 /CJ%)**QWdrSa!e__WWPVWWg rww'7'7g!$''QQQY%b!Q99$&== *(C88JD$$2BCCC$2BCCCF sL!!!!!r   )T)r-   r.   Tr/   )networkxr   numpyr   scipy.sparser   skimage._shared.compatr    r   r   r,   r;   rF   rY   r]   r6   r   r   r   <module>r|      s                  7 7 7 7 7 7        ; ; ; ;B M 	M M M M M`     F) ) )X! ! !$G" G" G" G" G"r   