a
    dm                     @   s  U d dl 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
 ddlmZmZ ddlmZ ddlmZ dd	lmZ i Zeeef ed
< ded< ded< dddddg dddddg ddddddddd d!dd"d#d$	dddd%d&gdd'd(ZG d)d* d*ejZdS )+    )CallableDictOptionalN)resize   )build_backbone)FinePreprocessLocalFeatureTransformer)CoarseMatching)FineMatching)PositionEncodingSineurlsz;http://cmp.felk.cvut.cz/~mishkdmy/models/loftr_outdoor.ckptoutdoorz:http://cmp.felk.cvut.cz/~mishkdmy/models/loftr_indoor.ckptZindoorZ	ResNetFPN)         T   )r         )Zinitial_dimZ
block_dimsr   r   )selfcrossr   r   r   r   r   r   ZlinearF)d_modeld_ffnnheadlayer_names	attentiontemp_bug_fixg?r   Zdual_softmaxg?   g      ?g?   )	ZthrZ	border_rmZ
match_typeZdsmax_temperatureZ	skh_itersZskh_init_bin_scoreZskh_prefilterZtrain_coarse_percentZtrain_pad_num_gt_minr   r   )r   r   r   r   r   )Zbackbone_type
resolutionZfine_window_sizeZfine_concat_coarse_featZ	resnetfpncoarsematch_coarsefinec                       sX   e Zd ZdZdefee ed fddZe	eee
jf dddZ fd	d
Z  ZS )LoFTRa  Module, which finds correspondences between two images.

    This is based on the original code from paper "LoFTR: Detector-Free Local
    Feature Matching with Transformers". See :cite:`LoFTR2021` for more details.

    If the distance matrix dm is not provided, :py:func:`torch.cdist` is used.

    Args:
        config: Dict with initiliazation parameters. Do not pass it, unless you know what you are doing`.
        pretrained: Download and set pretrained weights to the model. Options: 'outdoor', 'indoor'.
                    'outdoor' is trained on the MegaDepth dataset and 'indoor'
                    on the ScanNet.

    Returns:
        Dictionary with image correspondences and confidence scores.

    Example:
        >>> img1 = torch.rand(1, 1, 320, 200)
        >>> img2 = torch.rand(1, 1, 128, 128)
        >>> input = {"image0": img1, "image1": img2}
        >>> loftr = LoFTR('outdoor')
        >>> out = loftr(input)
    r   )
pretrainedconfigc                    s   t    || _t|| _t|d d |d d d| _t|d | _t	|d | _
t|| _t|d | _t | _|| _|d ur|t vrtdt  dd	 }tjjt| |d
}| |d  |   d S )Nr    r   r   )r   r!   r"   z$pretrained should be None or one of c                 S   s   | S )N )Zstoragelocr&   r&   c/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/feature/loftr/loftr.py<lambda>]       z LoFTR.__init__.<locals>.<lambda>)Zmap_location
state_dict)super__init__r%   r   backboner   pos_encodingr	   loftr_coarser
   coarse_matchingr   fine_preprocess
loftr_finer   fine_matchingr$   r   keys
ValueErrortorchZhubZload_state_dict_from_urlload_state_dicteval)r   r$   r%   Zstorage_fcnZpretrained_dict	__class__r&   r(   r-   K   s&    


zLoFTR.__init__)datareturnc                 C   sP  | |d d|d jdd |d jdd d |d |d kr| tj|d |d gdd	\}}||d
 ||d
  \}}\}}n&| |d | |d  \}}\}}| |jdd |jdd |jdd |jdd d | |dddd}|j\}}	}
}|	|d|}| |dddd}|j\}}}}|	|d|}d }}d|v rt
|d |d ddd}d|v rt
|d |d ddd}| ||||\}}| j|||||d | |||||\}}|ddkr| ||\}}| ||| ddddd}i }| D ]\}}|| ||< q4|S )a  
        Args:
            data: dictionary containing the input data in the following format:

        Keyword Args:
            image0: left image with shape :math:`(N, 1, H1, W1)`.
            image1: right image with shape :math:`(N, 1, H2, W2)`.
            mask0 (optional): left image mask. '0' indicates a padded position :math:`(N, H1, W1)`.
            mask1 (optional): right image mask. '0' indicates a padded position :math:`(N, H2, W2)`.

        Returns:
            - ``keypoints0``, matching keypoints from image0 :math:`(NC, 2)`.
            - ``keypoints1``, matching keypoints from image1 :math:`(NC, 2)`.
            - ``confidence``, confidence score [0, 1] :math:`(NC)`.
            - ``batch_indexes``, batch indexes for the keypoints and lafs :math:`(NC)`.
        Zimage0r   r   NZimage1)bshw0_ihw1_ir?   r@   )Zdimr>   )hw0_chw1_cZhw0_fZhw1_fr   r   Zmask0rA   Znearest)interpolationZmask1rB   )mask_c0mask_c1Z
keypoints0Z
keypoints1
confidenceZbatch_indexes)Zmkpts0_fZmkpts1_fZmconfZb_ids)updatesizeshaper.   r7   catsplitr/   ZpermuteZreshaper   flattenr0   r1   r2   r3   r4   items)r   r<   Zfeats_cZfeats_fZfeat_c0Zfeat_c1Zfeat_f0Zfeat_f1nhwcZn1h1Zw1Zc1rF   rG   Zfeat_f0_unfoldZfeat_f1_unfoldZrename_keysoutkvr&   r&   r(   forwardb   sP    0$(&

zLoFTR.forwardc                    sN   t | D ]&}|dr||||ddd< qt j|g|R i |S )Nzmatcher. r   )listr5   
startswithpopreplacer,   r8   )r   r+   argskwargsrV   r:   r&   r(   r8      s    
zLoFTR.load_state_dict)__name__
__module____qualname____doc__default_cfgr   strr   r-   dictr7   ZTensorrX   r8   __classcell__r&   r&   r:   r(   r#   2   s   Pr#   )typingr   r   r   r7   Ztorch.nnnnZkornia.geometryr   r.   r   Zloftr_moduler   r	   Zutils.coarse_matchingr
   Zutils.fine_matchingr   Zutils.position_encodingr   r   re   __annotations__rd   Moduler#   r&   r&   r&   r(   <module>   sH   	