o
    oi};                     @   s  d dl Z 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
mZmZ d dlmZ ddlmZmZ dd	lmZ dd
lmZ eeef Zd0dedededededefddZd0dedededededefddZd1dededededef
ddZ	d2dejdejdeej d edejf
d!d"Z	$d3dededed%ed&edefd'd(Zdededefd)d*Z d4dededee defd+d,Z!	$d5dededed%ed&edefd.d/Z"dS )6    N)OptionalTuple)Tensor)KORNIA_CHECK_SHAPE)_extract_device_dtypesafe_inverse_with_masksafe_solve_with_mask)_torch_svd_cast   )convert_points_from_homogeneousconvert_points_to_homogeneous)normalize_points)transform_pointsT:0yE>pts1pts2Hsquaredepsreturnc                 C   sn   t |g d | ddkrt| } |ddkrt|}t|| }|| djdd}|r1|S ||  S )ae  Return transfer error in image 2 for correspondences given the homography matrix.

    Args:
        pts1: correspondences from the left images with shape
          (B, N, 2 or 3). If they are homogeneous, converted automatically.
        pts2: correspondences from the right images with shape
          (B, N, 2 or 3). If they are homogeneous, converted automatically.
        H: Homographies with shape :math:`(B, 3, 3)`.
        squared: if True (default), the squared distance is returned.
        eps: Small constant for safe sqrt.

    Returns:
        the computed distance with shape :math:`(B, N)`.

    B3r         dim)r   sizer   r   powsumsqrt)r   r   r   r   r   	pts1_in_2error_squared r$   N/home/ubuntu/.local/lib/python3.10/site-packages/kornia/geometry/homography.pyoneway_transfer_error#   s   
r&   c                 C   s   t |g d | ddkrt| } |ddkrt|}t| jj}t|\}}t| ||d|}t|| |d|}	|	dd
|}
||	 |
|j ||
 |j  }|rZ|S ||  S )ad  Return Symmetric transfer error for correspondences given the homography matrix.

    Args:
        pts1: correspondences from the left images with shape
          (B, N, 2 or 3). If they are homogeneous, converted automatically.
        pts2: correspondences from the right images with shape
          (B, N, 2 or 3). If they are homogeneous, converted automatically.
        H: Homographies with shape :math:`(B, 3, 3)`.
        squared: if True (default), the squared distance is returned.
        eps: Small constant for safe sqrt.

    Returns:
        the computed distance with shape :math:`(B, N)`.

    r   r   r   Tr
   )r   r   r   torchfinfodtypemaxr   r&   view	expand_astor!   )r   r   r   r   r   max_numH_invgood_Htherebackgood_H_reshapeoutr$   r$   r%   symmetric_transfer_errorD   s   &r5   Fls1ls2c                 C   s   t |g d t | g d t |g d | jdd \}}tj| ddd\}}tj|ddd\}}	t|}
t|	}tjj|
|dd}tt||}tt||}||dd	 	||
 }||dd	 	||
 }d
||  }|ry|d }|S )a  Return transfer error in image 2 for line segment correspondences given the homography matrix.

    Line segment end points are reprojected into image 2, and point-to-line error is calculated w.r.t. line,
    induced by line segment in image 2. See :cite:`homolines2001` for details.

    Args:
        ls1: line segment correspondences from the left images with shape
          (B, N, 2, 2).
        ls2: line segment correspondences from the right images with shape
          (B, N, 2, 2).
        H: Homographies with shape :math:`(B, 3, 3)`.
        squared: if True (default is False), the squared distance is returned.

    Returns:
        the computed distance with shape :math:`(B, N)`.

    r   r   N2r:   Nr   r   chunksr   r   r   g      ?)r   shaper'   chunkr   linalgcrossr   	transposer+   abs)r6   r7   r   r   r   r9   ps1pe1ps2pe2ps2_hpe2_hln2ps1_in2pe1_in2er_st1er_end1errorr$   r$   r%   #line_segment_transfer_error_one_wayi   s"   rP   lupoints1points2weightssolverc              
   C   s  | j |j krt| j | j d dk rt| j t| g d t|g d t| |g\}}d}t| \}}t|\}	}
