a
    d8                     @   st  d dl Z 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 d dlmZ d dlmZ ddlm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mZmZ ddlm Z m!Z! ddl"m#Z# ddl$m%Z% d#ej&ej&ej'e(e)ej&dddZ*G dd dej'Z+G dd dej'Z,G dd de,Z-G dd de,Z.G dd de,Z/G dd  d e,Z0G d!d" d"ej'Z1dS )$    N)DictListOptionalTuple)rgb_to_grayscale)ConvQuadInterp3d)ScalePyramid)KORNIA_CHECK_LAF   )LAFAffNetShapeEstimator)HardNet)KeyNetDetector)extract_patches_from_pyramidget_laf_center	scale_laf)LAFOrienterOriNetPassLAF)BlobDoG
CornerGFTT)ScaleSpaceDetector)SIFTDescriptor    T)imglafspatch_descriptor
patch_sizegrayscale_descriptorreturnc                 C   s   t | || }|  | }|jd dkrZtd|j d t|jd |jd dS |rt| ddkrtt	| }t
|||}| \}}}	}
}|||| |	|
|||dS )aW  Function to get local descriptors, corresponding to LAFs (keypoints).

    Args:
        img: image features with shape :math:`(B,C,H,W)`.
        lafs: local affine frames :math:`(B,N,2,3)`.
        patch_descriptor: patch descriptor module, e.g. :class:`~kornia.feature.SIFTDescriptor`
            or :class:`~kornia.feature.HardNet`.
        patch_size: patch size in pixels, which descriptor expects.
        grayscale_descriptor: True if ``patch_descriptor`` expects single-channel image.

    Returns:
        Local descriptors of shape :math:`(B,N,D)` where :math:`D` is descriptor size.
    r
   r   zLAF contains no keypoints z, returning empty tensor      )r	   toevalshapewarningswarntorchemptysizer   r   view)r   r   r   r   r   ZtimgZpatchesBNZCHHW r/   b/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/feature/integrated.pyget_laf_descriptors   s    
r1   c                       sZ   e Zd ZdZdeej eedd fddZ	e
dd	d
ZejejejdddZ  ZS )LAFDescriptora  Module to get local descriptors, corresponding to LAFs (keypoints).

    Internally uses :func:`~kornia.feature.get_laf_descriptors`.

    Args:
        patch_descriptor_module: patch descriptor module, e.g. :class:`~kornia.feature.SIFTDescriptor`
            or :class:`~kornia.feature.HardNet`. Default: :class:`~kornia.feature.HardNet`.
        patch_size: patch size in pixels, which descriptor expects.
        grayscale_descriptor: ``True`` if patch_descriptor expects single-channel image.
    Nr   T)patch_descriptor_moduler   r   r   c                    s0   t    |d u rtd}|| _|| _|| _d S )NT)super__init__r   
descriptorr   r   )selfr3   r   r   	__class__r/   r0   r5   H   s    
zLAFDescriptor.__init__)r   c                 C   sB   | j jd d | j  d d t| j d d t| j d S )N(zdescriptor=z, zpatch_size=zgrayscale_descriptor=))r9   __name__r6   __repr__strr   r   )r7   r/   r/   r0   r=   U   s,    	
zLAFDescriptor.__repr__)r   r   r   c                 C   s   t ||| j| j| jS )a  Three stage local feature detection.

        First the location and scale of interest points are determined by
        detect function. Then affine shape and orientation.

        Args:
            img: image features with shape :math:`(B,C,H,W)`.
            lafs: local affine frames :math:`(B,N,2,3)`.

        Returns:
            Local descriptors of shape :math:`(B,N,D)` where :math:`D` is descriptor size.
        )r1   r6   r   r   )r7   r   r   r/   r/   r0   forwardd   s    zLAFDescriptor.forward)Nr   T)r<   
__module____qualname____doc__r   nnModuleintboolr5   r>   r=   r'   Tensorr?   __classcell__r/   r/   r8   r0   r2   <   s      r2   c                       s\   e Zd ZdZd
ejeedd fddZde	j
ee	j
 ee	j
