a
    d^                     @   s*  d dl mZmZmZ d dlZd dlm  mZ d dl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 d dlmZmZmZ d d	lm Z m!Z! g d
Z"ddde#dfejejee$e$f e%e%e&ejejdddZ'ddde#dfejejee$e$f e%e%e&ejejdddZ(ejeje%e&ejejdddZ)ejejejdddZ*ejejejdddZ+eeedddZ,ejejejejdd d!Z-dReeee%e%ee& e&ed#d$d%Z.ejejd&d'd(Z/dSejejejejeej eej ejd)d*d+Z0dTejeej eej d,d-d.Z1dUejejejejeej eej eej eej eej eej ejd/d0d1Z2dVejeej eej eej eej eej eej d2d3d4Z3d5d6 Z4dWejejee$e$e$f e%e%e&ejd7d8d9Z5ejejejd:d;d<Z6ejejejejd=d>d?Z7ejejejd@dAdBZ8ejeje%ejdCdDdEZ9dXejejee$e$e$f e%e%e&ejdFdGdHZ:dYejejee$e$f e%e%e&e&e&ejdI	dJdKZ;ejejee$e$e$f ee$e$e$f e%e%e&ejdLdMdNZ<dZejejee$e$e$f e%e%e&e&ejdOdPdQZ=dS )[    )ListOptionalTupleN)grid_sample)Tensorstack)angle_axis_to_rotation_matrixangle_to_rotation_matrix"convert_affinematrix_to_homography$convert_affinematrix_to_homography3ddeg2radnormalize_homographynormalize_homography3dnormalize_pixel_coordinates)transform_points)KORNIA_CHECKKORNIA_CHECK_SHAPE)create_meshgridcreate_meshgrid3deye_like)_torch_inverse_cast_torch_solve_cast)warp_perspectivewarp_affineget_perspective_transformget_rotation_matrix2dremapinvert_affine_transformget_affine_matrix2dget_affine_matrix3dget_shear_matrix2dget_shear_matrix3dwarp_affine3dget_projective_transformprojection_from_Rtget_perspective_transform3dwarp_perspective3d	warp_gridwarp_grid3dhomography_warphomography_warp3dbilinearzerosT   )srcMdsizemodepadding_modealign_corners
fill_valuereturnc                 C   sV  t | tjstdt|  t |tjs<tdt| t| jdksZtd| j t|jdkrz|jdd dkstd	|j |d
kr|jtdgkrtd|j | 	 \}}}	}
|\}}t
||	|
f||f}t|}t||d| jd| j|ddd}t|ddddf |}|d
krBt| ||||dS tj| ||||dS )aG  Apply a perspective transformation to an image.

    .. image:: https://kornia-tutorials.readthedocs.io/en/latest/_images/warp_perspective_10_1.png

    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-tutorials.readthedocs.io/en/
        latest/warp_perspective.html>`_.
    *Input src type is not a torch.Tensor. Got (Input M type is not a torch.Tensor. Got    (Input src must be a BxCxHxW tensor. Got r-   Nr-   r-   z$Input M must be a Bx3x3 tensor. Got fill2Padding_tensor only supported for 3 channels. Got Tnormalized_coordinatesdevice   r3   r1   r4   r3   r1   r2   )
isinstancetorchr   	TypeErrortypelenshape
ValueErrorSizesizer   r   r   r@   todtyperepeatr   _fill_and_warpFr   )r.   r/   r0   r1   r2   r3   r4   B_HWZh_outZw_outdst_norm_trans_src_normsrc_norm_trans_dst_normgrid rY   j/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/geometry/transform/imgwarp.pyr   .   s(    0 $
r   c                 C   sJ  t | tjstdt|  t |tjs<tdt| t| jdksZtd| j t|jdks|jdd dkstd	|j |d
kr|jtdgkrtd|j | 	 \}}}	}
t
|}t||	|
f|}t|}tj|ddddddf |||d |d g|d}|d
kr6t| ||||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-tutorials.readthedocs.io/en/latest/
       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])
    r6   r7   r8   r9   r-   r:   N   r-   z$Input M must be a Bx2x3 tensor. Got r<   r=   r\   r   rA   r3   rB   rC   )rD   rE   r   rF   rG   rH   rI   rJ   rK   rL   r
   r   r   rQ   affine_gridrP   r   )r.   r/   r0   r1   r2   r3   r4   rR   CrT   rU   ZM_3x3rV   rW   rX   rY   rY   rZ   r      s$    / 6
r   )r.   rX   r1   r3   r4   r5   c                 C   s\   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)`.
    NrA   r,   rC   )rE   	ones_likerM   rQ   r   )r.   rX   r1   r3   r4   Z	ones_maskZinv_ones_maskZinv_color_maskrY   rY   rZ   rP      s
    
