o
    oi                     @   s   d dl mZmZmZ d dlZd dlmZ d dlmZm	Z	m
Z
mZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ G d	d
 d
eZdS )    )DictOptionalTupleN)rgb_to_grayscale)ModuleTensorconcatenatewhere
zeros_like)LocalFeatureMatcherLoFTR)find_homography_dlt_iterated)RANSAC)warp_perspectivec                       s  e Zd ZdZd+dedededdf fd	d
ZdededefddZdededefddZ	dedededefddZ
dededeeef fddZdededefddZdeeef deeef fd d!Z		d,d"ed#ed$ee d%ee deeef f
d&d'Zd(edefd)d*Z  ZS )-ImageStitchera  Stitch two images with overlapping fields of view.

    Args:
        matcher: image feature matching module.
        estimator: method to compute homography, either "vanilla" or "ransac".
            "ransac" is slower with a better accuracy.
        blending_method: method to blend two images together.
            Only "naive" is currently supported.

    Note:
        Current implementation requires strict image ordering from left to right.

    .. code-block:: python

        IS = ImageStitcher(KF.LoFTR(pretrained='outdoor'), estimator='ransac').cuda()
        # Compute the stitched result with less GPU memory cost.
        with torch.inference_mode():
            out = IS(img_left, img_right)
        # Show the result
        plt.imshow(K.tensor_to_image(out))

    ransacnaivematcher	estimatorblending_methodreturnNc                    sN   t    || _|| _|| _|dvrtd| d|dkr%td| _d S d S )N)r   vanillaUnsupported estimator $. Use `ransac` or `vanilla` instead.r   
homography)super__init__r   r   r   NotImplementedErrorr   r   )selfr   r   r   	__class__ R/home/ubuntu/.local/lib/python3.10/site-packages/kornia/contrib/image_stitching.pyr   6   s   
zImageStitcher.__init__
keypoints1
keypoints2c              	   C   sn   | j dkrt|d |d t|ddddf }|S | j dkr.| ||\}}|d }|S td| j  d)zEstimate homography by the matched keypoints.

        Args:
            keypoints1: matched keypoint set from an image, shaped as :math:`(N, 2)`.
            keypoints2: matched keypoint set from the other image, shaped as :math:`(N, 2)`.

        r   Nr   r   r   r   )r   r   torch	ones_liker   r   )r   r#   r$   homo_r!   r!   r"   _estimate_homography@   s   
"
z"ImageStitcher._estimate_homographyargskwargsc                    s\   |d |d |d   fddt t  D }t|dkr*tdt|S )z%Compute the corresponding homography.
keypoints0r#   batch_indexesc                    s(   g | ]}  |k  |k qS r!   )r)   ).0iidxkp1kp2r   r!   r"   
<listcomp>V   s   ( z4ImageStitcher.estimate_transform.<locals>.<listcomp>r   z6Compute homography failed. No matched keypoints found.)rangelenuniqueRuntimeErrorr   )r   r*   r+   homosr!   r0   r"   estimate_transformS   s
   $z ImageStitcher.estimate_transformsrc_imgdst_imgmaskc                 C   s0   | j dkrt|dk||}|S td| j  d)zBlend two images together.r      zUnsupported blending method z. Use `naive`.)r   r	   r   )r   r;   r<   r=   outr!   r!   r"   blend_image]   s   
zImageStitcher.blend_imageimage_1image_2c                 C   s8   t | jttfrt|t|d}|S td| j d)z(Preprocess input to the required format.)image0image1zThe preprocessor for z has not been implemented.)
isinstancer   r   r   r   r   )r   rA   rB   
input_dictr!   r!   r"   
preprocessf   s   zImageStitcher.preprocessimagec                 C   sD   | d}t| d   }|dkr|S |dd |f S )N)r   r>   r   .)sumintboolanylongargminitem)r   rH   r=   mask_indexr!   r!   r"   postprocessr   s
   
zImageStitcher.postprocessdatac                 C   s
   |  |S )N)r   )r   rS   r!   r!   r"   
on_matcherz   s   
zImageStitcher.on_matcherimages_leftimages_right	mask_left
mask_rightc                 C   s   |  ||}|jd |jd |jd  f}| |}| jdi |}t|||}	t|t|gd}
|d u r:t|}|d u rCt|}t|||dd}t|t|gd}| 	|	|
||| 
 |jfS )Nnearest)moder!   )rG   shaperT   r:   r   r   r
   r%   r&   r@   rK   todtype)r   rU   rV   rW   rX   rF   	out_shapecorrespondencesr'   r;   r<   src_maskdst_maskr!   r!   r"   stitch_pair}   s   


"zImageStitcher.stitch_pairimgsc                 G   sN   |d }t |}tt|d D ]}| |||d  |\}}q| ||S )Nr   r>   )r%   r&   r5   r6   rd   rR   )r   re   img_outrW   r/   r!   r!   r"   forward   s
   
zImageStitcher.forward)r   r   )NN)__name__
__module____qualname____doc__r   strr   r   r)   r:   r@   r   rG   rR   rT   r   r   rd   rg   __classcell__r!   r!   r   r"   r      s.     

	"

r   )typingr   r   r   r%   kornia.colorr   kornia.corer   r   r   r	   r
   kornia.featurer   r   kornia.geometry.homographyr   kornia.geometry.ransacr   kornia.geometry.transformr   r   r!   r!   r!   r"   <module>   s   