
    voin                        S SK r S SKrS SKJrJrJr  S SKJrJr  S SK	r
S SKJr  S SKJrJr  SSKJrJrJrJrJr  \
R,                  " S5      rS	 rS
 r\ " S S\5      5       rSrSr " S S5      r " S S5      rS S jrS r S r!\  " S S\5      5       r"\  " S S\5      5       r#\  " S S\5      5       r$S r%S r&SSS\
RN                  S SSS4S jr(g)!    N)Protocolruntime_checkableSelf)warncatch_warnings)inv)optimizespatial   )_deprecate_estimateFailedEstimationdeprecate_parameterdeprecate_func
DEPRECATED   c                 h    U R                   S:w  d  U R                  S   U:w  a  [        SU S35      eg )Nr   r   zInput data must have shape (N, z).ndimshape
ValueError)datadims     O/var/www/html/land-ocr/venv/lib/python3.13/site-packages/skimage/measure/fit.py_check_data_dimr      s6    yyA~A#-:3%rBCC .    c                 `    U R                   S:  d  U R                  S   S:  a  [        S5      eg )Nr   r   zInput data must be at least 2D.r   )r   s    r   _check_data_atleast_2Dr      s-    yy1}

1):;; *r   c                   .    \ rS rSrSr\S 5       rS rSrg)RansacModelProtocol   z"Protocol for `ransac` model class.c                     g N )clsr   s     r   from_estimate!RansacModelProtocol.from_estimate#   s    #&r   c                     g r"   r#   selfr   s     r   	residualsRansacModelProtocol.residuals&   s    r   r#   N)	__name__
__module____qualname____firstlineno____doc__classmethodr%   r*   __static_attributes__r#   r   r   r   r      s    ,& &#r   r   z0.26z2.2c                       \ rS rSrS rSrg)	BaseModel-   c                 >    [        S[         S[         3[        SS9  g )Nz%`BaseModel` deprecated since version   and will be removed in version r   category
stacklevel)r   _PARAMS_DEP_START_PARAMS_DEP_STOPFutureWarningr)   s    r   __init_subclass__BaseModel.__init_subclass__.   s*    34E3F G**:);="		
r   r#   N)r,   r-   r.   r/   r?   r2   r#   r   r   r4   r4   -   s    
r   r4   c                   <    \ rS rSrSr\S\\-  4S j5       rS r	Sr
g)
_BaseModel7   a  Implement common methods for model classes.

This class can be removed when we expire deprecations of ``estimate``
method, and `params` arguments to ``predict*`` methods.

Note that each inheriting class will need to implement
``_params2init_values``, that breaks up the ``params`` vector into separate
components comprising the arguments to the function ``__init__``, and
checks the resulting input arguments for validity.
returnc                     [        SS9   U " 5       nS S S 5        WR                  USS9nUc  U$ [        U R                   SU 35      $ ! , (       d  f       N== f)Nignore)actionF	warn_onlyz: )r   	_estimater   r,   )r$   r   tfmsgs       r   r%   _BaseModel.from_estimateC   sW     8,B -ll45l1[rP&6#,,r#7O&PP -,s   A		
Ac           	         Ub	  U[         L ai  [        X R                  S   5      c*  [        U 5      R                  n[        SU SU SU S35      eU R                   Vs/ s H  n[        X5      PM     sn$ U R                  U5      $ s  snf )Nr   zM`params` argument must be specified when applied to model initialized with ``z()``; Consider creating new z. with suitable input arguments, or by using ``z.from_estimate``.)r   getattr
_init_argstyper,   r   _params2init_values)r)   paramscls_nameas       r   _get_init_values_BaseModel._get_init_valuesR   s    >Vz1t__Q/08  :.. !
">j !%%-J.?	A  /3oo>oGD$o>>''// ?s   Br#   N)r,   r-   r.   r/   r0   r1   r   r   r%   rV   r2   r#   r   r   rB   rB   7   s0    	 QD+;$; Q Q0r   rB   c                 4    U(       d  U $ [        U [        SS9  g)a  If `warn_only`, warn with `msg`, return ``None``, else return `msg`

For `from_estimate` API, we want to return a ``FailedEstimation`` for these
estimation failures, which we do by setting ``warn_only=False``, and
passing back the `msg` from the ``_estimation`` method via this function.
For the deprecated ``estimate`` API, we want to warn (``warn_only=True``),
and return an incomplete transform.  The ``None`` return value indicates
the estimation has kind-of succeeded, for back compatibility.
   r8   N)r   RuntimeWarning)rL   rI   s     r   _warn_or_msgr[   d   s     
~!4r   c                    ^  [         R                  " T R                  5      nUR                   Vs/ s H  o"S:w  d  M
  UPM     snT l        U 4S jnXl        UT l        T $ s  snf )a  Class decorator to allow, deprecate no input arguments to ``__init__``.

Makes a new ``__init__`` method, that a) will allow option of passing no
arguments, and b) when used thus, raises a deprecation warning.  Otherwise
defers to an assumed-existing ``_args_init`` instance method to deal with
input arguments.  If there are no parameters, set desired parameters to
None, to signal uninitialized object.

