
    9i5                         S SK rS SKJr  SSKJr  S rSS jrSS jr	S r
S	 rS
 rS rS r\R                  4S jrS rS r\R                  4S jr        SS jrg)    N)distance_transform_edt   )_supported_float_typec                    Sn[         R                  " USSS9nUSS2SS24   USS2SS24   -
  nUSS2SS24   USS2SS24   -
  n	USS2SS24   USS2SS24   -
  S	-  n
USS2SS24   USS2SS24   -
  nUSS2SS24   USS2SS24   -
  nUSS2SS24   USS2SS24   -
  S	-  nS
[         R                  " XhS-  -   US-  -   5      -  nS
[         R                  " XiS-  -   US-  -   5      -  nS
[         R                  " XjS-  -   US-  -   5      -  nS
[         R                  " XjS-  -   US-  -   5      -  nUSS2SS24   U-  USS2SS24   U-  -   USS2SS24   U-  -   USS2SS24   U-  -   nUS:  R                  U R                  5      n[        U U5      u  nnU* U U-
  S-  -  X@U-
  S-  -  -   nX[        U5      -  UU-  U-   -  -   nUSX%-  [        U5      -  X-   U-   U-   -  -   -  $ )ac  Returns the variation of level set 'phi' based on algorithm parameters.

This corresponds to equation (22) of the paper by Pascal Getreuer,
which computes the next iteration of the level set based on a current
level set.

A full explanation regarding all the terms is beyond the scope of the
present description, but there is one difference of particular import.
In the original algorithm, convergence is accelerated, and required
memory is reduced, by using a single array. This array, therefore, is a
combination of non-updated and updated values. If this were to be
implemented in python, this would require a double loop, where the
benefits of having fewer iterations would be outweided by massively
increasing the time required to perform each individual iteration. A
similar approach is used by Rami Cohen, and it is from there that the
C1-4 notation is taken.
gؗҜ<   edgemoder   N       @      ?r   )nppadsqrtastypedtype_cv_calculate_averages	_cv_delta)imagephimulambda1lambda2dtetaPphixpphixnphix0phiypphiynphiy0C1C2C3C4KHphic1c2difference_from_average_termnew_phis                           _/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/skimage/segmentation/_chan_vese.py_cv_calculate_variationr/      s   $ C
sAF#AadABhK!AbD!B$J-'EadAbDjMAadCRCiL(EqtQRx[1QrT3B3Y<'3.Eab!B$hK!AbD!B$J-'EadAbDjMAcrc1R4iL(Eqr1R4x[1SbS!B$Y<'3.E	rwwsAX~q01	1B	rwwsAX~q01	1B	rwwsAX~q01	1B	rwwsAX~q01	1B	!B$(b1QrT3B3Y<",,qQrT{R/??!CRC2I,QSBSSA!GEKK(D%eT2HR 
EBJ1$$w"*1B'BB ! )C.(R!V6R-RSSGa"'IcN2bglR6GHHII    c                 f    SSS[         R                  -  [         R                  " X-  5      -  -   -  $ )zNReturns the result of a regularised heavyside function of the
input value(s).
      ?r   r   )r   piarctanxepss     r.   _cv_heavysider8   5   s,     #ruu		!'(:::;;r0   c                     XS-  U S-  -   -  $ )zJReturns the result of a regularised dirac function of the
input value(s).
r    r5   s     r.   r   r   <   s     q&1a4-  r0   c                     UnSU-
  n[         R                  " U5      n[         R                  " U5      n[         R                  " X-  5      n[         R                  " X-  5      nUS:w  a  Xd-  nUS:w  a  Xu-  nXg4$ )z2Returns the average values 'inside' and 'outside'.r   r   )r   sum)r   r)   HHinvHsumHinvsum
avg_insideavg_oustides           r.   r   r   C   sq    A7D66!9DffTlG	"J&&&Kqy
!|$$r0   c                 \    [        X5      u  pESU-
  nX U-
  S-  -  U-  X0U-
  S-  -  U-  -   $ )znReturns the 'energy' contribution due to the difference from
the average value within a region at each point.
r   r   )r   )r   r)   
lambda_pos
lambda_negr*   r+   r>   s          r.    _cv_difference_from_average_termrF   R   sH     &e2HR:D))D0:PQ@Q3QTX3XXXr0   c                     [         R                  " U SSS9nUSS2SS24   USS2SS24   -
  S-  nUSS2SS24   USS2SS24   -
  S-  nU[        U 5      -  [         R                  " US-  US-  -   5      -  $ )	z|Returns the 'energy' contribution due to the length of the
edge between regions at each point, multiplied by a factor 'mu'.
r   r   r	   r   Nr   r   r   )r   r   r   r   )r   r   r   fyfxs        r.   _cv_edge_length_termrJ   [   s     	sAF#A
AB"H+#2#qt)
$	+B
AbD!"H+!B$)
$	+B	#QQ!777r0   c                     [        U5      n[        XX45      n[        X5      n[        R                  " U5      [        R                  " U5      -   $ )a+  Returns the total 'energy' of the current level set function.

This corresponds to equation (7) of the paper by Pascal Getreuer,
which is the weighted sum of the following:
(A) the length of the contour produced by the zero values of the
level set,
(B) the area of the "foreground" (area of the image where the
level set is positive),
(C) the variance of the image inside the foreground,
(D) the variance of the image outside of the foreground

Each value is computed for each pixel, and then summed. The weight
of (B) is set to 0 in this implementation.
)r8   rF   rJ   r   r<   )r   r   r   r   r   r=   	avgenergy	lenenergys           r.   
_cv_energyrN   e   sA     	cA07LI$S-I66)rvvi000r0   c                     U $ )zThis is a placeholder function as resetting the level set is not
strictly necessary, and has not been done for this implementation.
r:   )r   s    r.   _cv_reset_level_setrP   z   s	     Jr0   c                    [         R                  " U S   US9R                  U S   S5      n[         R                  " U S   US9n[         R                  U-  nXE-  nX5-  n[         R                  " U5      [         R                  " U5      -  $ )z|Generates a checkerboard level set function.

According to Pascal Getreuer, such a level set function has fast
convergence.
r   r   r   )r   arangereshaper3   sin)
image_sizesquare_sizer   yvxvsfs         r.   _cv_checkerboardr[      st     
:a=	.	6	6z!}a	HB	:a=	.B		BHBHB66":r
""r0   c                     [         R                  " U 5      n[        U S   S-
  S-  5      n[        U S   S-
  S-  5      nSXU4'   [        [	        X25      5      nU[        U5      -
  U-  $ )zdGenerates a disk level set function.

The disk covers the whole image along its smallest dimension.
r   r   r           r   onesintfloatmindistancerV   rescenterYcenterXradiuss        r.   _cv_large_diskri      sr    
 ''*
C:a=1$)*G:a=1$)*GC3w()FXc]"f,,r0   c                     [         R                  " U 5      n[        U S   S-
  S-  5      n[        U S   S-
  S-  5      nSXU4'   [        [	        X25      5      S-  nU[        U5      -
  US-  -  $ )zfGenerates a disk level set function.

The disk covers half of the image along its smallest dimension.
r   r   r   r]   r      r^   rd   s        r.   _cv_small_diskrl      s{    
 ''*
C:a=1$)*G:a=1$)*GC3w()C/FXc]"vz22r0   c                     [        U [        5      (       aC  U S:X  a  [        USU5      nO1U S:X  a  [        U5      nOU S:X  a  [	        U5      nO[        S5      eU nUR                  USS9$ )zGGenerates an initial level set function conditional on input arguments.checkerboard   diskz
small diskz-Incorrect name for starting level set preset.Fcopy)
isinstancestrr[   ri   rl   
ValueErrorr   )init_level_setimage_shaper   re   s       r.   _cv_init_level_setrx      sm    .#&&^+";59Cv% -C|+ -CLMM::e%:((r0   c	                 0   [        U R                  5      S:w  a  [        S5      e[        U R                  5      n	[        XpR                  U	S9n
[        U
5      [        R                  :w  d  U
R                  U R                  :w  a  [        S5      eU R                  U	SS9n U [        R                  " U 5      -
  n [        R                  " U 5      S:w  a  U [        R                  " U 5      -  n Sn[        X
XU5      n/ nUS-   nU
S:  nX:  a  X:  az  U
n[        X
XX65      n
[        U
5      n
[        R                  " U
U-
  S-  R!                  5       5      nU
S:  n[        X
XU5      nUR#                  U5        UnUS-  nX:  a  X:  a  Mz  U(       a  XU4$ U$ )	aH  Chan-Vese segmentation algorithm.

Active contour model by evolving a level set. Can be used to
segment objects without clearly defined boundaries.

Parameters
----------
image : (M, N) ndarray
    Grayscale image to be segmented.
mu : float, optional
    'edge length' weight parameter. Higher `mu` values will
    produce a 'round' edge, while values closer to zero will
    detect smaller objects.
lambda1 : float, optional
    'difference from average' weight parameter for the output
    region with value 'True'. If it is lower than `lambda2`, this
    region will have a larger range of values than the other.
lambda2 : float, optional
    'difference from average' weight parameter for the output
    region with value 'False'. If it is lower than `lambda1`, this
    region will have a larger range of values than the other.
tol : float, positive, optional
    Level set variation tolerance between iterations. If the
    L2 norm difference between the level sets of successive
    iterations normalized by the area of the image is below this
    value, the algorithm will assume that the solution was
    reached.
max_num_iter : uint, optional
    Maximum number of iterations allowed before the algorithm
    interrupts itself.
dt : float, optional
    A multiplication factor applied at calculations for each step,
    serves to accelerate the algorithm. While higher values may
    speed up the algorithm, they may also lead to convergence
    problems.
init_level_set : str or (M, N) ndarray, optional
    Defines the starting level set used by the algorithm.
    If a string is inputted, a level set that matches the image
    size will automatically be generated. Alternatively, it is
    possible to define a custom level set, which should be an
    array of float values, with the same shape as 'image'.
    Accepted string values are as follows.

    'checkerboard'
        the starting level set is defined as
        sin(x/5*pi)*sin(y/5*pi), where x and y are pixel
        coordinates. This level set has fast convergence, but may
        fail to detect implicit edges.
    'disk'
        the starting level set is defined as the opposite
        of the distance from the center of the image minus half of
        the minimum value between image width and image height.
        This is somewhat slower, but is more likely to properly
        detect implicit edges.
    'small disk'
        the starting level set is defined as the
        opposite of the distance from the center of the image
        minus a quarter of the minimum value between image width
        and image height.
extended_output : bool, optional
    If set to True, the return value will be a tuple containing
    the three return values (see below). If set to False which
    is the default value, only the 'segmentation' array will be
    returned.

Returns
-------
segmentation : (M, N) ndarray, bool
    Segmentation produced by the algorithm.
phi : (M, N) ndarray of floats
    Final level set computed by the algorithm.
energies : list of floats
    Shows the evolution of the 'energy' for each step of the
    algorithm. This should allow to check whether the algorithm
    converged.

Notes
-----
The Chan-Vese Algorithm is designed to segment objects without
clearly defined boundaries. This algorithm is based on level sets
that are evolved iteratively to minimize an energy, which is
defined by weighted values corresponding to the sum of differences
intensity from the average value outside the segmented region, the
sum of differences from the average value inside the segmented
region, and a term which is dependent on the length of the
boundary of the segmented region.

This algorithm was first proposed by Tony Chan and Luminita Vese,
in a publication entitled "An Active Contour Model Without Edges"
[1]_.

This implementation of the algorithm is somewhat simplified in the
sense that the area factor 'nu' described in the original paper is
not implemented, and is only suitable for grayscale images.

Typical values for `lambda1` and `lambda2` are 1. If the
'background' is very different from the segmented object in terms
of distribution (for example, a uniform black image with figures
of varying intensity), then these values should be different from
each other.

Typical values for mu are between 0 and 1, though higher values
can be used when dealing with shapes with very ill-defined
contours.

The 'energy' which this algorithm tries to minimize is defined
as the sum of the differences from the average within the region
squared and weighed by the 'lambda' factors to which is added the
length of the contour multiplied by the 'mu' factor.

Supports 2D grayscale images only, and does not implement the area
term described in the original article.

References
----------
.. [1] An Active Contour Model without Edges, Tony Chan and
       Luminita Vese, Scale-Space Theories in Computer Vision,
       1999, :DOI:`10.1007/3-540-48236-9_13`
.. [2] Chan-Vese Segmentation, Pascal Getreuer Image Processing On
       Line, 2 (2012), pp. 214-224,
       :DOI:`10.5201/ipol.2012.g-cv`
.. [3] The Chan-Vese Algorithm - Project Report, Rami Cohen, 2011
       :arXiv:`1107.2782`
r   z!Input image should be a 2D array.rR   zIThe dimensions of initial level set do not match the dimensions of image.Frq   r   r   )lenshaperu   r   r   rx   typer   ndarrayr   rb   maxrN   r/   rP   r   meanappend)r   r   r   r   tolmax_num_iterr   rv   extended_outputfloat_dtyper   i
old_energyenergiesphivarsegmentationoldphi
new_energys                     r.   	chan_veser      s   N 5;;1<=='4K
^[[
LCCyBJJ#))u{{":-
 	

 LL5L1EBFF5M!E	vve}u%	AEW=JH1WF7L
,1+ &e"wK!#&3<A-3356 QwBA
 	
#
	Q# ,1+& 8,,r0   )r   )g      ?r   r   gMbP?i  r2   rn   F)numpyr   scipy.ndimager   rc   _shared.utilsr   r/   r8   r   r   rF   rJ   rN   rP   float64r[   ri   rl   rx   r   r:   r0   r.   <module>r      s     < 1+J\<!%Y81* 57JJ #
-
3 ;=** )$ 
!tr0   