e	j
e	j
f ddd	Z  ZS )LocalFeaturea  Module, which combines local feature detector and descriptor.

    Args:
        detector: the detection module.
        descriptor: the descriptor module.
        scaling_coef: multiplier for change default detector scale (e.g. it is too small for KeyNet by default)
          ?N)detectorr6   scaling_coefr   c                    s6   t    || _|| _|dkr,td| || _d S )Nr   z!Scaling coef should be >= 0, got )r4   r5   rK   r6   
ValueErrorrL   )r7   rK   r6   rL   r8   r/   r0   r5   }   s    
zLocalFeature.__init__)r   maskr   c                 C   s2   |  ||\}}t|| j}| ||}|||fS )a  
        Args:
            img: image to extract features with shape :math:`(B,C,H,W)`.
            mask: a mask with weights where to apply the response function.
                The shape must be the same as the input image.

        Returns:
            - Detected local affine frames with shape :math:`(B,N,2,3)`.
            - Response function values for corresponding lafs with shape :math:`(B,N,1)`.
            - Local descriptors of shape :math:`(B,N,D)` where :math:`D` is descriptor size.
        )rK   r   rL   r6   )r7   r   rN   r   	responsesZdescsr/   r/   r0   r?      s    zLocalFeature.forward)rJ   )N)r<   r@   rA   rB   rC   rD   r2   floatr5   r'   rG   r   r   r?   rH   r/   r/   r8   r0   rI   t   s   	 rI   c                       s>   e Zd ZdZdddedfeeeejd fddZ  Z	S )	SIFTFeaturezConvenience module, which implements DoG detector + (Root)SIFT descriptor.

    Still not as good as OpenCV/VLFeat because of https://github.com/kornia/kornia/pull/884, but we are working on it
    @  FTcpu)num_featuresuprightrootsiftdevicec              
      sp   d}t |t tdtddddd|r*t ntdddd	d
|}tt||d|dd|}t	 
|| d S )N)   
   r    皙?r   TZdouble_image         @)resp_module
