o
    oi0                     @   s   d dl mZ d dlZd dlmZmZmZ d dlmZ d dl	m
Z
 G dd deZG dd	 d	Zd
eddfddZdeddfddZd
ededefddZdS )    )AnyN)Tensorstackzeros)transform_points)create_meshgridc                       s.   e Zd Zdedededdf fddZ  ZS )StereoExceptionmsgargskwargsreturnNc                    s*   d}|| }t  j|g|R i | dS )aq  Construct custom exception for the :module:`~kornia.geometry.camera.stereo` module.

        Adds a general helper module redirecting the user to the proper documentation site.

        Args:
            msg: Custom message to add to the general message.
            *args: Additional argument passthrough
            **kwargs: Additional argument passthrough

        z
 Please check documents here: https://kornia.readthedocs.io/en/latest/geometry.camera.stereo.html for further information and examples.N)super__init__)selfr	   r
   r   doc_help	final_msg	__class__ Q/home/ubuntu/.local/lib/python3.10/site-packages/kornia/geometry/camera/stereo.pyr      s   zStereoException.__init__)__name__
__module____qualname__strr   r   __classcell__r   r   r   r   r      s    &r   c                   @   s   e Zd ZdededdfddZedededdfddZedefd	d
Z	edefddZ
edefddZedefddZedefddZedefddZedefddZedefddZdefddZdedefddZdS )StereoCamerarectified_left_camerarectified_right_camerar   Nc                 C   s:   |  || || _|| _| jj| _| jj| _|  | _dS )a?  Class representing a horizontal stereo camera setup.

        Args:
            rectified_left_camera: The rectified left camera projection matrix
              of shape :math:`(B, 3, 4)`
            rectified_right_camera: The rectified right camera projection matrix
              of shape :math:`(B, 3, 4)`

        N)_check_stereo_camerar   r   devicedtype_init_Q_matrix	_Q_matrix)r   r   r   r   r   r   r   2   s   


zStereoCamera.__init__c              
   C   s  t | jdkrtd| j dt |jdkr td|j d| jdd dkr6td| jdd  d|jdd dkrLtd	|jdd  d| j|jkr_td
| j d|j d| j|jkrrtd| j d|j dtt| dddddf |dddddf std| dddddf  d|dddddf  d|d }tt|drtd| ddS )a9  Ensure user specified correct camera matrices.

        Args:
            rectified_left_camera: The rectified left camera projection matrix
              of shape :math:`(B, 3, 4)`
            rectified_right_camera: The rectified right camera projection matrix
              of shape :math:`(B, 3, 4)`

           z;Expected 'rectified_left_camera' to have 3 dimensions. Got .z;Expected 'rectified_right_camera' to have 3 dimension. Got N   )r#      z@Expected each 'rectified_left_camera' to be of shape (3, 4).Got zAExpected each 'rectified_right_camera' to be of shape (3, 4).Got z\Expected 'rectified_left_camera' and 'rectified_right_camera' to be on the same devices.Got z and zTExpected 'rectified_left_camera' and 'rectified_right_camera' tohave same dtype.Got .ztExpected 'left_rectified_camera' and 'rectified_right_camera' to havesame parameters except for the last column.Got .r   r#   r   z/Expected :math:`T_x * f_x` to be negative. Got )	lenshaper   r   r    torchalleqgt)r   r   tx_fxr   r   r   r   E   sX   6z!StereoCamera._check_stereo_camerac                 C   s   | j jd S )zgReturn the batch size of the storage.

        Returns:
           scalar with the batch size

        r   )r   r)   r   r   r   r   
batch_size   s   zStereoCamera.batch_sizec                 C   
   | j d S )zReturn the focal length in the x-direction.

        Note that the focal lengths of the rectified left and right
        camera are assumed to be equal.

        Returns:
            tensor of shape :math:`(B)`

        ).r   r   r   r/   r   r   r   fx      
zStereoCamera.fxc                 C   r1   )zReturns the focal length in the y-direction.

        Note that the focal lengths of the rectified left and right
        camera are assumed to be equal.

        Returns:
            tensor of shape :math:`(B)`

        ).r%   r%   r2   r/   r   r   r   fy   r4   zStereoCamera.fyc                 C   r1   )zReturn the x-coordinate of the principal point for the left camera.

        Returns:
            tensor of shape :math:`(B)`

        .r      r2   r/   r   r   r   cx_left      