rP   )rX   src_homo_dstr5   c                 C   sh   | d}|   \}}}}| |ddd} t|jdkrH||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, N, 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   r-   rA   r\   rL   expandrH   rI   viewr   rM   )rX   ra   
batch_sizerS   heightwidthflowrY   rY   rZ   r'      s    
r'   c                 C   sn   | d}|   \}}}}}| |dddd} t|jdkrL||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   rb   r-   rA   r8   rc   )rX   ra   rf   rS   depthrg   rh   ri   rY   rY   rZ   r(      s    
r(   )
points_src
points_dstr5   c                 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| jd}tj|| j| jd}t	dD ]}| 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< q|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)
    )rR   42z4Source data shape must match Destination data shape.z2Source data type must match Destination data type.r      r@   rN   r8   .rA   rb   Nr\   	   .r   .rb   r-   )r   r   rI   rN   rE   emptyr@   r,   onesranger   re   r   fill_)rk   rl   rR   Ar,   ru   ix1y1Zx2y2bXr/   rY   rY   rZ   r     s&    -
6<
r   )centeranglescaler5   c              	   C   sb  t | tjstdt|  t |tjs<tdt| t |tjsZtdt| t| jdkrv| jd dkstd| j t|jdkstd|j t|jdkr|jd dkstd|j | jd	 |jd	   kr|jd	 ksn td
| j|j|j| j	|j	  kr0|j	krTn n | j
|j
  krR|j
ksxn td| j	| j
|j	|j
|j	|j
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 = torch.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 torch.Tensor. Got z,Input angle type is not a torch.Tensor. Got z,Input scale type is not a torch.Tensor. Got r\   rA   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   zPInputs must have same batch size dimension. Got center {}, angle {} and scale {}zSInputs must have same device Got center ({}, {}), angle ({}, {}) and scale ({}, {})r-   N)rD   rE   r   rF   rG   rH   rI   rJ   formatr@   rN   r   r	   )r   r   r   Zshift_mZshift_m_invZscale_mZrotat_mZaffine_mrY   rY   rZ   r   t  sF    +*B


&&
r   F)imagemap_xmap_yr1   r2   r3   r?   r5   c                 C   sx   t | g d t |g d t |g d | j\}}}	}
t||gd}|sVt||	|
}||ddd}t| ||||dS )a0  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`.
    )rR   r_   rT   rU   )rR   rT   rU   rb   r1   r2   r3   )r   rI   r   r   rd   r   )r   r   r   r1   r2   r3   r?   rf   rS   rg   rh   Zmap_xyrY   rY   rZ   r     s    1r   )matrixr5   c                 C   st   t | tjstdt|  t| jdkr>| jdd dksNtd| j t| }t	|}|dddddf S )	uk  Invert an affine transformation.

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

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

    The result is also a 2×3 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 torch.Tensor. Got r-   r:   Nr[   z)Input matrix must be a Bx2x3 tensor. Got .r\   )
rD   rE   r   rF   rG   rH   rI   rJ   r
   r   )r   Z
matrix_tmpZ
matrix_invrY   rY   rZ   r     s     r   )translationsr   r   r   sxsyr5   c           	      C   sT   t || |}|d  | 7  < t|}tdd ||fD rPt|||}|| }|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`.
    ).r\   c                 s   s   | ]}|d uV  qd S NrY   .0srY   rY   rZ   	<genexpr>W      z&get_affine_matrix2d.<locals>.<genexpr>)r   r
   anyr    )	r   r   r   r   r   r   	transformtransform_h	shear_matrY   rY   rZ   r   9  s    r   )r   r   r   c           	   	   C   s   |du r t dg| dn|}|du rDt dg| dn|}t j| ddd\}}|d|d }}t |}t |}t |}t j|| || | |||  ||| |  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 degree along x axis.
        sy: shearing degree along y axis.

    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   rA   rb   Zdimr\   r-   )