nms_modulescale_pyr_module
ori_moduleZscale_space_responseZminima_are_also_goodmr_size)r   rV   r   r   )r   r   r   r   r   r   r"   r2   r   r4   r5   )r7   rT   rU   rV   rW   r   rK   r6   r8   r/   r0   r5      s&    	
zSIFTFeature.__init__
r<   r@   rA   rB   r'   rW   rE   rF   r5   rH   r/   r/   r8   r0   rQ      s   rQ   c                       s:   e Zd ZdZddedfeeejd fddZ  Z	S )GFTTAffNetHardNetzOConvenience module, which implements GFTT detector + AffNet-HardNet descriptor.rR   FrS   )rT   rU   rW   c              
      sl   t |t tddtddddd|r(t ntdtd	 d
d|}t	d dd	d|}t
 || d S )NrY   gh㈵>r    rZ   r   Fr[   r\   Tr]   )r^   r_   r`   ra   
aff_modulerb   rc   )r   r   r   r   r   r   r   r#   r"   r2   r4   r5   )r7   rT   rU   rW   rK   r6   r8   r/   r0   r5      s    
	zGFTTAffNetHardNet.__init__rd   r/   r/   r8   r0   re      s   re   c                       s>   e Zd ZdZddeddfeeejed fddZ	  Z
S )	KeyNetHardNetzJConvenience module, which implements KeyNet detector + HardNet descriptor.rR   FrS   rJ   rT   rU   rW   r   c                    sT   |r
t  nttdd}td||d|}td ddd|}t ||| d S )NTZangle_detector)rT   ra   r   rc   )r   r   r   r   r"   r2   r4   r5   r7   rT   rU   rW   r   ra   rK   r6   r8   r/   r0   r5      s    zKeyNetHardNet.__init__r<   r@   rA   rB   r'   rW   rE   rF   rP   r5   rH   r/   r/   r8   r0   rg      s   rg   c                       s>   e Zd ZdZddeddfeeejed fddZ	  Z
S )	KeyNetAffNetHardNetzSConvenience module, which implements KeyNet detector + AffNet + HardNet descriptor.rR   FrS   rJ   rh   c                    s^   |r
t  nttdd}td||td d|}td ddd|}t 	||| d S )NTri   )rT   ra   rf   r   rc   )
r   r   r   r   r   r#   r"   r2   r4   r5   rj   r8   r/   r0   r5      s    zKeyNetAffNetHardNet.__init__rk   r/   r/   r8   r0   rl      s   rl   c                       s   e Zd ZdZejejdd fddZdeje	ej e
eejf dddZejejed	d
dZe
eejf e
eejf dddZ  ZS )LocalFeatureMatchera  Module, which finds correspondences between two images based on local features.

    Args:
        local_feature: Local feature detector. See :class:`~kornia.feature.GFTTAffNetHardNet`.
        matcher: Descriptor matcher, see :class:`~kornia.feature.DescriptorMatcher`.

    Returns:
        Dict[str, torch.Tensor]: 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}
        >>> gftt_hardnet_matcher = LocalFeatureMatcher(
        ...     GFTTAffNetHardNet(10), kornia.feature.DescriptorMatcher('snn', 0.8)
        ... )
        >>> out = gftt_hardnet_matcher(input)
    N)local_featurematcherr   c                    s"   t    || _|| _|   d S )N)r4   r5   rn   ro   r#   )r7   rn   ro   r8   r/   r0   r5      s    
zLocalFeatureMatcher.__init__)imagerN   r   c                 C   s   |  ||\}}}|||dS )z2Function for feature extraction from simple image.)r   rO   descriptors)rn   )r7   rp   rN   lafs0Zresps0descs0r/   r/   r0   extract_features  s    z$LocalFeatureMatcher.extract_features)rW   dtyper   c                 C   sl   t jdd||dt jdd||dt jdddd||dt jdddd||dt jd||dt jd|t jddS )Nr      rW   ru   r    
keypoints0
keypoints1rr   lafs1
confidenceZbatch_indexes)r'   r(   long)r7   rW   ru   r/   r/   r0   no_match_output	  s    z#LocalFeatureMatcher.no_match_output)datar   c              	   C   sh  |d j d }d| vs&d| vrH| |d }|d |d  }}n|d |d  }}d| vsrd| vr| |d	 }|d |d  }}n|d |d  }}t|}	t|}
g }g }g }g }g }g }t|D ]}| || || \}}t|dkrq|	||d
d
df f }|
||d
d
df f }|||d
d
df f }|||d
d
df f }|d|  |tj	t||	j
tjd }|| || || || || qt|dkr| |d j
|d jS tj|ddddtj|ddddtj|ddddddtj|ddddddtj|dddtj|dddd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)`.
            - ``lafs0``, matching LAFs from image0 :math:`(1, NC, 2, 3)`.
            - ``lafs1``, matching LAFs from image1 :math:`(1, NC, 2, 3)`.
            - ``batch_indexes``, batch indexes for the keypoints and lafs :math:`(NC)`.
        Zimage0r   rr   Zdescriptors0r   rq   r{   Zdescriptors1Zimage1Nr
   rJ   rw   )Zdimr!   rv   r    rx   )r$   keysrt   r   rangero   lenappendr'   ZonesrW   r}   r~   ru   catr*   )r7   r   Znum_image_pairsZfeats_dict0rr   rs   Zfeats_dict1r{   Zdescs1ry   rz   Zout_keypoints0Zout_keypoints1Zout_confidenceZout_batch_indexesZ	out_lafs0Z	out_lafs1Z	batch_idxdistsZidxsZcurrent_keypoints_0Zcurrent_keypoints_1Zcurrent_lafs_0Zcurrent_lafs_1Z
batch_idxsr/   r/   r0   r?     sR    



zLocalFeatureMatcher.forward)N)r<   r@   rA   rB   rC   rD   r5   r'   rG   r   r   r>   rt   rW   ru   dictr~   r?   rH   r/   r/   r8   r0   rm      s
   &
rm   )r   T)2r%   typingr   r   r   r   r'   Ztorch.nnrC   Zkornia.colorr   Zkornia.geometry.subpixr   Zkornia.geometry.transformr   Zkornia.testingr	   Zaffine_shaper   Zhardnetr   Zkeynetr   Zlafr   r   r   Zorientationr   r   r   rO   r   r   Zscale_space_detectorr   Zsiftdescr   rG   rD   rE   rF   r1   r2   rI   rQ   re   rg   rl   rm   r/   r/   r/   r0   <module>   s@     &8%