zStereoCamera.cx_leftc                 C   r1   )zReturn the x-coordinate of the principal point for the right camera.

        Returns:
            tensor of shape :math:`(B)`

        r6   )r   r/   r   r   r   cx_right   r9   zStereoCamera.cx_rightc                 C   r1   )zReturn the y-coordinate of the principal point.

        Note that the y-coordinate of the principal points
        is assumed to be equal for the left and right camera.

        Returns:
            tensor of shape :math:`(B)`

        ).r%   r7   r2   r/   r   r   r   cy   r4   zStereoCamera.cyc                 C   s   | j d  | j S )ztThe horizontal baseline between the two cameras.

        Returns:
            Tensor of shape :math:`(B)`

        r'   )r   r3   r/   r   r   r   tx   s   zStereoCamera.txc                 C   s   | j S )aQ  The Q matrix of the horizontal stereo setup.

        This matrix is used for reprojecting a disparity tensor to
        the corresponding point cloud. Note that this is in a general form that allows different focal
        lengths in the x and y direction.

        Return:
            The Q matrix of shape :math:`(B, 4, 4)`.

        )r"   r/   r   r   r   Q   s   zStereoCamera.Qc                 C   s   t | jddf| j| jd}| j }| j| |ddddf< | j | j | |ddddf< | j| |ddddf< | j | j | |ddddf< | j| j | |ddddf< | j |ddddf< | j| j| j	  |ddddf< |S )zInitialize the Q matrix of the horizontal stereo setup. See the Q property.

        Returns:
            The Q matrix of shape :math:`(B, 4, 4)`.

        r&   )r   r    Nr   r#   r%   r7   )
r   r0   r   r    r<   r5   r8   r3   r;   r:   )r   r=   baseliner   r   r   r!      s      zStereoCamera._init_Q_matrixdisparity_tensorc                 C   s   t || jS )zReproject the disparity tensor to a 3D point cloud.

        Args:
            disparity_tensor: Disparity tensor of shape :math:`(B, 1, H, W)`.

        Returns:
            The 3D point cloud of shape :math:`(B, H, W, 3)`

        )reproject_disparity_to_3Dr=   )r   r?   r   r   r   r@      s   
z&StereoCamera.reproject_disparity_to_3D)r   r   r   r   r   staticmethodr   propertyintr0   r3   r5   r8   r:   r;   r<   r=   r!   r@   r   r   r   r   r   1   s,    <				r   r?   r   c                 C   s   t | tstdt|  dt| jdkrtd| j d| jd dkr/td| j d| jtjtj	tj
fvrBtd| j d	S )
zEnsure correct user provided correct disparity tensor.

    Args:
        disparity_tensor: The disparity tensor of shape :math:`(B, 1, H, W)`.

    z@Expected 'disparity_tensor' to be an instance of Tensor but got r$   r&   z6Expected 'disparity_tensor' to have 4 dimensions. Got r%   z]Expected dimension 1 of 'disparity_tensor' to be 1 for as single channeled disparity map.Got z\Expected 'disparity_tensor' to have dtype torch.float16, torch.float32 or torch.float64.Got N
isinstancer   r   typer(   r)   r    r*   float16float32float64)r?   r   r   r   _check_disparity_tensor   s&   
rK   Q_matrixc                 C   s   t | tstdt|  dt| jdkstd| j | jdd dks/td| j | jtjtj	tj
fvrBtd	| j dS )
zEnsure Q matrix is of correct form.

    Args:
        Q_matrix: The Q matrix for reprojecting disparity to a point cloud of shape :math:`(B, 4, 4)`

    z8Expected 'Q_matrix' to be an instance of Tensor but got r$   r#   z.Expected 'Q_matrix' to have 3 dimensions. Got r%   N)r&   r&   zFExpected last two dimensions of 'Q_matrix' to be of shape (4, 4). Got zUExpected 'Q_matrix' to be of type torch.float16, torch.float32 or torch.float64. Got rE   )rL   r   r   r   _check_Q_matrix  s   

rM   c                 C   s   t | t|  | j\}}}}| j}| j}t||d||d}||ddd}tj|dd\}	}
t	|	dt	|
d}	}
t
|
|	| fd|ddddd}t|||||d}|j|||dfksrtd	|||df d
|j d|S )a  Reproject the disparity tensor to a 3D point cloud.

    Args:
        disparity_tensor: Disparity tensor of shape :math:`(B, H, W, 1)`.
        Q_matrix: Tensor of Q matrices of shapes :math:`(B, 4, 4)`.

    Returns:
        The 3D point cloud of shape :math:`(B, H, W, 3)`

    F)normalized_coordinatesr   r    rD   )dimr%   r#   r   r7   z]Something went wrong in `reproject_disparity_to_3D`. Expected the final outputto be of shape z(.But the computed point cloud had shape zO. Please ensure input are correct. If this is an error, please submit an issue.)rM   rK   r)   r    r   r   expandr*   unbind	unsqueezer   reshapepermuter   r   )r?   rL   r0   rowscols_r    r   uvvuuvdpointsr   r   r   r@   0  s(   $
r@   )typingr   r*   kornia.corer   r   r   kornia.geometry.linalgr   kornia.utils.gridr   	Exceptionr   r   rK   rM   r@   r   r   r   r   <module>   s    N