a
    dj                     @   s   d dl mZmZ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 d dlmZ d dlmZ d dlmZ G dd	 d	ejZdS )
    )DictListOptionalTupleN)rgb_to_grayscale)LocalFeatureMatcherLoFTR)find_homography_dlt_iterated)RANSAC)warp_perspectivec                       s  e Zd ZdZdejeedd fddZej	ej	ej	dd	d
Z
ej	dddZej	ej	ej	ej	dddZej	ej	eeej	f dddZej	ej	ej	dddZedddZd ej	ej	eej	 eej	 eej	ej	f dddZej	ej	d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naiveN)matcher	estimatorblending_methodreturnc                    sJ   t    || _|| _|| _|dvr4td| d|dkrFtd| _d S )N)r   vanillaUnsupported estimator ,   . Use ‘ransac’ or ‘vanilla’ instead.r   Z
homography)super__init__r   r   r   NotImplementedErrorr
   r   )selfr   r   r   	__class__ g/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/contrib/image_stitching.pyr   $   s    
zImageStitcher.__init__)
keypoints1
keypoints2r   c              	   C   sn   | j dkr4t|d |d t|ddddf }n6| j dkrX| ||\}}|d }ntd| j  d|S )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)r   c              	   K   sv   g }|d |d |d   }}}t t| D ]&}|| |||k |||k  q0t|dkrltdt|S )z%Compute the corresponding homography.Z
keypoints0r   Zbatch_indexesr   z6Compute homography failed. No matched keypoints found.)rangelenuniqueappendr$   RuntimeErrorr    cat)r   kwargsZhomosZkp1Zkp2idxir   r   r   estimate_transformA   s    $z ImageStitcher.estimate_transform)src_imgdst_imgmaskr   c                 C   s4   | j dkrt|dk||}ntd| j  d|S )zBlend two images together.r      zUnsupported blending method u   . Use ‘naive’.)r   r    wherer   )r   r/   r0   r1   outr   r   r   blend_imageK   s    
zImageStitcher.blend_image)image_1image_2r   c                 C   sB   t | jtst | jtr,t|t|d}ntd| j d|S )z(Preprocess input to the required format.)Zimage0Zimage1zThe preprocessor for z has not been implemented.)
isinstancer   r   r   r   r   )r   r6   r7   
input_dictr   r   r   
preprocessT   s    zImageStitcher.preprocess)imager1   r   c                 C   sD   | d}t| d   }|dkr4|S |dd |f S )N)r   r2   r   .)sumintboolanylongZargminitem)r   r;   r1   Zmask_indexr   r   r   postprocess`   s
    
zImageStitcher.postprocessc                 C   s
   |  |S )N)r   )r   datar   r   r   
on_matcherh   s    zImageStitcher.on_matcher)images_leftimages_right	mask_left
mask_rightr   c                 C   s   |  ||}|jd |jd |jd  f}| |}| jf i |}t|||}	tj|t|gdd}
|d u rzt|}|d u rt|}t|||dd}tj|t|gdd}| 	|	|
||| 
 |jfS )N)ZdimZnearest)mode)r:   shaperE   r.   r   r    r*   Z
zeros_liker!   r5   r>   toZdtype)r   rF   rG   rH   rI   r9   Z	out_shapeZcorrespondencesr"   r/   r0   Zsrc_maskZdst_maskr   r   r   stitch_pairk   s    


zImageStitcher.stitch_pair)imgsr   c                 G   sN   |d }t |}tt|d D ]}| |||d  |\}}q"| ||S )Nr   r2   )r    r!   r%   r&   rO   rC   )r   rP   Zimg_outrH   r-   r   r   r   forward   s
    
zImageStitcher.forward)r   r   )NN)__name__
__module____qualname____doc__nnModulestrr   r    ZTensorr$   r.   r5   r   r:   rC   dictrE   r   r   rO   rQ   __classcell__r   r   r   r   r      s$   

	   r   )typingr   r   r   r   r    Ztorch.nnrV   Zkornia.colorr   Zkornia.featurer   r   Zkornia.geometry.homographyr	   Zkornia.geometry.ransacr
   Zkornia.geometry.transformr   rW   r   r   r   r   r   <module>   s   