
    k h                     8    d dl Zd dlmZ ddlmZ  G d d      Zy)    N)distance_matrix   )check_nDc                   N    e Zd ZdZd Zd Zed        Zd Zd Z	d Z
ed        Zy	)
ThinPlateSplineTransformul  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                 .    d| _         d | _        d | _        y )NF)
_estimated_spline_mappingssrcselfs    /home/developers/rajanand/mypropertyqr-fmb-refixing-v2/venv/lib/python3.12/site-packages/skimage/transform/_thin_plate_splines.py__init__z!ThinPlateSplineTransform.__init__G   s     $    c                    | j                   d}t        |      t        j                  |      }|j                  dk7  s|j
                  d   dk7  rd}t        |      | j                  |      }| j                  ||      }|S )a*  Estimate 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__z!ThinPlateSplineTransform.__call__L   s       (%  S/!&!;;!v||A!39CS/!++F3!226;G!!r   c                     t        d      )NzNot supported)NotImplementedErrorr   s    r   inversez ThinPlateSplineTransform.inversej   s    !/22r   c                 z   t        |dd       t        |dd       |j                  d   dk  s|j                  d   dk  rd}t        |      |j                  |j                  k7  r'd|j                   d	|j                   }t        |      || _        |j                  \  }}t	        ||      }| j                  |      }t        j                  t        j                  |d
f      |g      }|dz   }	t        j                  |	|	ft        j                        }
||
d|d|f<   ||
d|ddf<   |j                  |
ddd|f<   t        j                  |t        j                  |d
z   |f      g      }	 t        j                  j                  |
|      | _        y# t        j                  j                   $ r Y yw xY w)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   estimatez!ThinPlateSplineTransform.estimaten   s   & 	a%(a%(99Q<!syy|a/@CS/!99		!;CII;d399+VCS/!yy1sC(%%d+IIrww1v,-q5HHh)<"1"bqb&	"1"bc'
SS"#rr'
IIsBHHa!eQZ012	$&IIOOAq$9D!  yy$$ 		s   4%F F:9F:c                 P    t        || j                        }| j                  |      S )zCCompute the radial distance between input points and source points.)r   r   r(   )r   r   distss      r   r   z)ThinPlateSplineTransform._radial_distance   s#    1((//r   c                     | j                   j                  d   }| j                  d| }| j                  |d }|d   t        j                  ||dd       z   t        j                  ||      z   }|S )z3Estimate the spline function in X and Y directions.r   Nr   )r   r   r
   r   dot)r   r   r   r2   war   s          r   r   z)ThinPlateSplineTransform._spline_function   so    HHNN1!!"1%!!!"%qTBFF61QR5$99BFF;PQ<RR!!r   c           	      z    d}| dz  }t        j                  | dk(  d|t        j                  ||z         z        }|S )aj  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(   z-ThinPlateSplineTransform._radial_basis_kernel   s?     !tHHQ#XsD266$-+@$@Ar   N)__name__
__module____qualname____doc__r   r   propertyr!   r:   r   r   staticmethodr(    r   r   r   r      sJ    =~
"< 3 3-^0
"  r   r   )numpyr   scipy.spatialr   _shared.utilsr   r   rN   r   r   <module>rR      s     ) $u ur   