o
    oi/                     @  s&  d dl mZ d dlmZ d dlZd dlm  mZ d dl	m
Z
mZmZmZmZmZmZmZ d dlmZmZ d dlmZmZmZmZmZmZmZmZ d dlmZ d dl m!Z!m"Z"m#Z# d d	l$m%Z%m&Z& g d
Z'				dzd{ddZ(				dzd{ddZ)d|d d!Z*d}d#d$Z+d}d%d&Z,d~d)d*Z-dd.d/Z.				0ddd6d7Z/dd9d:Z0		ddd>d?Z1dd@dAZ2dddBdCZ3						dddKdLZ4						dddMdNZ5ddVdWZ6			dddZd[Z7dd^d_Z8ddadbZ9ddddeZ:ddidjZ;			0dddldmZ<			0		dddpdqZ=ddvdwZ>			0	dddxdyZ?dS )    )annotations)OptionalN)Tensorconcatenateones	ones_likestacktantensorzeros)KORNIA_CHECKKORNIA_CHECK_SHAPE)angle_to_rotation_matrixaxis_angle_to_rotation_matrix"convert_affinematrix_to_homography$convert_affinematrix_to_homography3ddeg2radnormalize_homographynormalize_homography3dnormalize_pixel_coordinates)transform_points)create_meshgridcreate_meshgrid3deye_like)_torch_inverse_cast_torch_solve_cast)get_affine_matrix2dget_affine_matrix3dget_perspective_transformget_perspective_transform3dget_projective_transformget_rotation_matrix2dget_shear_matrix2dget_shear_matrix3dget_translation_matrix2dhomography_warphomography_warp3dinvert_affine_transformprojection_from_Rtremapwarp_affinewarp_affine3d	warp_gridwarp_grid3dwarp_perspectivewarp_perspective3dbilinearr   Tsrcr   Mdsizetuple[int, int]modestrpadding_modealign_cornersbool
fill_valueOptional[Tensor]returnc                 C  s`  t | tstdt|  t |tstdt| t| jdks+td| j t|jdkr;|jdd dksCtd	|j |du rKtd}|d
kr`|jt	dgkr`td|j | 
 \}}}	}
|\}}t||	|
f||f}t|}t||d| jd| j|||d}t|ddddf |}|d
krt| ||||dS tj| ||||dS )a  Apply a perspective transformation to an image.

    The function warp_perspective transforms the source image using
    the specified matrix:

    .. math::
        \text{dst} (x, y) = \text{src} \left(
        \frac{M^{-1}_{11} x + M^{-1}_{12} y + M^{-1}_{13}}{M^{-1}_{31} x + M^{-1}_{32} y + M^{-1}_{33}} ,
        \frac{M^{-1}_{21} x + M^{-1}_{22} y + M^{-1}_{23}}{M^{-1}_{31} x + M^{-1}_{32} y + M^{-1}_{33}}
        \right )

    Args:
        src: input image with shape :math:`(B, C, H, W)`.
        M: transformation matrix with shape :math:`(B, 3, 3)`.
        dsize: size of the output image (height, width).
        mode: interpolation mode to calculate output values ``'bilinear'`` | ``'nearest'``.
        padding_mode: padding mode for outside grid values ``'zeros'`` | ``'border'`` | ``'reflection'`` | ``'fill'``.
        align_corners: interpolation flag.
        fill_value: tensor of shape :math:`(3)` that fills the padding area. Only supported for RGB.

    Returns:
        the warped input image :math:`(B, C, H, W)`.

    Example:
       >>> img = torch.rand(1, 4, 5, 6)
       >>> H = torch.eye(3)[None]
       >>> out = warp_perspective(img, H, (4, 2), align_corners=True)
       >>> print(out.shape)
       torch.Size([1, 4, 4, 2])

    .. note::
        This function is often used in conjunction with :func:`get_perspective_transform`.

    .. note::
        See a working example `here <https://kornia.github.io/tutorials/nbs/warp_perspective.html>`_.

    $Input src type is not a Tensor. Got "Input M type is not a Tensor. Got    (Input src must be a BxCxHxW tensor. Got    NrA   rA   z$Input M must be a Bx3x3 tensor. Got fillz2Padding_tensor only supported for 3 channels. Got Tnormalized_coordinatesdevice   r8   r5   r:   r8   r5   r7   )
isinstancer   	TypeErrortypelenshape
ValueErrorr   torchSizesizer   r   r   rG   todtypeexpandr   _fill_and_warpFgrid_sample)r1   r2   r3   r5   r7   r8   r:   B_HWh_outw_outdst_norm_trans_src_normsrc_norm_trans_dst_normgrid rc   U/home/ubuntu/.local/lib/python3.10/site-packages/kornia/geometry/transform/imgwarp.pyr.   A   s0   
.
 r.   c                 C  s*  t | tstdt|  t |tstdt| t| jdks+td| j t|jdksC|jdd dksCtd	|j |  \}}}	}
