
    h                     8    S SK rS SKJr  SSKJr   " S S5      rg)    N)distance_matrix   )check_nDc                   V    \ rS rSrSrS rS r\S 5       rS r	S r
S r\S	 5       rS
rg)ThinPlateSplineTransform   u  Thin-plate spline transformation.

Given two matching sets of points, source and destination, this class
estimates the thin-plate spline (TPS) transformation which transforms
each point in source into its destination counterpart.

Attributes
----------
src : (N, 2) array_like
    Coordinates of control points in source image.

References
----------
.. [1] Bookstein, Fred L. "Principal warps: Thin-plate splines and the
       decomposition of deformations," IEEE Transactions on pattern analysis
       and machine intelligence 11.6 (1989): 567–585.
       DOI:`10.1109/34.24792`
       https://user.engineering.uiowa.edu/~aip/papers/bookstein-89.pdf

Examples
--------
>>> import skimage as ski

Define source and destination control points such that they simulate
rotating by 90 degrees and generate a meshgrid from them:

>>> src = np.array([[0, 0], [0, 5], [5, 5], [5, 0]])
>>> dst = np.array([[5, 0], [0, 0], [0, 5], [5, 5]])

Estimate the transformation:

>>> tps = ski.transform.ThinPlateSplineTransform()
>>> tps.estimate(src, dst)
True

Appyling the transformation to `src` approximates `dst`:

>>> np.round(tps(src))
array([[5., 0.],
       [0., 0.],
       [0., 5.],
       [5., 5.]])

Create a meshgrid to apply the transformation to:

>>> grid = np.meshgrid(np.arange(5), np.arange(5))
>>> grid[1]
array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1],
       [2, 2, 2, 2, 2],
       [3, 3, 3, 3, 3],
       [4, 4, 4, 4, 4]])

>>> coords = np.vstack([grid[0].ravel(), grid[1].ravel()]).T
>>> transformed = tps(coords)
>>> np.round(transformed[:, 1]).reshape(5, 5).astype(int)
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])
c                 .    SU l         S U l        S U l        g )NF
_estimated_spline_mappingssrcselfs    _/var/www/fran/franai/venv/lib/python3.13/site-packages/skimage/transform/_thin_plate_splines.py__init__!ThinPlateSplineTransform.__init__G   s     $    c                 
   U R                   c  Sn[        U5      e[        R                  " U5      nUR                  S:w  d  UR
                  S   S:w  a  Sn[        U5      eU R                  U5      nU R                  X5      nU$ )zEstimate the transformation from a set of corresponding points.

Parameters
----------
coords : (N, 2) array_like
    x, y coordinates to transform

Returns
-------
transformed_coords: (N, D) array
    Destination coordinates
zOTransformation is undefined, define it by calling `estimate` before applying itr      z%Input `coords` must have shape (N, 2))r   
ValueErrornparrayndimshape_radial_distance_spline_function)r   coordsmsgradial_disttransformed_coordss        r   __call__!ThinPlateSplineTransform.__call__L   s       (%  S/!&!;;!v||A!39CS/!++F3!226G!!r   c                     [        S5      e)NzNot supported)NotImplementedErrorr   s    r   inverse ThinPlateSplineTransform.inversej   s    !/22r   c                 l   [        USSS9  [        USSS9  UR                  S   S:  d  UR                  S   S:  a  Sn[        U5      eUR                  UR                  :w  a'  SUR                   S	UR                   3n[        U5      eXl        UR                  u  pE[	        X5      nU R                  U5      n[        R                  " [        R                  " US
45      U/5      nUS-   n	[        R                  " X4[        R                  S9n
XzSU2SU24'   XSU2SS24'   UR                  U
SS2SU24'   [        R                  " U[        R                  " US
-   U45      /5      n [        R                  R                  X5      U l        g! [        R                  R                    a     gf = f)a  Estimate optimal spline mappings between source and destination points.

Parameters
----------
src : (N, 2) array_like
    Control points at source coordinates.
dst : (N, 2) array_like
    Control points at destination coordinates.

Returns
-------
success: bool
    True indicates that the estimation was successful.

Notes
-----
The number N of source and destination points must match.
r   r   )arg_namedstr      z,Need at least 3 points in in `src` and `dst`z'Shape of `src` and `dst` didn't match, z != r   )dtypeNFT)r   r   r   r   r   _radial_basis_kernelr   hstackoneszerosfloat32Tvstacklinalgsolver   LinAlgError)r   r   r)   r   nddistKPn_plus_3LVs               r   estimate!ThinPlateSplineTransform.estimaten   s   & 	a%(a%(99Q<!syy|a/@CS/!99		!;CII;d399+VCS/!yys(%%d+IIrww1v,-q5HHh)<"1"bqb&	"1"bc'
SS"#rr'
IIsBHHa!eQZ012	$&IIOOA$9D!  yy$$ 		s   -$F F32F3c                 N    [        XR                  5      nU R                  U5      $ )zCCompute the radial distance between input points and source points.)r   r   r-   )r   r   distss      r   r   )ThinPlateSplineTransform._radial_distance   s!    1((//r   c                     U R                   R                  S   nU R                  SU nU R                  US nUS   [        R                  " XSS 5      -   [        R                  " X$5      -   nU$ )z3Estimate the spline function in X and Y directions.r   Nr   )r   r   r   r   dot)r   r   r   r7   war    s          r   r   )ThinPlateSplineTransform._spline_function   sj    HHNN1!!"1%!!!"%qTBFF6QR5$99BFF;<RR!!r   c           	      |    SnU S-  n[         R                  " U S:H  SU[         R                  " X!-   5      -  5      nU$ )a  Compute the radial basis function for thin-plate splines.

Parameters
----------
r : (4, N) ndarray
    Input array representing the Euclidean distance between each pair of
    two collections of control points.

Returns
-------
U : (4, N) ndarray
    Calculated kernel function U.
g:0yE>r   g        )r   wherelog)r_smallr_sqUs       r   r-   -ThinPlateSplineTransform._radial_basis_kernel   s=     !tHHQ#XsD266$-+@$@Ar   r
   N)__name__
__module____qualname____firstlineno____doc__r   r!   propertyr%   r?   r   r   staticmethodr-   __static_attributes__ r   r   r   r      sJ    =~
"< 3 3-^0
"  r   r   )numpyr   scipy.spatialr   _shared.utilsr   r   rY   r   r   <module>r]      s     ) $u ur   