
    1-Ph'                     h    d dl Zd dl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   )_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       X/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/skimage/graph/_graph_cut.py
<listcomp>z!cut_threshold.<locals>.<listcomp>5   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_edger/   r)   r'   nr   s              r   cut_normalizedr:   F   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(   r9   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_cutrE      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   wr7   mcutmnmxmin_masktmaskcosts              r   get_min_ncutrX      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)rI   r"   )r#   	attr_namer)   	new_labelr9   r   s         r   
_label_allr\      sd     syy{{D	$)!,I		t	$$ ! !1 )! !r   c           
      &   t          j        |           \  }}|j        d         }|dk    rU||k    j        dk    rE|                                }t          j        t          j        |j        |j                  |j                  |_        |||z
  z  |z  }|	                    |j        d                   }	t          j        |d|	t          d|dz
                      \  }
}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      )outSMd   )whichv0kNr1   )r   DW_matricesshapennzr   r   
reciprocalsqrtr   r2   r   eigshrI   realr   argmin2rX   rE   r5   r\   )r#   r   r7   random_generatorr   rP   md2Arc   valsvectorsindex2rO   cut_maskrQ   rC   rD   s                     r   r5   r5      s   ( S!!DAq	
A	AAF<!## VVXX -RW = = =27KKK !a%L2$$QWQZ00QdrSa!e__MMM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    r   r   r+   r:   rE   rX   r\   r5   r   r   r   <module>ry      s                         ; ; ; ;B M 	M M M M M`     F) ) )X! ! !$C" C" C" C" C"r   