t|}t	||	|
f|}t
|}tj|dddd
ddf |||d |d g|d}|dkr|du rtd}t| ||||dS tj| ||||dS )a  Apply an affine transformation to a tensor.

    .. image:: _static/img/warp_affine.png

    The function warp_affine transforms the source tensor using
    the specified matrix:

    .. math::
        \text{dst}(x, y) = \text{src} \left( M_{11} x + M_{12} y + M_{13} ,
        M_{21} x + M_{22} y + M_{23} \right )

    Args:
        src: input tensor of shape :math:`(B, C, H, W)`.
        M: affine transformation of shape :math:`(B, 2, 3)`.
        dsize: size of the output image (height, width).
        mode: interpolation mode to calculate output values ``'bilinear'`` | ``'nearest'``.
        padding_mode: padding mode for outside grid values ``'zeros'`` | ``'border'`` | ``'reflection'`` | ``'fill'``.
        align_corners : mode for grid_generation.
        fill_value: tensor of shape :math:`(3)` that fills the padding area. Only supported for RGB.

    Returns:
        the warped tensor with shape :math:`(B, C, H, W)`.

    .. note::
        This function is often used in conjunction with :func:`get_rotation_matrix2d`,
        :func:`get_shear_matrix2d`, :func:`get_affine_matrix2d`, :func:`invert_affine_transform`.

    .. note::
       See a working example `here <https://kornia.github.io/tutorials/nbs/rotate_affine.html>`__.

    Example:
       >>> img = torch.rand(1, 4, 5, 6)
       >>> A = torch.eye(2, 3)[None]
       >>> out = warp_affine(img, A, (4, 2), align_corners=True)
       >>> print(out.shape)
       torch.Size([1, 4, 4, 2])

    r=   r>   r?   r@   rA   rB   NrH   rA   z$Input M must be a Bx2x3 tensor. Got rH   r      r8   rD   rI   rJ   )rK   r   rL   rM   rN   rO   rP   rS   r   r   r   rX   affine_gridr   rW   rY   )r1   r2   r3   r5   r7   r8   r:   rZ   Cr\   r]   M_3x3r`   ra   rb   rc   rc   rd   r*      s$   
/
 6r*   rb   c                 C  sZ   t | }||dddddf }dtj||||dd }|| }tj| |||dd| S )a  Warp a mask of ones, then multiple with fill_value and add to default warp.

    Args:
        src: input tensor of shape :math:`(B, 3, H, W)`.
        grid: grid tensor from `transform_points`.
        mode: interpolation mode to calculate output values ``'bilinear'`` | ``'nearest'``.
        align_corners: interpolation flag.
        fill_value: tensor of shape :math:`(3)` that fills the padding area. Only supported for RGB.

    Returns:
        the warped and filled tensor with shape :math:`(B, 3, H, W)`.

    Nrf   r   rJ   )r   rT   rX   rY   )r1   rb   r5   r8   r:   	ones_maskinv_ones_maskinv_color_maskrc   rc   rd   rW      s
   rW   src_homo_dstc                 C  sh   | d}|   \}}}}| |ddd} t|jdkr$||ddd}t|| |}||||dS )a  Compute the grid to warp the coordinates grid by the homography/ies.

    Args:
        grid: Unwrapped grid of the shape :math:`(1, H, W, 2)`.
        src_homo_dst: Homography or homographies (stacked) to
          transform all points in the grid. Shape of the homography
          has to be :math:`(1, 3, 3)` or :math:`(N, 1, 3, 3)`.

    Returns:
        the transformed grid of shape :math:`(N, H, W, 2)`.

    r   rA   rf   rH   rS   rV   rN   rO   viewr   rT   )rb   rn   
batch_sizer[   heightwidthflowrc   rc   rd   r,      s   
r,   c                 C  sn   | d}|   \}}}}}| |dddd} t|jdkr&||ddd}t|| |}|||||dS )a  Compute the grid to warp the coordinates grid by the homography/ies.

    Args:
        grid: Unwrapped grid of the shape :math:`(1, D, H, W, 3)`.
        src_homo_dst: Homography or homographies (stacked) to
          transform all points in the grid. Shape of the homography
          has to be :math:`(1, 4, 4)` or :math:`(N, 1, 4, 4)`.

    Returns:
        the transformed grid of shape :math:`(N, H, W, 3)`.

    r   ro   rA   rf   r?   rp   )rb   rn   rr   r[   depthrs   rt   ru   rc   rc   rd   r-     s   
r-   
points_src
points_dstc                 C  s  t | g d t |g d t| j|jkd t| j|jkd | jd }tj|dd| j| jd}t|| j| jd}t|| j| jd}t	dD ]X}| d|df | d|d	f }}|d|df |d|d	f }	}
t
||||||| |	 | |	 gd
|ddd| f< t
||||||| |
 | |
 gd
|ddd| d	 f< qG|d
dd	}t||}tj|d| j| jd}|d |dddf< |d d	 |d
ddS )a^  Calculate a perspective transform from four pairs of the corresponding points.

    The algorithm is a vanilla implementation of the Direct Linear transform (DLT).
    See more: https://www.cs.cmu.edu/~16385/s17/Slides/10.2_2D_Alignment__DLT.pdf

    The function calculates the matrix of a perspective transform that maps from
    the source to destination points:

    .. math::

        \begin{bmatrix}
        x^{'} \\
        y^{'} \\
        1 \\
        \end{bmatrix}
        =
        \begin{bmatrix}
        h_1 & h_2 & h_3 \\
        h_4 & h_5 & h_6 \\
        h_7 & h_8 & h_9 \\
        \end{bmatrix}
        \cdot
        \begin{bmatrix}
        x \\
        y \\
        1 \\
        \end{bmatrix}

    Args:
        points_src: coordinates of quadrangle vertices in the source image with shape :math:`(B, 4, 2)`.
        points_dst: coordinates of the corresponding quadrangle vertices in
            the destination image with shape :math:`(B, 4, 2)`.

    Returns:
        the perspective transformation with shape :math:`(B, 3, 3)`.

    .. note::
        This function is often used in conjunction with :func:`warp_perspective`.

    Example:
        >>> x1 = torch.tensor([[[0., 0.], [1., 0.], [1., 1.], [0., 1.]]])
        >>> x2 = torch.tensor([[[1., 0.], [0., 0.], [0., 1.], [1., 1.]]])
        >>> x2_trans_x1 = get_perspective_transform(x1, x2)

    )rZ   42z4Source data shape must match Destination data shape.z2Source data type must match Destination data type.r      rG   rU   r?   .rf   ro   NrH   	   .r   .ro   rA   )r   r   rO   rU   rQ   emptyrG   r   r   ranger   rq   r   fill_)rw   rx   rZ   A_zeros_onesix1y1x2y2bXr2   rc   rc   rd   r   3  s&   .
6<
r   centeranglescalec                 C  sp  t | tstdt|  t |tstdt| t |ts*tdt| t| jdkr8| jd dks@td| j t|jdksOtd|j t|jdkr]|jd dksetd|j | jd	 |jd	   krx|jd	 ksn td
| j d|j d|j | j|j  kr|jkrn n| j|j  kr|jksn td| j d| j d|j d|j d|j d|j dt	d| }| |dddddf< t	d| }|  |dddddf< t	d| }|ddd	d	f  |ddd	f 9  < |ddddf  |dddf 9  < t	d| }t
||ddddddf< || | | }|ddddddf S )a  Calculate an affine matrix of 2D rotation.

    The function calculates the following matrix:

    .. math::
        \begin{bmatrix}
            \alpha & \beta & (1 - \alpha) \cdot \text{x}
            - \beta \cdot \text{y} \\
            -\beta & \alpha & \beta \cdot \text{x}
            + (1 - \alpha) \cdot \text{y}
        \end{bmatrix}

    where

    .. math::
        \alpha = \text{scale} \cdot cos(\text{angle}) \\
        \beta = \text{scale} \cdot sin(\text{angle})

    The transformation maps the rotation center to itself
    If this is not the target, adjust the shift.

    Args:
        center: center of the rotation in the source image with shape :math:`(B, 2)`.
        angle: rotation angle in degrees. Positive values mean
            counter-clockwise rotation (the coordinate origin is assumed to
            be the top-left corner) with shape :math:`(B)`.
        scale: scale factor for x, y scaling with shape :math:`(B, 2)`.

    Returns:
        the affine matrix of 2D rotation with shape :math:`(B, 2, 3)`.

    Example:
        >>> center = zeros(1, 2)
        >>> scale = torch.ones((1, 2))
        >>> angle = 45. * torch.ones(1)
        >>> get_rotation_matrix2d(center, angle, scale)
        tensor([[[ 0.7071,  0.7071,  0.0000],
                 [-0.7071,  0.7071,  0.0000]]])

    .. note::
        This function is often used in conjunction with :func:`warp_affine`.

    z'Input center type is not a Tensor. Got z&Input angle type is not a Tensor. Got z&Input scale type is not a Tensor. Got rH   rf   z'Input center must be a Bx2 tensor. Got z$Input angle must be a B tensor. Got z&Input scale must be a Bx2 tensor. Got r   z7Inputs must have same batch size dimension. Got center z, angle z and scale z)Inputs must have same device Got center (, z
), angle (z) and scale ()rA   N)rK   r   rL   rM   rN   rO   rP   rG   rU   r   r   )r   r   r   shift_mshift_m_invscale_mrotat_maffine_mrc   rc   rd   r!     sN   
,

(:


&&
r!   Fimagemap_xmap_yOptional[bool]rF   c                 C  sz   t | g d t |g d t |g d | j\}}}	}
t||gd}|s+t||	|
}||ddd}tj| ||||dS )a1  Apply a generic geometrical transformation to an image tensor.

    .. image:: _static/img/remap.png

    The function remap transforms the source tensor using the specified map:

    .. math::
        \text{dst}(x, y) = \text{src}(map_x(x, y), map_y(x, y))

    Args:
        image: the tensor to remap with shape (B, C, H, W).
          Where C is the number of channels.
        map_x: the flow in the x-direction in pixel coordinates.
          The tensor must be in the shape of (B, H, W).
        map_y: the flow in the y-direction in pixel coordinates.
          The tensor must be in the shape of (B, H, W).
        mode: interpolation mode to calculate output values
          ``'bilinear'`` | ``'nearest'``.
        padding_mode: padding mode for outside grid values
          ``'zeros'`` | ``'border'`` | ``'reflection'``.
        align_corners: mode for grid_generation.
        normalized_coordinates: whether the input coordinates are
           normalized in the range of [-1, 1].

    Returns:
        the warped tensor with same shape as the input grid maps.

    Example:
        >>> import torch
        >>> from kornia.utils import create_meshgrid
        >>> grid = create_meshgrid(2, 2, False)  # 1x2x2x2
        >>> grid += 1  # apply offset in both directions
        >>> input = torch.ones(1, 1, 2, 2)
        >>> remap(input, grid[..., 0], grid[..., 1], align_corners=True)   # 1x1x2x2
        tensor([[[[1., 0.],
                  [0., 0.]]]])

    .. note::
        This function is often used in conjunction with :func:`kornia.utils.create_meshgrid`.

    )rZ   ri   r\   r]   )rZ   r\   r]   ro   r5   r7   r8   )r   rO   r   r   rV   rX   rY   )r   r   r   r5   r7   r8   rF   rr   r[   rs   rt   map_xyrc   rc   rd   r)     s   2r)   matrixc                 C  sr   t | tstdt|  t| jdkr| jdd dks&td| j t| }t|}|dddddf S )	aj  Invert an affine transformation.

    The function computes an inverse affine transformation represented by
    2x3 matrix:

    .. math::
        \begin{bmatrix}
            a_{11} & a_{12} & b_{1} \\
            a_{21} & a_{22} & b_{2} \\
        \end{bmatrix}

    The result is also a 2x3 matrix of the same type as M.

    Args:
        matrix: original affine transform. The tensor must be
          in the shape of :math:`(B, 2, 3)`.

    Return:
        the reverse affine transform with shape :math:`(B, 2, 3)`.

    .. note::
        This function is often used in conjunction with :func:`warp_affine`.

    z'Input matrix type is not a Tensor. Got rA   rB   Nre   z)Input matrix must be a Bx2x3 tensor. Got .rH   )	rK   r   rL   rM   rN   rO   rP   r   r   )r   
matrix_tmp
matrix_invrc   rc   rd   r'   *  s   
 r'   translationssxsyc           	      C  sT   t || |}|d  | 7  < t|}tdd ||fD r(t|||}|| }|S )a  Compose affine matrix from the components.

    Args:
        translations: tensor containing the translation vector with shape :math:`(B, 2)`.
        center: tensor containing the center vector with shape :math:`(B, 2)`.
        scale: tensor containing the scale factor with shape :math:`(B, 2)`.
        angle: tensor of angles in degrees :math:`(B)`.
        sx: tensor containing the shear factor in the x-direction with shape :math:`(B)`.
        sy: tensor containing the shear factor in the y-direction with shape :math:`(B)`.

    Returns:
        the affine transformation matrix :math:`(B, 3, 3)`.

    .. note::
        This function is often used in conjunction with :func:`warp_affine`, :func:`warp_perspective`.

    .rH   c                 s      | ]}|d uV  qd S Nrc   .0src   rc   rd   	<genexpr>n      z&get_affine_matrix2d.<locals>.<genexpr>)r!   r   anyr"   )	r   r   r   r   r   r   	transformtransform_h	shear_matrc   rc   rd   r   O  s   r   c                 C  s<   t d| ddddddf }|d  | 7  < t|}|S )aZ  Compose translation matrix from the components.

    Args:
        translations: tensor containing the translation vector with shape :math:`(B, 2)`.

    Returns:
        the affine transformation matrix :math:`(B, 3, 3)`.

    .. note::
        This function is often used in conjunction with :func:`warp_affine`, :func:`warp_perspective`.

    rA   NrH   r   )r   r   )r   r   r   rc   rc   rd   r$   u  s    r$   c           	   
   C  s   |du rt dg| dn|}|du r t dg| dn|}tj| ddd\}}|d|d}}t|}t|}t|}t|| || | |||  ||||   gddddd}t	|}|S )	a  Compose shear matrix Bx4x4 from the components.

    Note: Ordered shearing, shear x-axis then y-axis.

    .. math::
        \begin{bmatrix}
            1 & b \\
            a & ab + 1 \\
        \end{bmatrix}

    Args:
        center: shearing center coordinates of (x, y).
        sx: shearing angle along x axis in radiants.
        sy: shearing angle along y axis in radiants

    Returns:
        params to be passed to the affine transformation with shape :math:`(B, 3, 3)`.

    Examples:
        >>> rng = torch.manual_seed(0)
        >>> sx = torch.randn(1)
        >>> sx
        tensor([1.5410])
        >>> center = torch.tensor([[0., 0.]])  # Bx2
        >>> get_shear_matrix2d(center, sx=sx)
        tensor([[[  1.0000, -33.5468,   0.0000],
                 [ -0.0000,   1.0000,   0.0000],
                 [  0.0000,   0.0000,   1.0000]]])

    .. note::
        This function is often used in conjunction with :func:`warp_affine`, :func:`warp_perspective`.

    N        r   rf   ro   dimrH   rA   )
r
   repeatrS   rQ   splitrq   r	   r   r   r   )	r   r   r   xysx_tansy_tanr   r   rc   rc   rd   r"     s   """,
r"   anglessxysxzsyxsyzszxszyc
                 C  sd   t || |}
|
d  | 7  < t|
}tdd ||||||	fD r0t|||||||	}|| }|S )a  Compose 3d affine matrix from the components.

    Args:
        translations: tensor containing the translation vector (dx,dy,dz) with shape :math:`(B, 3)`.
        center: tensor containing the center vector (x,y,z) with shape :math:`(B, 3)`.
        scale: tensor containing the scale factor with shape :math:`(B)`.
        angles: axis angle vector containing the rotation angles in degrees in the form
            of (rx, ry, rz) with shape :math:`(B, 3)`. Internally it calls Rodrigues to compute
            the rotation matrix from axis-angle.
        sxy: tensor containing the shear factor in the xy-direction with shape :math:`(B)`.
        sxz: tensor containing the shear factor in the xz-direction with shape :math:`(B)`.
        syx: tensor containing the shear factor in the yx-direction with shape :math:`(B)`.
        syz: tensor containing the shear factor in the yz-direction with shape :math:`(B)`.
        szx: tensor containing the shear factor in the zx-direction with shape :math:`(B)`.
        szy: tensor containing the shear factor in the zy-direction with shape :math:`(B)`.

    Returns:
        the 3d affine transformation matrix :math:`(B, 3, 3)`.

    .. note::
        This function is often used in conjunction with :func:`warp_perspective`.

    ).rA   c                 s  r   r   rc   r   rc   rc   rd   r     r   z&get_affine_matrix3d.<locals>.<genexpr>)r    r   r   r#   )r   r   r   r   r   r   r   r   r   r   r   r   r   rc   rc   rd   r     s   #r   c                 C  s$  |du rt dg| dn|}|du r t dg| dn|}|du r1t dg| dn|}|du rBt dg| dn|}|du rSt dg| dn|}|du rdt dg| dn|}tj| ddd\}}}	|d|d|	d}}}	t|}
t|}t|}t|}t|}t|}t|
|||||\	}}}}}}}}}|| ||	  }|| ||  ||	  | }|| ||  ||	  |	 }|
 | | | | | f\}
}}}}}t|
|||||\	}}}}}}}}}t||||||||||||gdddd}t	|}|S )	aO  Compose shear matrix Bx4x4 from the components.

    Note: Ordered shearing, shear x-axis then y-axis then z-axis.

    .. math::
        \begin{bmatrix}
            1 & o & r & oy + rz \\
            m & p & s & mx + py + sz -y \\
            n & q & t & nx + qy + tz -z \\
            0 & 0 & 0 & 1  \\
        \end{bmatrix}
        Where:
        m = S_{xy}
        n = S_{xz}
        o = S_{yx}
        p = S_{xy}S_{yx} + 1
        q = S_{xz}S_{yx} + S_{yz}
        r = S_{zx} + S_{yx}S_{zy}
        s = S_{xy}S_{zx} + (S_{xy}S_{yx} + 1)S_{zy}
        t = S_{xz}S_{zx} + (S_{xz}S_{yx} + S_{yz})S_{zy} + 1

    Params:
        center: shearing center coordinates of (x, y, z).
        sxy: shearing angle along x axis, towards y plane in radiants.
        sxz: shearing angle along x axis, towards z plane in radiants.
        syx: shearing angle along y axis, towards x plane in radiants.
        syz: shearing angle along y axis, towards z plane in radiants.
        szx: shearing angle along z axis, towards x plane in radiants.
        szy: shearing angle along z axis, towards y plane in radiants.

    Returns:
        params to be passed to the affine transformation.

    Examples:
        >>> rng = torch.manual_seed(0)
        >>> sxy, sxz, syx, syz = torch.randn(4, 1)
        >>> sxy, sxz, syx, syz
        (tensor([1.5410]), tensor([-0.2934]), tensor([-2.1788]), tensor([0.5684]))
        >>> center = torch.tensor([[0., 0., 0.]])  # Bx3
        >>> get_shear_matrix3d(center, sxy=sxy, sxz=sxz, syx=syx, syz=syz)
        tensor([[[  1.0000,  -1.4369,   0.0000,   0.0000],
                 [-33.5468,  49.2039,   0.0000,   0.0000],
                 [  0.3022,  -1.0729,   1.0000,   0.0000],
                 [  0.0000,   0.0000,   0.0000,   1.0000]]])

    .. note::
        This function is often used in conjunction with :func:`warp_perspective3d`.

    Nr   r   rf   ro   r   rA   r?   )
r
   r   rS   rQ   r   rq   r	   _compute_shear_matrix_3dr   r   )r   r   r   r   r   r   r   r   r   zsxy_tansxz_tansyx_tansyz_tanszx_tanszy_tanm00m10m20m01m11m21m02m12m22m03m13m23r   rc   rc   rd   r#     s6   ":""""""(,r#   r   r   r   r   r   r   tuple[Tensor, ...]c              	   C  s~   t | }|| |}}}	|| | | || | }
}}|| | }| | ||  }|| ||  | }|||	|
|||||f	S r   )r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rc   rc   rd   r   M  s    r   tuple[int, int, int]flagsc                 C  s   t | jdkrt| jt |jdkr|jdd dks!t|jt |dkr+t||  \}}}}	}
||	|
f}|}t|}t|||}t|}|ddddf }||gt|}tj	|||d}tj
| ||||dS )aD  Apply a projective transformation a to 3d tensor.

    .. warning::
        This API signature it is experimental and might suffer some changes in the future.

    Args:
        src : input tensor of shape :math:`(B, C, D, H, W)`.
        M: projective transformation matrix of shape :math:`(B, 3, 4)`.
        dsize: size of the output image (depth, height, width).
        flags: interpolation mode to calculate output values
          ``'bilinear'`` | ``'nearest'``.
        padding_mode: padding mode for outside grid values
          ``'zeros'`` | ``'border'`` | ``'reflection'``.
        align_corners : mode for grid_generation.

    Returns:
        Tensor: the warped 3d tensor with shape :math:`(B, C, D, H, W)`.

    .. note::
        This function is often used in conjunction with :func:`get_perspective_transform3d`.

       rA   rB   N)rA   r?   rg   rJ   )rN   rO   AssertionErrorrS   r   r   r   listrX   rh   rY   )r1   r2   r3   r   r7   r8   rZ   ri   Dr\   r]   size_srcsize_outM_4x4r`   ra   P_norm	dsize_outrb   rc   rc   rd   r+   Z  s    
 