tj|ddd\}}tj|	ddd\}}t|t|}}tj	|||| | | || || |g	dd}tj	||||||| | | | | g	dd}tj	||fdd
|j d	 d|j d }|d
u r|dd| }n*t|j dkr|j | j d
d kst|j |jdddd}|dd| | }|dkrz	t|\}}}W n  ty   tjdtdd tj|d	ddf||d Y S w |d ddd}n&|dkr0tj|j d	 |j d ||d}t||\}}}|
ddd}ntt|
d	 ||  }||ddd
dd
f |  }|S )aI  Compute the homography matrix using the DLT formulation.

    The linear system is solved by using the Weighted Least Squares Solution for the 4 Points algorithm.

    Args:
        points1: A set of points in the first image with a tensor shape :math:`(B, N, 2)`.
        points2: A set of points in the second image with a tensor shape :math:`(B, N, 2)`.
        weights: Tensor containing the weights per point correspondence with a shape of :math:`(B, N)`.
        solver: variants: svd, lu.


    Returns:
        the computed homography matrix with shape :math:`(B, 3, 3)`.

    r
      )r   r9   r:   r   r   r   r;   r   r   Nr=   svdSVD did not converge
stacklevelr   devicer)   .r   rQ   .)r>   AssertionErrorr   r   r   r'   r?   	ones_like
zeros_likecatreshaperB   lenrepeat_interleave	unsqueezer	   RuntimeErrorwarningswarnRuntimeWarningemptyr   r+   onesr   NotImplementedErrorr   )rR   rS   rT   rU   r\   r)   r   points1_norm
transform1points2_norm
transform2x1y1x2y2rk   zerosaxayAw_full_Vr   r   solH_normr$   r$   r%   find_homography_dlt   sL   

..("

 
r~         @   soft_inl_thn_iterc           	      C   T   t | ||}t|d D ]}t| ||d}t| d|d   }t | ||}q|S )a  Compute the homography matrix using the iteratively-reweighted least squares (IRWLS).

    The linear system is solved by using the Reweighted Least Squares Solution for the 4 Points algorithm.

    Args:
        points1: A set of points in the first image with a tensor shape :math:`(B, N, 2)`.
        points2: A set of points in the second image with a tensor shape :math:`(B, N, 2)`.
        weights: Tensor containing the weights per point correspondence with a shape of :math:`(B, N)`.
          Used for the first iteration of the IRWLS.
        soft_inl_th: Soft inlier threshold used for weight calculation.
        n_iter: number of iterations.

    Returns:
        the computed homography matrix with shape :math:`(B, 3, 3)`.

    r
   F       @r   )r~   ranger5   r'   exp)	rR   rS   rT   r   r   r   rz   errorsweights_newr$   r$   r%   find_homography_dlt_iterated      r   c                 C   sj  | j |j krt| j t| g d t|g d | j}tjg dg dg dg dgtj|d}t| }t|}|dd|f }|dd|f }tjj	|dd	d
ddf |dd
dddf dd|ddd	ddf 
dd	dd
  }tjj	|dd	d
ddf |dd
dddf dd|ddd	ddf 
dd	dd
  }	||	kddjd	dd }
|
S )a  Implement oriented constraint check from :cite:`Marquez-Neila2015`.

    Analogous to https://github.com/opencv/opencv/blob/4.x/modules/calib3d/src/usac/degeneracy.cpp#L88

    Args:
        points1: A set of points in the first image with a tensor shape :math:`(B, 4, 2)`.
        points2: A set of points in the second image with a tensor shape :math:`(B, 4, 2)`.

    Returns:
        Mask with the minimal sample is good for homography estimation:math:`(B, 3, 3)`.

    )r   4r:   )r   r
   r   )r   r
   r   )r   r   r   )r
   r   r   )r)   r\   N.r
   r   r   r   r   r   rV   )r>   r^   r   r\   r'   tensorlongr   r@   rA   permutesignr+   min)rR   rS   r\   idx_permpoints_src_hpoints_dst_hsrc_permdst_perm	left_sign