rE   tensorrO   rL   splitre   tanr`   r   r
   )	r   r   r   xyZsx_tanZsy_tanru   r   rY   rY   rZ   r    ^  s    !$$


,r    )r   r   r   anglessxysxzsyxsyzszxszyr5   c
                 C   sd   t || |}
|
d  | 7  < t|
}tdd ||||||	fD r`t|||||||	}|| }|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)`.
        angle: angle axis 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`.
    ).r-   c                 s   s   | ]}|d uV  qd S r   rY   r   rY   rY   rZ   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   rY   rY   rZ   r     s    "r   )r   r   r   r   r   r   r   c                 C   s@  |du r t dg| dn|}|du rDt dg| dn|}|du rht dg| dn|}|du rt dg| dn|}|du rt dg| dn|}|du rt dg| dn|}t j| ddd\}}}	|d|d|	d  }}}	t |}
t |}t |}t |}t |}t |}t|
|||||\	}}}}}}}}}|| ||	  }|| ||  ||	  | }|| ||  ||	  |	 }|
 | | | | | f\}
}}}}}t|
|||||\	}}}}}}}}}t j||||||||||||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 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 degree along x axis, towards y plane.
        sxz: shearing degree along x axis, towards z plane.
        syx: shearing degree along y axis, towards x plane.
        syz: shearing degree along y axis, towards z plane.
        szx: shearing degree along z axis, towards x plane.
        szy: shearing degree along z axis, towards y plane.

    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   rA   rb   r   r-   r8   )
rE   r   rO   rL   r   re   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m22Zm03Zm13Zm23r   rY   rY   rZ   r!     s6    8$$$$$$"





(0r!   c              	   C   s   t | }|| |  }}}	|| | | || |   }
}}|| | }| | ||  }|| ||  | }|||	|
|||||f	S r   )rE   r`   )r   r   r   r   r   r   ru   r   r   r   r   r   r   r   r   r   rY   rY   rZ   r     s    
 r   )r.   r/   r0   flagsr2   r3   r5   c                 C   s   t | jdkrt| jt |jdkr8|jdd dksBt|jt |dkrVt||  \}}}}	}
||	|
f}|}t|}t|||}t|}|ddddf }||gt| }tj	j
j|||d}tj	j
j| ||||dS )aH  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).
        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.

    Returns:
        torch.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`.
       r-   r:   N)r-   r8   r]   rC   )rH   rI   AssertionErrorrL   r   r   r   listrE   nn
functionalr^   r   )r.   r/   r0   r   r2   r3   rR   r_   DrT   rU   Zsize_srcZsize_outZM_4x4rV   rW   ZP_normZ	dsize_outrX   rY   rY   rZ   r"   '  s$    
 


r"   )rmattvecr5   c                 C   sf   t | jdkr | jdd dks*t| jt |jdkrJ|jdd dksTt|jtj| |gd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)`.
    r\   r:   Nr;   )r-   rA   rb   r   )rH   rI   r   rE   cat)r   r   rY   rY   rZ   r$   _  s
     
 