r+   rmattvecc                 C  sb   t | jdkr| jdd dkst| jt |jdkr%|jdd dks*t|jt| |gdS )a  Compute the projection matrix from Rotation and translation.

    .. warning::
        This API signature it is experimental and might suffer some changes in the future.

    Concatenates the batch of rotations and translations such that :math:`P = [R | t]`.

    Args:
       rmat: the rotation matrix with shape :math:`(*, 3, 3)`.
       tvec: the translation vector with shape :math:`(*, 3, 1)`.

    Returns:
       the projection matrix with shape :math:`(*, 3, 4)`.

    rH   rB   NrC   )rA   rf   ro   )rN   rO   r   r   )r   r   rc   rc   rd   r(     s
    
 
r(   scalesc           	      C  s.  t | jdkr| jd dkst| jt |jdkr!|jd dks&t|j| j|jkr3t| j|j| j|jkr@t| j|jt|}t|}td|}||jdd }||	| }td|dd}|d	d
ddf  | 7  < |
 }t|}t|t| d }t|}|| | }|d	d
dd
d
f S )aL  Calculate the projection matrix for a 3D rotation.

    .. warning::
        This API signature it is experimental and might suffer some changes in the future.

    The function computes the projection matrix given the center and angles per axis.

    Args:
        center: center of the rotation (x,y,z) in the source with shape :math:`(B, 3)`.
        angles: axis angle vector containing the rotation angles in degrees in the form
            of (rx, ry, rz) with shape :math:`(B, 3)`. Internally it calls Rodrigues to compute
            the rotation matrix from axis-angle.
        scales: scale factor for x-y-z-directions with shape :math:`(B, 3)`.

    Returns:
        the projection matrix of 3D rotation with shape :math:`(B, 3, 4)`.

    .. note::
        This function is often used in conjunction with :func:`warp_affine3d`.

    rH   ro   rA   rf   r   r?   F)shared_memory.N).N)rN   rO   r   rG   rU   r   r   r   	unsqueezerT   cloner   r(   rQ   
zeros_liker   )	r   r   r   axis_angle_radr   scaling_matrixfrom_origin_matto_origin_matproj_matrc   rc   rd   r      s*   