right_signsample_is_validr$   r$   r%   sample_is_valid_for_homography   s,   
*4 4 r   c           $   
   C   s  t | jdkr| d } t |jdkr|d }t| g d t|g d | jdd \}}t| |g\}}| |d| d}||d| d}t|\}	}
t|\}}tj|	ddd\}}tj|ddd\}}tj|ddd\}}tj|ddd\}}tj|ddd\}}tj|ddd\}}|| }|| }|| ||  }d}tj|| || ||| || ||| || |g	dd	}tj|| || ||| || ||| || |g	dd	}tj||fdd	|jd
 d|jd }|du r|	dd| }n7t |jdkr|j| jdd kst
|jt|jdd	ddd|jd
 d}|	dd| | }z	t|\} } }!W n  tyZ   tjdtdd tj|	d
ddf||d Y S w |!d ddd}"t|d
 |"|
  }"|"|"dddddf |  }#|#S )a  Compute the homography matrix using the DLT formulation for line correspondences.

    See :cite:`homolines2001` for details.

    The linear system is solved by using the Weighted Least Squares Solution for the 4 Line correspondences algorithm.

    Args:
        ls1: A set of line segments in the first image with a tensor shape :math:`(B, N, 2, 2)`.
        ls2: A set of line segments in the second image with a tensor shape :math:`(B, N, 2, 2)`.
        weights: Tensor containing the weights per point correspondence with a shape of :math:`(B, N)`.

    Returns:
        the computed homography matrix with shape :math:`(B, 3, 3)`.

    r   Nr8   r   r
   r;   r   r   r   r   r=   rX   rY   r[   r]   .)rc   r>   r   r   rb   r   r'   r?   ra   rB   r^   
diag_embedre   repeatr	   rf   rg   rh   ri   rj   r   r+   r   )$r6   r7   rT   BSr9   r\   r)   rR   rS   rm   rn   ro   rp   lst1le1lst2le2xs1ys1xs2ys2xe1ye1xe2ye2rx   r   Cr   rv   rw   w_diagrz   r{   r   r}   r$   r$   r%   find_homography_lines_dlt  sR   88(&
* r         @c           	      C   r   )a  Compute the homography matrix using the iteratively-reweighted least squares (IRWLS) from line segments.

    The linear system is solved by using the Reweighted Least Squares Solution for the 4 line segments algorithm.

    Args:
        ls1: A set of line segments in the first image with a tensor shape :math:`(B, N, 2, 2)`.
        ls2: A set of line segments in the second image with a tensor shape :math:`(B, N, 2, 2)`.
        weights: Tensor containing the weights per point correspondence with a shape of :math:`(B, N)`.
          Used for the first iteration of the IRWLS.
        soft_inl_th: Soft inlier threshold used for weight calculation.
        n_iter: number of iterations.

    Returns:
        the computed homography matrix with shape :math:`(B, 3, 3)`.

    r
   Fr   r   )r   r   rP   r'   r   )	r6   r7   rT   r   r   r   rz   r   r   r$   r$   r%   "find_homography_lines_dlt_iteratedY  r   r   )Tr   )F)NrQ   )r   r   )N)r   r   )#rg   typingr   r   r'   kornia.corer   kornia.core.checkr   kornia.utilsr   r   r   kornia.utils.helpersr	   conversionsr   r   epipolarr   r@   r   TupleTensorboolfloatr&   r5   rP   strr~   intr   r   r   r   r$   r$   r$   r%   <module>   sp   $$! %&
E
 %H