o
    oi
                     @  sd   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 dd
dZddddZdddZdS )z?Module for the projection of points in the canonical z=1 plane.    )annotations)OptionalN)TensorKORNIA_CHECK_SHAPEpoints_in_camerar   returnc                 C  s.   t | ddg | dddf | dddf  S )aS  Project one or more points from the camera frame into the canonical z=1 plane through perspective division.

    .. math::

        \begin{bmatrix} u \\ v \\ w \end{bmatrix} =
        \begin{bmatrix} x \\ y \\ z \end{bmatrix} / z

    .. note::

        This function has a precondition that the points are in front of the camera, i.e. z > 0.
        If this is not the case, the points will be projected to the canonical plane, but the resulting
        points will be behind the camera and causing numerical issues for z == 0.

    Args:
        points_in_camera: Tensor representing the points to project with shape (..., 3).

    Returns:
        Tensor representing the projected points with shape (..., 2).

    Example:
        >>> points = torch.tensor([1., 2., 3.])
        >>> project_points_z1(points)
        tensor([0.3333, 0.6667])

    *3.N      r   )r    r   X/home/ubuntu/.local/lib/python3.10/site-packages/kornia/geometry/camera/projection_z1.pyproject_points_z1   s    r   points_in_cam_canonical	extensionOptional[Tensor]c                 C  sf   t | ddg |du rtj| jdd d | j| jd}n|jd dkr(|d	 }tj| | |gdd
S )a  Unproject one or more points from the canonical z=1 plane into the camera frame.

    .. math::
        \begin{bmatrix} x \\ y \\ z \end{bmatrix} =
        \begin{bmatrix} u \\ v \end{bmatrix} \cdot w

    Args:
        points_in_cam_canonical: Tensor representing the points to unproject with shape (..., 2).
        extension: Tensor representing the extension (depth) of the points to unproject with shape (..., 1).

    Returns:
        Tensor representing the unprojected points with shape (..., 3).

    Example:
        >>> points = torch.tensor([1., 2.])
        >>> extension = torch.tensor([3.])
        >>> unproject_points_z1(points, extension)
        tensor([3., 6., 3.])

    r	   2N)   )devicedtyper   r   ).Ndim)r   opsonesshaper   r   concatenate)r   r   r   r   r   unproject_points_z1<   s   r   c                 C  s~   t | ddg | d }| d }| d }d| }|| }t|}tjtj||| | gddtj||| | gddgd	dS )
aN  Compute the derivative of the x projection with respect to the x coordinate.

    Returns point derivative of inverse depth point projection with respect to the x coordinate.

    .. math::
        \frac{\partial \pi}{\partial x} =
        \begin{bmatrix}
            \frac{1}{z} & 0 & -\frac{x}{z^2} \\
            0 & \frac{1}{z} & -\frac{y}{z^2}
        \end{bmatrix}

    .. note::
        This function has a precondition that the points are in front of the camera, i.e. z > 0.
        If this is not the case, the points will be projected to the canonical plane, but the resulting
        points will be behind the camera and causing numerical issues for z == 0.

    Args:
        points_in_camera: Tensor representing the points to project with shape (..., 3).

    Returns:
        Tensor representing the derivative of the x projection with respect to the x coordinate with shape (..., 2, 3).

    Example:
        >>> points = torch.tensor([1., 2., 3.])
        >>> dx_project_points_z1(points)
        tensor([[ 0.3333,  0.0000, -0.1111],
                [ 0.0000,  0.3333, -0.2222]])

    r	   r
   ).r   ).r   ).r   g      ?r   r   )r   r   
zeros_likestack)r   xyzz_invz_sqzerosr   r   r   dx_project_points_z1_   s   
r(   )r   r   r   r   )N)r   r   r   r   r   r   )__doc__
__future__r   typingr   kornia.corecorer   r   kornia.core.checkr   r   r   r(   r   r   r   r   <module>   s   
#