r    dstc           	      C  s
  t | tstdt|  t |tstdt| | jdd dks-td| j | j|jks;td|j | jd |jd ksQtd| j d	|j | j|jkr]| j|jksrtd
| j d|j d| j d|j d	g }dD ]A}|	t
| dd|f |dd|f d |	t
| dd|f |dd|f d |	t
| dd|f |dd|f d qvt|d}t|dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf |dddddf gd}t||}| jd }tj|d| j| jd}|d |dddf< |d d |dd d S )!a  Calculate a 3d perspective transform from four pairs of the corresponding points.

    The function calculates the matrix of a perspective transform so that:

    .. math::

        \begin{bmatrix}
        t_{i}x_{i}^{'} \\
        t_{i}y_{i}^{'} \\
        t_{i}z_{i}^{'} \\
        t_{i} \\
        \end{bmatrix}
        =
        \textbf{map_matrix} \cdot
        \begin{bmatrix}
        x_{i} \\
        y_{i} \\
        z_{i} \\
        1 \\
        \end{bmatrix}

    where

    .. math::
        dst(i) = (x_{i}^{'},y_{i}^{'},z_{i}^{'}), src(i) = (x_{i}, y_{i}, z_{i}), i = 0,1,2,5,7

    Concrete math is as below:

    .. math::

        \[ u_i =\frac{c_{00} * x_i + c_{01} * y_i + c_{02} * z_i + c_{03}}
            {c_{30} * x_i + c_{31} * y_i + c_{32} * z_i + c_{33}} \]
        \[ v_i =\frac{c_{10} * x_i + c_{11} * y_i + c_{12} * z_i + c_{13}}
            {c_{30} * x_i + c_{31} * y_i + c_{32} * z_i + c_{33}} \]
        \[ w_i =\frac{c_{20} * x_i + c_{21} * y_i + c_{22} * z_i + c_{23}}
            {c_{30} * x_i + c_{31} * y_i + c_{32} * z_i + c_{33}} \]

    .. math::

        \begin{pmatrix}
        x_0 & y_0 & z_0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_0*u_0 & -y_0*u_0 & -z_0 * u_0 \\
        x_1 & y_1 & z_1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_1*u_1 & -y_1*u_1 & -z_1 * u_1 \\
        x_2 & y_2 & z_2 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_2*u_2 & -y_2*u_2 & -z_2 * u_2 \\
        x_5 & y_5 & z_5 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_5*u_5 & -y_5*u_5 & -z_5 * u_5 \\
        x_7 & y_7 & z_7 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_7*u_7 & -y_7*u_7 & -z_7 * u_7 \\
        0 & 0 & 0 & 0 & x_0 & y_0 & z_0 & 1 & 0 & 0 & 0 & 0 & -x_0*v_0 & -y_0*v_0 & -z_0 * v_0 \\
        0 & 0 & 0 & 0 & x_1 & y_1 & z_1 & 1 & 0 & 0 & 0 & 0 & -x_1*v_1 & -y_1*v_1 & -z_1 * v_1 \\
        0 & 0 & 0 & 0 & x_2 & y_2 & z_2 & 1 & 0 & 0 & 0 & 0 & -x_2*v_2 & -y_2*v_2 & -z_2 * v_2 \\
        0 & 0 & 0 & 0 & x_5 & y_5 & z_5 & 1 & 0 & 0 & 0 & 0 & -x_5*v_5 & -y_5*v_5 & -z_5 * v_5 \\
        0 & 0 & 0 & 0 & x_7 & y_7 & z_7 & 1 & 0 & 0 & 0 & 0 & -x_7*v_7 & -y_7*v_7 & -z_7 * v_7 \\
        0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_0 & y_0 & z_0 & 1 & -x_0*w_0 & -y_0*w_0 & -z_0 * w_0 \\
        0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_1 & y_1 & z_1 & 1 & -x_1*w_1 & -y_1*w_1 & -z_1 * w_1 \\
        0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_2 & y_2 & z_2 & 1 & -x_2*w_2 & -y_2*w_2 & -z_2 * w_2 \\
        0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_5 & y_5 & z_5 & 1 & -x_5*w_5 & -y_5*w_5 & -z_5 * w_5 \\
        0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_7 & y_7 & z_7 & 1 & -x_7*w_7 & -y_7*w_7 & -z_7 * w_7 \\
        \end{pmatrix}

    Args:
        src: coordinates of quadrangle vertices in the source image with shape :math:`(B, 8, 3)`.
        dst: coordinates of the corresponding quadrangle vertices in
            the destination image with shape :math:`(B, 8, 3)`.

    Returns:
        the perspective transformation with shape :math:`(B, 4, 4)`.

    .. note::
        This function is often used in conjunction with :func:`warp_perspective3d`.

    z Input type is not a Tensor. Got rB   N)r{   rA   z#Inputs must be a Bx8x3 tensor. Got z%Inputs must have the same shape. Got r   z3Inputs must have same batch size dimension. Expect z	 but got z5Expect `src` and `dst` to be in the same device (Got r   z) with the same dtype (Got z).)r   rf   rH   r      r   r   r   rf   rH   rA   r      r   r{      r|   r~   .   r   ro   r?   )rK   r   rL   rM   rO   rP   rG   rU   r   append_build_perspective_param3dr   r   rQ   r   r   rq   )	r1   r   pr   r   r   r   rr   r2   rc   rc   rd   r     sb   
F
**,


r   r   qaxisc                 C  s  t | dddf }t | dddf }|dkrt| d d ddf | d d ddf | d d ddf |||||||||| d d ddf  |d d ddf  | d d ddf  |d d ddf  | d d ddf  |d d ddf  gdS |dkrt||||| d d ddf | d d ddf | d d ddf |||||| d d ddf  |d d ddf  | d d ddf  |d d ddf  | d d ddf  |d d ddf  gdS |dkrRt||||||||| d d ddf | d d ddf | d d ddf || d d ddf  |d d ddf  | d d ddf  |d d ddf  | d d ddf  |d d ddf  gdS td	| d
)N.r   rf   r   rH   rA   r   r   zperspective params for axis `z` is not implemented.)rQ   r   r   r   NotImplementedError)r   r   r   r   r   rc   rc   rd   r   n  s~   ((((((
(((r   border_modec           	      C  s   t | tstdt|  t |tstdt| t| jdks+td| j t|jdksC|jdd dksCtd	|j | jd
d \}}}t| ||||f||||S )a  Apply a perspective transformation to an image.

    The function warp_perspective transforms the source image using
    the specified matrix:

    .. math::
        \text{dst} (x, y) = \text{src} \left(
        \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} ,
        \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}}
        \right )

    Args:
        src: input image with shape :math:`(B, C, D, H, W)`.
        M: transformation matrix with shape :math:`(B, 4, 4)`.
        dsize: size of the output image (height, width).
        flags: interpolation mode to calculate output values
          ``'bilinear'`` | ``'nearest'``.
        border_mode: padding mode for outside grid values
          ``'zeros'`` | ``'border'`` | ``'reflection'``.
        align_corners: interpolation flag.

    Returns:
        the warped input image :math:`(B, C, D, H, W)`.

    .. note::
        This function is often used in conjunction with :func:`get_perspective_transform3d`.

    r=   r>   r   z*Input src must be a BxCxDxHxW tensor. Got rA   rB   N)r?   r?   z$Input M must be a Bx4x4 tensor. Got )rK   r   rL   rM   rN   rO   rP   _transform_warp_impl3d)	r1   r2   r3   r   r   r8   dhwrc   rc   rd   r/     s   
