a
    d0                     @   s   d dl mZmZ d dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ dejeeejejf dd	d
Zdejejejeej eejdddZdS )    )OptionalTupleN)convert_points_to_homogeneous)transform_points)eye_like)	linalg_qr:0yE>)pointsepsreturnc           	      C   sF  t | tjstdt|  t| jdkr>td| j dtj| ddd}| | jdd	d
jdd}| jd }tj	| jd tj
| jd}t|||  }t|d | }tj|tj| jd}|dd||f |dddf  |dd||f< |dd||f |dddf  |ddd|f   |dd||f< t|| }||fS )a\  Normalizes points.

    Args:
       points : Tensor containing the points to be normalized with shape :math:`(B, N, D)`.
       eps : Small value to avoid division by zero error.

    Returns:
       Tuple containing the normalized points in the shape :math:`(B, N, D)` and the transformation matrix
       in the shape :math:`(B, D+1, D+1)`.
    z=points is not an instance of torch.Tensor. Type of points is    z-points must be of shape (B, N, D). Got shape .   T)dimZkeepdim   )r   pr   dtypedeviceNr   )
isinstancetorchTensorAssertionErrortypelenshapemeannormZtensorfloat64r   sqrtr   Zarangeint64r   )	r	   r
   Zx_meanZscaleZD_intZD_floatZ	transformZidxsZpoints_norm r#   h/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/geometry/calibration/pnp.py_mean_isotropic_scale_normalize   s    
0D
r%   -C6?)world_points
img_points
intrinsicsweightssvd_epsr   c           #      C   s  t | tjstdt|  t |tjs<tdt| t |tjsZtdt| |durt |tjstdt| t|turtdt| tjtjf}| j|vrtd| d| j d	|j|vrtd
| d|j d	|j|vrtd| d|j d	t	| j
dks2| j
d dkrDtd| j
 d	t	|j
dksd|j
d dkrvtd|j
 d	t	|j
dks|j
dd dkrtd|j
 d	| j