At the end of deprecation we can drop this decorator, and rename
``_args_init`` to ``__init__``.
r)   c                   > [        U5      (       d  [        U5      (       a  U R                  " U0 UD6  g [        STR                   S[         S[
         STR                   S3	[        SS9  TR                   H  n[        XS 5        M     g )Nz
Calling ``z;()`` (without arguments) has been deprecated since version r7   z; see help for ``z``.r   r8   )	len
_args_initr   r,   r;   r<   r=   rP   setattr)r)   argskwargskr$   s       r   init _deprecate_no_args.<locals>.init   s    t99FOOT,V, '((9': ;""2!3 4c# #	
 ADT"  r   )inspect	signaturer_   
parametersrP   __signature____init__)r$   args_init_sigrc   rd   s   `   r   _deprecate_no_argsrl   t   sZ     %%cnn5M!.!9!9I!9A&[a!9ICN#  'CLJ) Js
   	A A c                     [        S[        [        SS9" U 5      n U R                  R	                  S[        5      U l        U $ )z5Deprecate `params` argument of various model methods.rS   F)start_versionstop_versionmodify_docstringz{{ start_version }})r   r;   r<   r0   replace)funcs    r   _deprecate_model_paramsrs      sC    '%	
 D <<''(=?PQDLKr   c                      ^  \ rS rSrSrS rS rS r\\	" \
\SS9S 5       5       r\U 4S	 j5       rSS
 jr\\4S j5       r\S\4S j5       r\\4S j5       r\\4S j5       r\S 5       rSrU =r$ )LineModelND   a  Total least squares estimator for N-dimensional lines.

In contrast to ordinary least squares line estimation, this estimator
minimizes the orthogonal distances of points to the estimated line.

Lines are defined by a point (origin) and a unit vector (direction)
according to the following vector equation::

    X = origin + lambda * direction

Parameters
----------
origin : array-like, shape (N,)
    Coordinates of line origin in N dimensions.
direction : array-like, shape (N,)
    Vector giving line direction.

Raises
------
ValueError
    If length of `origin` and `direction` differ.

Examples
--------
>>> x = np.linspace(1, 2, 25)
>>> y = 1.5 * x + 3
>>> lm = LineModelND.from_estimate(np.stack([x, y], axis=-1))
>>> lm.origin
array([1.5 , 5.25])
>>> lm.direction  # doctest: +FLOAT_CMP
array([0.5547 , 0.83205])
>>> res = lm.residuals(np.stack([x, y], axis=-1))
>>> np.abs(np.round(res, 9))
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0.])
>>> np.round(lm.predict_y(x[:5]), 3)
array([4.5  , 4.562, 4.625, 4.688, 4.75 ])
>>> np.round(lm.predict_x(y[:5]), 3)
array([1.   , 1.042, 1.083, 1.125, 1.167])

c                 @    U R                  X5      u  U l        U l        g)zInitialize ``LineModelND`` instance.

Parameters
----------
origin : array-like, shape (N,)
    Coordinates of line origin in N dimensions.
direction : array-like, shape (N,)
    Vector giving line direction.
N)_check_init_valuesorigin	directionr)   ry   rz   s      r   r_   LineModelND._args_init   s     '+&=&=f&P#T^r   c                 f    S X4 5       u  p[        U5      [        U5      :w  a  [        S5      eX4$ )Nc              3   N   #    U  H  n[         R                  " U5      v   M     g 7fr"   )nparray).0vs     r   	<genexpr>1LineModelND._check_init_values.<locals>.<genexpr>   s     F2EQRXXa[[2Es   #%z7Direction vector should be same length as origin point.)r^   r   r{   s      r   rx   LineModelND._check_init_values   s7    F62EFv;#i.(VWW  r   c                 T    [        U5      S:w  a  [        S5      eU R                  " U6 $ )Nr   z!Input `params` should be length 2)r^   r   rx   r)   rS   s     r   rR   LineModelND._params2init_values   s+    v;!@AA&&//r   zK`params` attribute deprecated; use ``origin, direction`` attributes insteaddeprecated_versionremoved_versionhintc                 2    U R                   U R                  4$ )z7Return model attributes as ``origin, direction`` tuple.)ry   rz   r>   s    r   rS   LineModelND.params   s     {{DNN**r   c                 "   > [         TU ]  U5      $ )a  Estimate line model from data.

This minimizes the sum of shortest (orthogonal) distances
from the given data points to the estimated line.

Parameters
----------
data : (N, dim) array
    N points in a space of dimensionality dim >= 2.

Returns
-------
model : Self or `~.FailedEstimation`
    An instance of the line model if the estimation succeeded.
    Otherwise, we return a special ``FailedEstimation`` object to
    signal a failed estimation. Testing the truth value of the failed
    estimation object will return ``False``. E.g.

    .. code-block:: python

        model = LineModelND.from_estimate(...)
        if not model:
            raise RuntimeError(f"Failed estimation: {model}")
superr%   r$   r   	__class__s     r   r%   LineModelND.from_estimate   s    4 w$T**r   c                 ^   [        U5        UR                  SS9nX-
  nUR                  S   S:X  a5  US   US   -
  n[        R                  R                  U5      nUS:w  a  XE-  nO;UR                  S   S:  a'  [        R                  R                  USS9u    pgUS   nOgX0l        X@l        g )Nr   axisr   r   F)full_matriceszestimate under-determined)	r   meanr   r   linalgnormsvdry   rz   )r)   r   rI   ry   rz   r   _r   s           r   rJ   LineModelND._estimate  s    t$"}::a=AQ$q')I99>>),Dqy!	ZZ]QiimmDm>GAq!I."r   c                 F   [        U5        U R                  U5      u  p4[        U5      UR                  S   :w  a(  [	        S[        U5       SUR                  S    S35      eX-
  X-
  U-  S[
        R                  4   U-  -
  n[
        R                  R                  USS9$ )a  Determine residuals of data to model.

For each point, the shortest (orthogonal) distance to the line is
returned. It is obtained by projecting the data onto the line.

Parameters
----------
data : (N, dim) array
    N points in a space of dimension dim.

Returns
-------
residuals : (N,) array
    Residual for each data point.

Other parameters
----------------
params : `~.DEPRECATED`, optional
    Optional custom parameter set in the form (`origin`, `direction`).

    .. deprecated:: {{ start_version }}
r   z`origin` is zD, but `data` is D.r   )	r   rV   r^   r   r   r   newaxisr   r   )r)   r   rS   ry   rz   ress         r   r*   LineModelND.residuals$  s    0 	t$ 11&9v;$**Q-'s6{m+<TZZ]O1M  }$-9!<O!
!  yy~~c~**r   r   c                     U R                  U5      u  pEXR   S:X  a  [        SU 35      eXU   -
  XR   -  nXFS[        R                  4   U-  -   nU$ )a  Predict intersection of line model with orthogonal hyperplane.

Parameters
----------
x : (n, 1) array
    Coordinates along an axis.
axis : int
    Axis orthogonal to the hyperplane intersecting the line.

Returns
-------
data : (n, m) array
    Predicted coordinates.

Other parameters
----------------
params : `~.DEPRECATED`, optional
    Optional custom parameter set in the form (`origin`, `direction`).

    .. deprecated:: {{ start_version }}

Raises
------
ValueError
    If the line is parallel to the given axis.
r   zLine parallel to axis .)rV   r   r   r   )r)   xr   rS   ry   rz   lr   s           r   predictLineModelND.predictG  sf    8 !11&9?a5dV<==0#rzz/*Y66r   c                     Ub	  U[         L a  U O[        U 5      " U R                  U5      6 nUR                  USS9SS2S4   nU$ )a  Predict x-coordinates for 2D lines using the estimated model.

Alias for::

    predict(y, axis=1)[:, 0]

Parameters
----------
y : array
    y-coordinates.

Returns
-------
x : array
    Predicted x-coordinates.

Other parameters
----------------
params : `~.DEPRECATED`, optional
    Optional custom parameter set in the form (`origin`, `direction`).

    .. deprecated:: {{ start_version }}

Nr   r   r   r   rQ   rR   r   )r)   yrS   rK   r   s        r   	predict_xLineModelND.predict_xl  S    : &J"6 dT55f=> 	
 JJqqJ!!Q$'r   c                     Ub	  U[         L a  U O[        U 5      " U R                  U5      6 nUR                  USS9SS2S4   nU$ )a  Predict y-coordinates for 2D lines using the estimated model.

Alias for::

    predict(x, axis=0)[:, 1]

Parameters
----------
x : array
    x-coordinates.

Returns
-------
y : array
    Predicted y-coordinates.

Other parameters
----------------
params : `~.DEPRECATED`, optional
    Optional custom parameter set in the form (`origin`, `direction`).

    .. deprecated:: {{ start_version }}

Nr   r   r   r   )r)   r   rS   rK   r   s        r   	predict_yLineModelND.predict_y  r   r   c                 (    U R                  U5      SL $ )a9  Estimate line model from data.

This minimizes the sum of shortest (orthogonal) distances
from the given data points to the estimated line.

Parameters
----------
data : (N, dim) array
    N points in a space of dimensionality ``dim >= 2``.

Returns
-------
success : bool
    True, if model estimation succeeds.
NrJ   r(   s     r   estimateLineModelND.estimate  s    " ~~d#t++r   )rz   ry   T)r,   r-   r.   r/   r0   r_   rx   rR   propertyr   r;   r<   rS   r1   r%   rJ   rs   r   r*   r   r   r   r   r   r2   __classcell__r   s   @r   ru   ru      s    (T
Q!0
 ,(Z
+ + + +6, %/  +  +D 
 " "H ",    D ",    D , ,r   ru   c                      ^  \ rS rSrSrS rS rS r\\	" \
\SS9S 5       5       r\U 4S	 j5       rSS
 jrS r\\4S j5       r\S 5       rSrU =r$ )CircleModeli  u5  Total least squares estimator for 2D circles.

The functional model of the circle is::

    r**2 = (x - xc)**2 + (y - yc)**2

This estimator minimizes the squared distances from all points to the
circle::

    min{ sum((r - sqrt((x_i - xc)**2 + (y_i - yc)**2))**2) }

A minimum number of 3 points is required to solve for the parameters.

Parameters
----------
center : array-like, shape (2,)
    Coordinates of circle center.
radius : float
    Circle radius.

Notes
-----
The estimation is carried out using a 2D version of the spherical
estimation given in [1]_.

References
----------
.. [1] Jekel, Charles F. Obtaining non-linear orthotropic material models
       for pvc-coated polyester via inverse bubble inflation.
       Thesis (MEng), Stellenbosch University, 2016. Appendix A, pp. 83-87.
       https://hdl.handle.net/10019.1/98627

Raises
------
ValueError
    If `center` does not have length 2.

Examples
--------
>>> t = np.linspace(0, 2 * np.pi, 25)
>>> xy = CircleModel((2, 3), 4).predict_xy(t)
>>> model = CircleModel.from_estimate(xy)
>>> model.center
array([2., 3.])
>>> model.radius
4.0
>>> res = model.residuals(xy)
>>> np.abs(np.round(res, 9))
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0.])

The estimation can fail when — for example — all the input or output
points are the same.  If this happens, you will get a transform that is not
"truthy" - meaning that ``bool(tform)`` is ``False``:

>>> # A successfully estimated model is truthy:
>>> if model:
...     print("Estimation succeeded.")
Estimation succeeded.
>>> # Not so for a degenerate model with identical points.
>>> bad_data = np.ones((4, 2))
>>> bad_model = CircleModel.from_estimate(bad_data)
>>> if not bad_model:
...     print("Estimation failed.")
Estimation failed.

Trying to use this failed estimation transform result will give a suitable
error:

>>> bad_model.residuals(xy)  # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
  ...
FailedEstimationAccessError: No attribute "residuals" for failed estimation ...
c                 @    U R                  X5      u  U l        U l        g)zInitialize CircleModel instance.

Parameters
----------
center : array-like, shape (2,)
    Coordinates of circle center.
radius : float
    Circle radius.
N)rx   centerradiusr)   r   r   s      r   r_   CircleModel._args_init  s     $(#:#:6#J T[r   c                 h    [         R                  " U5      n[        U5      S:X  d  [        S5      eX4$ )Nr   %Center coordinates should be length 2r   r   r^   r   r   s      r   rx   CircleModel._check_init_values  s0    &!6{aDEE~r   c                     [         R                  " U5      n[        U5      S:w  a  [        S5      eU R	                  US S US   5      $ )N   z!Input `params` should be length 3r   r   r   r^   r   rx   r   s     r   rR   CircleModel._params2init_values%  sE    &!v;!@AA&&vbqz6!9==r   zF`params` attribute deprecated; use `center, radius` attributes insteadr   c                 T    [         R                  U R                  U R                  4   $ )z7Return model attributes ``center, radius`` as 1D array.)r   r_r   r   r>   s    r   rS   CircleModel.params+  s      uuT[[$++-..r   c                 "   > [         TU ]  U5      $ )ao  Estimate circle model from data using total least squares.

Parameters
----------
data : (N, 2) array
    N points with ``(x, y)`` coordinates, respectively.

Returns
-------
model : Self or `~.FailedEstimation`
    An instance of the circle model if the estimation succeeded.
    Otherwise, we return a special ``FailedEstimation`` object to
    signal a failed estimation. Testing the truth value of the failed
    estimation object will return ``False``. E.g.

    .. code-block:: python

        model = CircleModel.from_estimate(...)
        if not model:
            raise RuntimeError(f"Failed estimation: {model}")
r   r   s     r   r%   CircleModel.from_estimate5  s    . w$T**r   c                    [        USS9  [        R                  " UR                  [        R                  5      nUR                  USS9nUR                  SS9nX-
  nUR                  5       nU[        R                  " U5      R                  :  a
  [        SUS9$ X-  n[        R                  " US-  [        R                  " UR                  S   S	4US
9S	S9n[        R                  " US-  S	S9n[        R                  R!                  XgS S9u  ppU
S:w  a
  [        SUS9$ USS n["        R$                  " X5      n[        R&                  " [        R                  " US-  5      5      nX-  U-   U l        X-  U l        g )Nr   r   Fcopyr   r   zUStandard deviation of data is too small to estimate circle with meaningful precision.rH   r   dtype)rcondr   z6Input does not contain enough significant data points.)r   r   promote_typesr   float32astyper   stdfinfotinyr[   appendonesr   sumr   lstsqr
   minkowski_distancesqrtr   r   )r)   r   rI   
float_typery   scaleAfCr   rankr   	distancesrs                 r   rJ   CircleModel._estimateN  s`   !$ %%djj"**=
{{:E{2 "}
288J',,,4#  	
 IIdQhA(:* MTUVFF47#		D9d19H# 
 1Q..v<	GGBGGIqL)* nv-ir   c                     [        USS9  U R                  u  p#U R                  nUSS2S4   nUSS2S4   nU[        R                  " XR-
  S-  Xc-
  S-  -   5      -
  $ )a  Determine residuals of data to model.

For each point the shortest distance to the circle is returned.

Parameters
----------
data : (N, 2) array
    N points with ``(x, y)`` coordinates, respectively.

Returns
-------
residuals : (N,) array
    Residual for each data point.

r   r   Nr   r   )r   r   r   r   r   )r)   r   xcycr   r   r   s          r   r*   CircleModel.residualsx  sa    " 	!$KKAJAJ277AFq=AFq=8999r   c                    [         R                  " U5      nU R                  U5      u  u  p4nX5[         R                  " U5      -  -   nXE[         R                  " U5      -  -   n[         R
                  " US   US   4UR                  S9$ )a  Predict x- and y-coordinates using the estimated model.

Parameters
----------
t : array-like
    Angles in circle in radians. Angles start to count from positive
    x-axis to positive y-axis in a right-handed system.

Returns
-------
xy : (..., 2) array
    Predicted x- and y-coordinates.

Other parameters
----------------
params : `~.DEPRECATED`, optional
    Optional parameters ``xc``, ``yc``, `radius`.

    .. deprecated:: {{ start_version }}
.Nr   )r   
asanyarrayrV   cossinconcatenater   )r)   trS   r   r   r   r   r   s           r   
predict_xyCircleModel.predict_xy  sr    , MM!++F3!RVVAYRVVAY~~q|Qy\:HHr   c                 (    U R                  U5      SL $ )zEstimate circle model from data using total least squares.