$
 r/   	patch_srcnormalized_homographyc                 C  sz   |j | j kstd| j  d|j  d|r3|\}}	t||	|| j | jd}
t|
|}tj| ||||dS t| ||d|ddS )a  Warp image patches or tensors by normalized 2D homographies.

    See :class:`~kornia.geometry.warp.HomographyWarper` for details.

    Args:
        patch_src: The image or tensor to warp. Should be from source of shape :math:`(N, C, H, W)`.
        src_homo_dst: The homography or stack of homographies from destination to source of shape :math:`(N, 3, 3)`.
        dsize:
          if homography normalized: The height and width of the image to warp.
          if homography not normalized: size of the output image (height, width).
        mode: interpolation mode to calculate output values ``'bilinear'`` | ``'nearest'``.
        padding_mode: padding mode for outside grid values ``'zeros'`` | ``'border'`` | ``'reflection'``.
        align_corners: interpolation flag.
        normalized_coordinates: Whether the homography assumes [-1, 1] normalized coordinates or not.
        normalized_homography: show is homography normalized.

    Return:
        Patch sampled at locations from source to destination.

    Example:
        >>> input = torch.rand(1, 3, 32, 32)
        >>> homography = torch.eye(3).view(1, 3, 3)
        >>> output = homography_warp(input, homography, (32, 32))

    Example:
        >>> img = torch.rand(1, 4, 5, 6)
        >>> H = torch.eye(3)[None]
        >>> out = homography_warp(img, H, (4, 2), align_corners=True, normalized_homography=False)
        >>> print(out.shape)
        torch.Size([1, 4, 4, 2])

    CPatch and homography must be on the same device. Got patch.device:  src_H_dst.device: .)rF   rG   rU   r   r0   T)rG   rL   r   rU   r,   rX   rY   r.   )r   rn   r3   r5   r7   r8   rF   r   rs   rt   rb   warped_gridrc   rc   rd   r%     s    *