r$   )r   r   scalesr5   c           	      C   sD  t | jdkr| jd dks&t| jt |jdkrB|jd dksLt|j| j|jkrft| j|j| j|jkrt| j|jt|}t|}td|}||jdd }||	| }t
dd |jd dd| }|d	dddf  | 7  < | }t|}t|t
| d
 }t|}|| | }|d	ddddf S )aK  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: angle axis 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`.
    r\   rb   r-   rA   r   r8   Nr   .).N)rH   rI   r   r@   rN   r   r   r   Z	unsqueezerM   rE   ZeyerO   Ztype_ascloner   r$   
zeros_liker   )	r   r   r   Zangle_axis_radr   Zscaling_matrixZfrom_origin_matZto_origin_matZproj_matrY   rY   rZ   r#   v  s*    


$r#   )r.   dstr5   c           	      C   s  t | tjstdt|  t |tjs<tdt| | jdd dks^td| j | j|jksztd|j | jd |jd kstd| j d	|j | j|jkr| j|jkst	d
| j d|j d| j d|j d	g }dD ]}|
t| dd|f |dd|f d |
t| dd|f |dd|f d |
t| dd|f |dd|f d qtj|dd}tj|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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 torch.Tensor. Got r:   N)ro   r-   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 z, z) with the same dtype (Got z).)r   rA   r\   r      r   r   r   rA   r   r\   r-   r      r   ro      rp   rr   .   rs   rb   r8   )rD   rE   r   rF   rG   rI   rJ   r@   rN   r   append_build_perspective_param3dr   r   rt   rw   re   )	r.   r   pry   rx   r}   r~   rf   r/   rY   rY   rZ   r%     sb    E**,

r%   )r   qaxisr5   c                 C   s  t | dddf }t | dddf }|dkrt j| 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dS |dkrt j||||| 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dS |d	krt j||||||||| 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dS td
| dd S )N.r   rA   r   r\   r-   r   r   r   zperspective params for axis `z` is not implemented.)rE   r`   r   r   NotImplementedError)r   r   r   ru   r,   rY   rY   rZ   r   9  s~    
(((
(((
(((r   )r.   r/   r0   r   border_moder3   r5   c           	      C   s   t | tjstdt|  t |tjs<tdt| t| jdksZtd| j t|jdks|jdd dkst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`.
    r6   r7   r   z*Input src must be a BxCxDxHxW tensor. Got r-   r:   N)r8   r8   z$Input M must be a Bx4x4 tensor. Got )	rD   rE   r   rF   rG   rH   rI   rJ   _transform_warp_impl3d)	r.   r/   r0   r   r   r3   dhwrY   rY   rZ   r&     s    # r&   )		patch_srcra   r0   r1   r2   r3   r?   normalized_homographyr5   c                 C   st   |j | j ks td| j |j |r`|\}}	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])
    tPatch and homography must be on the same device.                          Got patch.device: {} src_H_dst.device: {}.)r?   r@   rN   r   r+   T)	r@   rF   r   r   rN   r'   rQ   r   r   )r   ra   r0   r1   r2   r3   r?   r   rg   rh   rX   warped_gridrY   rY   rZ   r)     s     )
r)   )r.   dst_pix_trans_src_pix	dsize_src	dsize_dst	grid_moder2   r3   r5   c           	      C   s*   t |||}t|}t| |||||dS )zHCompute the transform in normalized coordinates and perform the warping.T)r   rE   Zinverser*   )	r.   r   r   r   r   r2   r3   rV   rW   rY   rY   rZ   r     s    

r   )r   ra   r0   r1   r2   r3   r?   r5   c                 C   s\   |j | j ks td| j |j |\}}}	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   )r@   rF   r   r   r(   rQ   r   )r   ra   r0   r1   r2   r3   r?   rj   rg   rh   rX   r   rY   rY   rZ   r*     s    

r*   )r+   r,   NF)NN)NN)NNNNNN)NNNNNN)r+   r,   T)r+   r,   F)r+   r,   FTT)r+   r,   FT)>typingr   r   r   rE   Ztorch.nn.functionalr   r   rQ   r   Zkornia.corer   r   Zkornia.geometry.conversionsr   r	   r
   r   r   r   r   r   Zkornia.geometry.linalgr   Zkornia.testingr   r   Zkornia.utilsr   r   r   Zkornia.utils.helpersr   r   __all__r,   intstrboolr   r   rP   r'   r(   r   r   r   r   r   r    r   r!   r   r"   r$   r#   r%   r   r&   r)   r   r*   rY   rY   rY   rZ   <module>   s^  (

X
QU`    E)  %"7      0      ^   86 M   8     
>    