Parameters
----------
data : (N, 2) array
    N points with ``(x, y)`` coordinates, respectively.

Returns
-------
success : bool
    True, if model estimation succeeds.

Nr   r(   s     r   r   CircleModel.estimate  s     ~~d#t++r   )r   r   r   r,   r-   r.   r/   r0   r_   rx   rR   r   r   r;   r<   rS   r1   r%   rJ   r*   rs   r   r   r   r   r2   r   r   s   @r   r   r     s    IV
K> ,(U
/ / + +0(T:6 #- I I: , ,r   r   c                      ^  \ rS rSrSrS rS rS r\\	" \
\SS9S 5       5       r\U 4S	 j5       rSS
 jrS r\\4S j5       r\S 5       rSrU =r$ )EllipseModeli  uR  Total least squares estimator for 2D ellipses.

The functional model of the ellipse is::

    xt = xc + a*cos(theta)*cos(t) - b*sin(theta)*sin(t)
    yt = yc + a*sin(theta)*cos(t) + b*cos(theta)*sin(t)
    d = sqrt((x - xt)**2 + (y - yt)**2)

where ``(xt, yt)`` is the closest point on the ellipse to ``(x, y)``. Thus
d is the shortest distance from the point to the ellipse.

The estimator is based on a least squares minimization. The optimal
solution is computed directly, no iterations are required. This leads
to a simple, stable and robust fitting method.

Parameters
----------
center : array-like, shape (2,)
    Coordinates of ellipse center.
axis_lengths : array-like, shape (2,)
    Length of first axis and length of second axis.  Call these ``a`` and
    ``b``.
theta : float
    Angle of first axis.

Raises
------
ValueError
    If `center` does not have length 2.

Examples
--------

>>> em = EllipseModel((10, 15), (8, 4), np.deg2rad(30))
>>> xy = em.predict_xy(np.linspace(0, 2 * np.pi, 25))
>>> ellipse = EllipseModel.from_estimate(xy)
>>> ellipse.center
array([10., 15.])
>>> ellipse.axis_lengths
array([8., 4.])
>>> round(ellipse.theta, 2)
0.52
>>> np.round(abs(ellipse.residuals(xy)), 5)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0.])