r%   dst_pix_trans_src_pix	dsize_src	dsize_dst	grid_modec           	      C  s,   t |||}tj|}t| |||||dS )zHCompute the transform in normalized coordinates and perform the warping.T)r   rQ   linalginvr&   )	r1   r  r  r  r  r7   r8   r`   ra   rc   rc   rd   r   (  s   
r   c                 C  sb   |j | j kstd| j  d|j  d|\}}}	t|||	|| j d}
t|
|}tj| ||||dS )a  Warp image patches or tensors by normalized 3D homographies.

    Args:
        patch_src: The image or tensor to warp. Should be from source of shape :math:`(N, C, D, H, W)`.
        src_homo_dst: The homography or stack of homographies from destination to source of shape
          :math:`(N, 4, 4)`.
        dsize: The height and width of the image to warp.
        mode: interpolation mode to calculate output values ``'bilinear'`` | ``'nearest'``.
        padding_mode: padding mode for outside grid values ``'zeros'`` | ``'border'`` | ``'reflection'``.
        align_corners: interpolation flag.
        normalized_coordinates: Whether the homography assumes [-1, 1] normalized coordinates or not.

    Return:
        Patch sampled at locations from source to destination.

    Example:
        >>> input = torch.rand(1, 3, 32, 32)
        >>> homography = torch.eye(3).view(1, 3, 3)
        >>> output = homography_warp(input, homography, (32, 32))

    r   r   r   rE   r   )rG   rL   r   r-   rX   rY   )r   rn   r3   r5   r7   r8   rF   rv   rs   rt   rb   r  rc   rc   rd   r&   8  s   


r&   )r0   r   TN)r1   r   r2   r   r3   r4   r5   r6   r7   r6   r8   r9   r:   r;   r<   r   )r1   r   rb   r   r5   r6   r8   r9   r:   r   r<   r   )rb   r   rn   r   r<   r   )rw   r   rx   r   r<   r   )r   r   r   r   r   r   r<   r   )r0   r   NF)r   r   r   r   r   r   r5   r6   r7   r6   r8   r   rF   r9   r<   r   )r   r   r<   r   )NN)r   r   r   r   r   r   r   r   r   r;   r   r;   r<   r   )r   r   r<   r   )r   r   r   r;   r   r;   r<   r   )NNNNNN)r   r   r   r   r   r   r   r   r   r;   r   r;   r   r;   r   r;   r   r;   r   r;   r<   r   )r   r   r   r;   r   r;   r   r;   r   r;   r   r;   r   r;   r<   r   )r   r   r   r   r   r   r   r   r   r   r   r   r<   r   )r0   r   T)r1   r   r2   r   r3   r   r   r6   r7   r6   r8   r9   r<   r   )r   r   r   r   r<   r   )r   r   r   r   r   r   r<   r   )r1   r   r   r   r<   r   )r   r   r   r   r   r6   r<   r   )r0   r   F)r1   r   r2   r   r3   r   r   r6   r   r6   r8   r9   r<   r   )r0   r   FTT)r   r   rn   r   r3   r4   r5   r6   r7   r6   r8   r9   rF   r9   r   r9   r<   r   )r1   r   r  r   r  r   r  r   r  r6   r7   r6   r8   r9   r<   r   )r0   r   FT)r   r   rn   r   r3   r   r5   r6   r7   r6   r8   r9   rF   r9   r<   r   )@
__future__r   typingr   rQ   torch.nn.functionalnn
functionalrX   kornia.corer   r   r   r   r   r	   r
   r   kornia.core.checkr   r   kornia.geometry.conversionsr   r   r   r   r   r   r   r   kornia.geometry.linalgr   kornia.utilsr   r   r   kornia.utils.helpersr   r   __all__r.   r*   rW   r,   r-   r   r!   r)   r'   r   r$   r"   r   r#   r   r+   r(   r    r   r   r/   r%   r   r&   rc   rc   rc   rd   <module>   s   ((
Z
N


 
V_
F*
&81
`
7

7 
M9
<