d |j
d krtd| j
d |j
d ks| j
d |j
d krtd| j
d dk r$td| j
d  d| j
dd \}}t| \}}	t|\}
}}
t|dddf |k r~td| dt|}t|}t||}t|\}}t|}tj|d| df| j| jd}||dddddddf< ||dddddddf< |d |d ddf  |dddddddf< |d |d ddf  |dddddddf< t|\}
}
}|d! }||dd}td|}||ddddddf< t||	}t||ddddddf }t|ddddddf }t|}t|dk |d |}||ddddf  }tj|dddddf ddd"}d| ddddf }|| }t|ddddddf \}}td|}t|| } t|| }!tj|!|ddddddf gdd#}"|"S )$a  This function attempts to solve the Perspective-n-Point (PnP) problem using Direct Linear Transform (DLT).

    Given a batch (where batch size is :math:`B`) of :math:`N` 3D points
    (where :math:`N \geq 6`) in the world space, a batch of :math:`N`
    corresponding 2D points in the image space and a batch of
    intrinsic matrices, this function tries to estimate a batch of
    world to camera transformation matrices.

    This implementation needs at least 6 points (i.e. :math:`N \geq 6`) to
    provide solutions.

    This function cannot be used if all the 3D world points (of any element
    of the batch) lie on a line or if all the 3D world points (of any element
    of the batch) lie on a plane. This function attempts to check for these
    conditions and throws an AssertionError if found. Do note that this check
    is sensitive to the value of the svd_eps parameter.

    Another bad condition occurs when the camera and the points lie on a
    twisted cubic. However, this function does not check for this condition.

    Args:
        world_points : A tensor with shape :math:`(B, N, 3)` representing
          the points in the world space.
        img_points : A tensor with shape :math:`(B, N, 2)` representing
          the points in the image space.
        intrinsics : A tensor with shape :math:`(B, 3, 3)` representing
          the intrinsic matrices.
        weights : This parameter is not used currently and is just a
          placeholder for API consistency.
        svd_eps : A small float value to avoid numerical precision issues.

    Returns:
        A tensor with shape :math:`(B, 3, 4)` representing the estimated world to
        camera transformation matrices (also known as the extrinsic matrices).

    Example:
        >>> world_points = torch.tensor([[
        ...     [ 5. , -5. ,  0. ], [ 0. ,  0. ,  1.5],
        ...     [ 2.5,  3. ,  6. ], [ 9. , -2. ,  3. ],
        ...     [-4. ,  5. ,  2. ], [-5. ,  5. ,  1. ],
        ... ]], dtype=torch.float64)
        >>>
        >>> img_points = torch.tensor([[
        ...     [1409.1504, -800.936 ], [ 407.0207, -182.1229],
        ...     [ 392.7021,  177.9428], [1016.838 ,   -2.9416],
        ...     [ -63.1116,  142.9204], [-219.3874,   99.666 ],
        ... ]], dtype=torch.float64)
        >>>
        >>> intrinsics = torch.tensor([[
        ...     [ 500.,    0.,  250.],
        ...     [   0.,  500.,  250.],
        ...     [   0.,    0.,    1.],
        ... ]], dtype=torch.float64)
        >>>
        >>> print(world_points.shape, img_points.shape, intrinsics.shape)
        torch.Size([1, 6, 3]) torch.Size([1, 6, 2]) torch.Size([1, 3, 3])
        >>>
        >>> pred_world_to_cam = kornia.geometry.solve_pnp_dlt(world_points, img_points, intrinsics)
        >>>
        >>> print(pred_world_to_cam.shape)
        torch.Size([1, 3, 4])
        >>>
        >>> pred_world_to_cam
        tensor([[[ 0.9392, -0.3432, -0.0130,  1.6734],
                 [ 0.3390,  0.9324, -0.1254, -4.3634],
                 [ 0.0552,  0.1134,  0.9920,  3.7785]]], dtype=torch.float64)
    zIworld_points is not an instance of torch.Tensor. Type of world_points is zEimg_points is not an instance of torch.Tensor. Type of img_points is zEintrinsics is not an instance of torch.Tensor. Type of intrinsics is Nz_If weights is not None, then weights should be an instance of torch.Tensor. Type of weights is z"Type of svd_eps is not float. Got z3world_points must have one of the following dtypes z. Currently it has r   z1img_points must have one of the following dtypes z1intrinsics must have one of the following dtypes r   r   z3world_points must be of shape (B, N, 3). Got shape z1img_points must be of shape (B, N, 2). Got shape r   )r   r   z1intrinsics must be of shape (B, 3, 3). Got shape z=world_points and img_points must have equal number of points.r   zFworld_points, img_points and intrinsics must have the same batch size.   z9At least 6 points are required to use this function. Got z points.r   zQThe last singular value of one/more of the elements of the batch is smaller than z. This function cannot be used if all world_points (of any element of the batch) lie on a line or if all world_points (of any element of the batch) lie on a plane.   r         .).r   )inputr   r   r   )r   r   r   r   r   floatfloat32r    r   r   r   r%   ZsvdanyZinverser   r   zerosr   Zreshaper   ZbmmdetZ	ones_likewherer   r   signcat)#r'   r(   r)   r*   r+   Zaccepted_dtypesBNZworld_points_normZworld_transform_norm_sZintrinsics_invZworld_points_norm_hZimg_points_invZimg_points_normZimg_transform_normZinv_img_transform_normsystemvZsolutionZsolution_4x4Zintermediater5   ZonesZsign_fixZnorm_colZ
mul_factortempZorthorightmaskZcol_sign_fixZrot_matZpred_world_to_camr#   r#   r$   solve_pnp_dlt-   s    T

  $,


00
" 
""
(rB   )r   )Nr&   )typingr   r   r   Zkornia.geometry.conversionsr   Zkornia.geometry.linalgr   Zkornia.utilsr   Zkornia.utils._compatr   r   r1   r%   rB   r#   r#   r#   r$   <module>   s    "&  