The estimation can fail when — for example — all the input or output
points are the same.  If this happens, you will get an ellipse model for
which ``bool(model)`` is ``False``:

>>> # A successfully estimated model is truthy:
>>> if ellipse:
...     print("Estimation succeeded.")
Estimation succeeded.
>>> # Not so for a degenerate model with identical points.
>>> bad_data = np.ones((4, 2))
>>> bad_ellipse = EllipseModel.from_estimate(bad_data)
>>> if not bad_ellipse:
...     print("Estimation failed.")
Estimation failed.

Trying to use this failed estimation transform result will give a suitable
error:

>>> bad_ellipse.residuals(xy)  # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
  ...
FailedEstimationAccessError: No attribute "residuals" for failed estimation ...
c                 N    U R                  XU5      u  U l        U l        U l        g)a"  Initialize ``EllipseModel`` instance.

Parameters
----------
center : array-like, shape (2,)
    Coordinates of ellipse center.
axis_lengths : array-like, shape (2,)
    Length of first axis and length of second axis.  Call these ``a``
    and ``b``.
theta : float
    Angle of first axis.
N)rx   r   axis_lengthstheta)r)   r   r   r   s       r   r_   EllipseModel._args_init  s'     6:5L5L%6
2T&
r   c                     X4 Vs/ s H  n[         R                  " U5      PM     snu  p[        U5      S:X  d  [        S5      e[        U5      S:X  d  [        S5      eXU4$ s  snf )Nr   r   zAxis lengths should be length 2r   )r)   r   r   r   r   s        r   rx   EllipseModel._check_init_values  sh    6<5KL5K5KL6{aDEE< A%>??U**  Ms    A#c                     [         R                  " U5      n[        U5      S:w  a  [        S5      eU R	                  US S USS US   5      $ )NrY   z!Input `params` should be length 5r      r   r   s     r   rR    EllipseModel._params2init_values$  sM    &!v;!@AA&&vbqz6!A;q	JJr   zS`params` attribute deprecated; use `center, axis_lengths, theta` attributes insteadr   c                 j    [         R                  U R                  U R                  U R                  4   $ )zDReturn model attributes ``center, axis_lengths, theta`` as 1D array.)r   r   r   r   r   r>   s    r   rS   EllipseModel.params*  s(     uuT[[$"3"3TZZ?@@r   c                 "   > [         TU ]  U5      $ )ay  Estimate ellipse model from data using total least squares.

Parameters
----------
data : (N, 2) array
    N points with ``(x, y)`` coordinates, respectively.

Returns
-------
model : Self or `~.FailedEstimation`
    An instance of the ellipse model if the estimation succeeded.
    Otherwise, we return a special ``FailedEstimation`` object to
    signal a failed estimation. Testing the truth value of the failed
    estimation object will return ``False``. E.g.

    .. code-block:: python

        model = EllipseModel.from_estimate(...)
        if not model:
            raise RuntimeError(f"Failed estimation: {model}")

References
----------
.. [1] Halir, R.; Flusser, J. "Numerically stable direct least squares
       fitting of ellipses". In Proc. 6th International Conference in
       Central Europe on Computer Graphics and Visualization.
       WSCG (Vol. 98, pp. 125-132).

r   r   s     r   r%   EllipseModel.from_estimate4  s    > w$T**r   c                    [        USS9  [        U5      S:  a
  [        SUS9$ [        R                  " UR
                  [        R                  5      nUR                  USS9nUR                  SS	9nX-
  nUR                  5       nU[        R                  " U5      R                  :  a
  [        S
US9$ X-  nUS S 2S4   nUS S 2S4   n[        R                  " US-  Xg-  US-  /5      R                  n[        R                  " Xg[        R                  " U5      /5      R                  n	UR                  U-  n
UR                  U	-  nU	R                  U	-  n[        R                  " / SQ/ SQ/ SQ/5      n [!        U5      X[!        U5      -  UR                  -  -
  -  n[        R"                  R'                  U5      u  nnS[        R(                  " USS S 24   USS S 24   5      -  [        R*                  " USS S 24   S5      -
  nUS S 2US:  4   nSUR,                  ;   d  [        UR/                  5       5      S:w  a  gUR/                  5       u  nnn[!        U5      * UR                  -  U-  nUR/                  5       u  nnnUS-  nUS-  nUS-  nUU-  UU-  -
  US-  UU-  -
  -  nUU-  UU-  -
  US-  UU-  -
  -  nUUS-  -  UUS-  -  -   UUS-  -  -   SU-  U-  U-  -
  UU-  U-  -
  n[        R0                  " UU-
  S-  SUS-  -  -   5      nUS-  UU-  -
  UUU-   -
  -  nUS-  UU-  -
  U* UU-   -
  -  n[        R0                  " SU-  U-  5      n [        R0                  " SU-  U-  5      n!S[        R2                  " SU-  UU-
  -  5      -  n"UU:  a  U"S[        R4                  -  -  n"U U!:  a  U!U n!n U"[        R4                  S-  -  n"U"[        R4                  -  n"[        R6                  " UUU U!U"/5      R8                  n#U#S S=== U-  sss& U#S S=== U-  sss& U#S S U#SS U#S   sU l        U l        U l        g ! [        R"                  R$                   a     gf = f)Nr   r   rY   z3Need at least 5 data points to estimate an ellipse.rH   Fr   r   r   zVStandard deviation of data is too small to estimate ellipse with meaningful precision.r   )        r
         @)r
  g      r
  )r  r
  r
  zSingular matrix from estimationr  r   zEigenvector constraints not metr  g      ?) r   r^   r[   r   r   r   r   r   r   r   r   r   vstackT	ones_liker   r   r   LinAlgErroreigmultiplypowerr   ravelr   arctanpi
nan_to_numrealr   r   r   )$r)   r   rI   r   ry   r   r   r   D1D2S1S2S3C1Meig_valseig_vecsconda1rU   bca2dr   gx0y0	numeratortermdenominator1denominator2widthheightphirS   s$                                       r   rJ   EllipseModel._estimateU  s    	!$t9q=E#  %%djj"**=
{{:E{2 "}
288J',,,5# 
 	AJAJ YY1aeQT*+--YYbll1o./11 TTBYTTBYTTBY XX(8/JK	5B2SWrtt 334A  YY]]1-( 2;;x1~x1~>>QTNAB
 
 a$(m$=C
Oq04((*1a "gX_r!((*1a 	
S	S	S !ea!em3Q/!ea!em3Q/ 1Hq1a4x'!ad(2QUQY]BQUQYN	wwA!|a!Q$h./1q1uQ81q1u$!a%9I45Y56 BIIsQw1q5122q53;C
 6>"E6E25519Cruu Bvs;<AAr
e
r
f
 2AJ1QK2J 	3T&

 A yy$$ 	54	5s   8)Q Q-,Q-c                 Z  ^^^^^^ [        USS9  U R                  u  mmU R                  u  mmU R                  n[        R
                  " U5      m[        R                  " U5      mUSS2S4   nUSS2S4   nUR                  S   nUUUUUU4S jn[        R                  " U4[        R                  S9n[        R                  " UT-
  UT-
  5      U-
  n[        U5       HE  n	X9   n
XI   n[        R                  " XhU	   X4S9u  p[        R                  " U" XU5      5      Xy'   MG     U$ )	a  Determine residuals of data to model.

For each point the shortest distance to the ellipse is returned.

Parameters
----------
data : (N, 2) array
    N points with ``(x, y)`` coordinates, respectively.

Returns
-------
residuals : (N,) array
    Residual for each data point.

r   r   Nr   r   c                   > [         R                  " [        R                  " U 5      5      n[         R                  " [        R                  " U 5      5      nTTT	-  U-  -   TT
-  U-  -
  nTTT
-  U-  -   TT	-  U-  -   nX-
  S-  X&-
  S-  -   $ )Nr   )mathr   r   squeezer   )r   xiyictstxtytrU   r$  cthetasthetar   r   s          r   fun#EllipseModel.residuals.<locals>.fun  s    "**Q-(B"**Q-(Ba&j2o%F
R7Ba&j2o%F
R7BG>RWN22r   r   )ra   )r   r   r   r   r5  r   r   r   r   emptyfloat64arctan2ranger	   leastsqr   )r)   r   r   r   r   Nr?  r*   t0ir7  r8  r   r   rU   r$  r=  r>  r   r   s                 @@@@@@r   r*   EllipseModel.residuals  s   " 	!$B  1

%%AJAJJJqM	3 	3$ HHaT4	 ZZBB'%/ qABB##CAbX>DA773qb>2IL  r   c                    [         R                  " U5      nU R                  U5      u  u  p4u  pVn[         R                  " U5      n[         R                  " U5      n	[
        R                  " U5      n
[
        R                  " U5      nX5U
-  U-  -   Xk-  U	-  -
  nXEU-  U-  -   Xj-  U	-  -   n[         R                  " US   US   4UR                  S9$ )a  Predict x- and y-coordinates using the estimated model.

Parameters
----------
t : array
    Angles in circle in radians. Angles start to count from positive
    x-axis to positive y-axis in a right-handed system.

Returns
-------
xy : (..., 2) array
    Predicted x- and y-coordinates.

Other parameters
----------------
params : `~.DEPRECATED`, optional
    Optional ellipse model parameters in the following order ``xc``,
    ``yc``, `a`, `b`, `theta`.

    .. deprecated:: {{ start_version }}
r   r   )r   r   rV   r   r   r5  r   r   )r)   r   rS   r   r   rU   r$  r   r9  r:  r=  r>  r   r   s                 r   r   EllipseModel.predict_xy  s    . MM!"&"7"7"?&1%VVAYVVAY%%Vb 1:?2Vb 1:?2~~q|Qy\:HHr   c                 (    U R                  U5      SL $ )a  Estimate ellipse model from data using total least squares.

Parameters
----------
data : (N, 2) array
    N points with ``(x, y)`` coordinates, respectively.

Returns
-------
success : bool
    True, if model estimation succeeds.


References
----------
.. [1] Halir, R.; Flusser, J. "Numerically stable direct least squares
       fitting of ellipses". In Proc. 6th International Conference in
       Central Europe on Computer Graphics and Visualization.
       WSCG (Vol. 98, pp. 125-132).

Nr   r(   s     r   r   EllipseModel.estimate*  s    . ~~d#t++r   )r   r   r   r   r   r   s   @r   r   r     s    DL
"+K ,(b
A A + +@ob>@ #- !I !IF , ,r   r   c                 b   US:X  a  gU S:X  a  [         R                  $ X-  nSU-
  nSXB-  -
  n[         R                  " U[        S[        -
  S9n[         R                  " U[        S[        -
  S9n[         R                  " [         R
                  " U5      [         R
                  " U5      -  5      $ )a  Determine number trials such that at least one outlier-free subset is
sampled for the given inlier/outlier ratio.

Parameters
----------
n_inliers : int
    Number of inliers in the data.
n_samples : int
    Total number of samples in the data.
min_samples : int
    Minimum number of samples chosen randomly from original data.
probability : float
    Probability (confidence) that one outlier-free sample is generated.

Returns
-------
trials : int
    Number of trials.
r   r   )a_mina_max)r   infclip_EPSILONceillog)	n_inliers	n_samplesmin_samplesprobabilityinlier_rationomdenoms          r   _dynamic_max_trialsr]  D  s    ( aA~vv(L
k/C))E ''#XQ\
:CGGEX>E77266#;.//r   c                   ^  [        T S5      (       a6  [        R                  " T R                  5      (       d  [	        ST  S35      eT $ [        T S5      (       d  [	        ST  S35      e[        S[        SS9   " U 4S	 jS
T 5      nU$ )z=Add ``from_estimate`` method  class using ``estimate`` methodr%   zClass z( `from_estimate` must be a class method.r   z= must have `from_estimate` class method or `estimate` method.zPassing custom classes without `from_estimate` has been deprecated since version 0.26 and will be removed in version 2.2. Add `from_estimate` class method to custom class to avoid this warning.r   r8   c                   ,   > \ rS rSr\U 4S j5       rSrg)(add_from_estimate.<locals>.FromEstimatedi~  c                 z   > U " 5       nUR                   " U0 UD6nU(       a  U$ [        STR                   S35      $ )N`z` estimation failed)r   r   r,   )klassra   rb   instancesuccessr$   s        r   r%   6add_from_estimate.<locals>.FromEstimated.from_estimate  sM     wH''88G   &#,,7J&KLr   r#   N)r,   r-   r.   r/   r1   r%   r2   )r$   s   r   FromEstimatedr`  ~  s    		 
	r   rg  )hasattrrf   ismethodr%   	TypeErrorr   r=   )r$   rg  s   ` r   add_from_estimaterk  g  s     sO$$ 1 122fSE)UUVV
3
##SE $ $
 	

 		 
 
 r   d   c           	      n   Sn[         R                  n/ nUSLnUSLn[         R                  R                  U
5      n
[	        U [
        [        45      (       d  U 4n [        U S   5      nSUs=:  a  U::  d  O  [        SU S35      eUS:  a  [        S5      eUS:  a  [        S5      eSU	s=::  a  S::  d  O  [        S5      eUb*  [        U5      U:w  a  [        S	[        U5       S
U S35      eUb  UOU
R                  UUSS9n[        U5      n[	        U[        5      (       d  [        SU S35      eSnUU:  a  US-  nU  Vs/ s H  nUU   PM
     nnU
R                  UUSS9nU(       a  U" U6 (       d  MD  UR                  " U6 nU(       d  M\  U(       a  U" U/UQ76 (       d  Ms  [         R                  " UR                  " U 6 5      nUU:  nUR!                  U5      n[         R"                  " U5      nUU:  d  UU:X  a.  UU:  a(  UnUnUn[%        U['        UUX)5      5      nX:  d  X::  a  OUU:  a  M  [)        U5      (       aE  U  Vs/ s H  nUU   PM
     nnUR                  " U6 nU(       a  U" U/UQ76 (       d  [+        S5        OSnSn[+        S5        [-        USU5      U4$ s  snf s  snf )u  Fit a model to data with the RANSAC (random sample consensus) algorithm.

RANSAC is an iterative algorithm for the robust estimation of parameters
from a subset of inliers from the complete data set. Each iteration
performs the following tasks:

1. Select `min_samples` random samples from the original data and check
   whether the set of data is valid (see `is_data_valid`).
2. Estimate a model to the random subset
   (`model_cls.from_estimate(*data[random_subset]`) and check whether the
   estimated model is valid (see `is_model_valid`).
3. Classify all data as inliers or outliers by calculating the residuals
   to the estimated model (`model_cls.residuals(*data)`) - all data samples
   with residuals smaller than the `residual_threshold` are considered as
   inliers.
4. Save estimated model as best model if number of inlier samples is
   maximal. In case the current estimated model has the same number of
   inliers, it is only considered as the best model if it has less sum of
   residuals.

These steps are performed either a maximum number of times or until one of
the special stop criteria are met. The final model is estimated using all
inlier samples of the previously determined best model.

Parameters
----------
data : list or tuple or array of shape (N,)
    Data set to which the model is fitted, where N is the number of data
    points and the remaining dimension are depending on model requirements.
    If the model class requires multiple input data arrays (e.g. source and
    destination coordinates of  ``skimage.transform.AffineTransform``),
    they can be optionally passed as tuple or list. Note, that in this case
    the functions ``estimate(*data)``, ``residuals(*data)``,
    ``is_model_valid(model, *random_data)`` and
    ``is_data_valid(*random_data)`` must all take each data array as
    separate arguments.
model_class : type
    Class with the following methods:

    * Either:

      * ``from_estimate`` class method returning transform instance, as in
        ``tform = model_class.from_estimate(*data)``; the resulting
        ``tform`` should be truthy (``bool(tform) == True``) where
        estimation succeeded, or falsey (``bool(tform) == False``) where it
        failed;  OR
      * (deprecated) ``estimate`` instance method, returning flag to
        indicate successful estimation, as in ``tform = model_class();
        success = tform.estimate(*data)``. ``success == True`` when
        estimation succeeded, ``success == False`` when it failed.

    * ``residuals(*data)``

    Your model should conform to the ``RansacModelProtocol`` — meaning
    implement all of the methods / attributes specified by the
    :class:``RansacModelProctocol``. An easy check to see whether that is
    the case is to use ``isinstance(MyModel, RansacModelProtocol)``. See
    https://docs.python.org/3/library/typing.html#typing.Protocol for more
    details.

min_samples : int, in range (0, N)
    The minimum number of data points to fit a model to.
residual_threshold : float, >0
    Maximum distance for a data point to be classified as an inlier.
is_data_valid : Callable, optional
    This function is called with the randomly selected data before the
    model is fitted to it: `is_data_valid(*random_data)`.
is_model_valid : Callable, optional
    This function is called with the estimated model and the randomly
    selected data: `is_model_valid(model, *random_data)`, .
max_trials : int, optional
    Maximum number of iterations for random sample selection.
stop_sample_num : int, optional
    Stop iteration if at least this number of inliers are found.
stop_residuals_sum : float, optional
    Stop iteration if sum of residuals is less than or equal to this
    threshold.
stop_probability : float, optional, in range [0, 1]
    RANSAC iteration stops if at least one outlier-free set of the
    training data is sampled with ``probability >= stop_probability``,
    depending on the current best model's inlier ratio and the number
    of trials. This requires to generate at least N samples (trials):

        N >= log(1 - probability) / log(1 - e**m)

    where the probability (confidence) is typically set to a high value
    such as 0.99, e is the current fraction of inliers w.r.t. the
    total number of samples, and m is the min_samples value.
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.
initial_inliers : array-like of bool, shape (N,), optional
    Initial samples selection for model estimation


Returns
-------
model : object
    Best model with largest consensus set.
inliers : (N,) array
    Boolean mask of inliers classified as ``True``.

References
----------
.. [1] "RANSAC", Wikipedia, https://en.wikipedia.org/wiki/RANSAC

Examples
--------

Generate ellipse data without tilt and add noise:

>>> t = np.linspace(0, 2 * np.pi, 50)
>>> xc, yc = 20, 30
>>> a, b = 5, 10
>>> x = xc + a * np.cos(t)
>>> y = yc + b * np.sin(t)
>>> data = np.column_stack([x, y])
>>> rng = np.random.default_rng(203560)  # do not copy this value
>>> data += rng.normal(size=data.shape)

Add some faulty data:

>>> data[0] = (100, 100)
>>> data[1] = (110, 120)
>>> data[2] = (120, 130)
>>> data[3] = (140, 130)

Estimate ellipse model using all available data:

>>> model = EllipseModel.from_estimate(data)
>>> np.round(model.center)
array([71., 75.])
>>> np.round(model.axis_lengths)
array([77., 13.])
>>> np.round(model.theta)
1.0

Next we estimate an ellipse model using RANSAC.

Note that the results are not deterministic, because the RANSAC algorithm
uses some randomness.   If you need the results to be deterministic, pass a
seeded number generator with the ``rng`` argument to ``ransac``.

>>> ransac_model, inliers = ransac(data, EllipseModel, 20, 3, max_trials=50)
>>> np.abs(np.round(ransac_model.center))  # doctest: +SKIP
array([20., 30.])
>>> np.abs(np.round(ransac_model.axis_lengths))  # doctest: +SKIP
array([10., 6.])
>>> np.abs(np.round(ransac_model.theta))    # doctest: +SKIP
2.0
>>> inliers  # doctest: +SKIP
array([False, False, False, False,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True], dtype=bool)
>>> sum(inliers) > 40
True

RANSAC can be used to robustly estimate a geometric
transformation. In this section, we also show how to use a
proportion of the total samples, rather than an absolute number.

>>> from skimage.transform import SimilarityTransform
>>> rng = np.random.default_rng()
>>> src = 100 * rng.random((50, 2))
>>> model0 = SimilarityTransform(scale=0.5, rotation=1,
...                              translation=(10, 20))
>>> dst = model0(src)
>>> dst[0] = (10000, 10000)
>>> dst[1] = (-100, 100)
>>> dst[2] = (50, 50)
>>> ratio = 0.5  # use half of the samples
>>> min_samples = int(ratio * len(src))
>>> model, inliers = ransac(
...     (src, dst),
...     SimilarityTransform,
...     min_samples,
...     10,
...     initial_inliers=np.ones(len(src), dtype=bool),
... )  # doctest: +SKIP
>>> inliers  # doctest: +SKIP
array([False, False, False,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True])

r   Nz#`min_samples` must be in range (0, ]z.`residual_threshold` must be greater than zeroz&`max_trials` must be greater than zeror   z*`stop_probability` must be in range [0, 1]z4RANSAC received a vector of initial inliers (length z+) that didn't match the number of samples (z). The vector of initial inliers should have the same length as the number of samples and contain only True (this sample is an initial inlier) and False (this one isn't) values.F)rq   z`model_class` z1 should be of (protocol) type RansacModelProtocolz8Estimated model is not valid. Try increasing max_trials.z"No inliers found. Model not fittedmodel)r   rQ  randomdefault_rng
isinstancetuplelistr^   r   choicerk  r   rj  r%   absr*   dotcount_nonzerominr]  anyr   rO   )r   model_classrX  residual_thresholdis_data_validis_model_valid
max_trialsstop_sample_numstop_residuals_sumstop_probabilityrnginitial_inliersbest_inlier_numbest_inlier_residuals_sumbest_inliersvalidate_modelvalidate_datanum_samplesspl_idxs
num_trialsr'  samplesro  r*   inliersresiduals_suminliers_countdata_inlierss                               r   ransacr    s   ^ O "L#4/N!-M
))


$C dUDM**wd1g,K*{*>{m1MNNAIJJA~ABB!&Q&EFF"s?';{'JB?#$ %#} %
 	
 & 	ZZ[%Z@  $K0K k#677[M *" "
 	

 J
z
!a
 )--11X;- ::k;:F !8))73 ."A"A"AFF5??D12	00!i0 ((1 O+ 0!$== ,O(5%"L##[+J  2,Bi z
!n <156A,6))<8."F"F"FKL12 5'5)<77 .j 7s   J-J2r   ))rf   r5  typingr   r   r   warningsr   r   numpyr   numpy.linalgr   scipyr	   r
   _shared.utilsr   r   r   r   r   spacingrS  r   r   r   r;   r<   r4   rB   r[   rl   rs   ru   r   r   r]  rk  rQ  r  r#   r   r   <module>r     s     4 4 )   #  ::a=D
<
 $( $ $   
 
*0 *0Z "J	 ],* ], ],@	 y,* y, y,x },: }, },@ 0F#V FFH8r   