o
    oi                     @   s   U d dl mZ d dlZd dlm  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ed< G dd dejZG dd dejZdS )    )DictN)nn)KORNIA_CHECK_SHAPE)is_mps_tensor_safeurlsz]https://github.com/DagnyT/hardnet/raw/master/pretrained/pretrained_all_datasets/HardNet++.pthz	hardnet++znhttps://github.com/DagnyT/hardnet/raw/master/pretrained/train_liberty_with_aug/checkpoint_liberty_with_aug.pthliberty_augz/http://cmp.felk.cvut.cz/~mishkdmy/hardnet8v2.pt
hardnet8v2c                       sf   e Zd ZdZdZddeddf fddZedd
ej	de
dej	fddZdej	dej	fddZ  ZS )HardNeta~  Module, which computes HardNet descriptors of given grayscale patches of 32x32.

    This is based on the original code from paper "Working hard to know your neighbor's
    margins: Local descriptor learning loss". See :cite:`HardNet2017` for more details.

    Args:
        pretrained: Download and set pretrained weights to the model.

    Returns:
        torch.Tensor: HardNet descriptor of the patches.

    Shape:
        - Input: :math:`(B, 1, 32, 32)`
        - Output: :math:`(B, 128)`

    Examples:
        >>> input = torch.rand(16, 1, 32, 32)
        >>> hardnet = HardNet()
        >>> descs = hardnet(input) # 16x128

        F
pretrainedreturnNc                    sP  t    ttjddddddtjdddt tjddddddtjdddt tjddddddd	tjdddt tjddddddtjdddt tjdd
ddddd	tjd
ddt tjd
d
ddddtjd
ddt tdtjd
d
dddtjd
dd| _|rt	j
jtd t	dd}| j|d dd |   d S )N   r
      Fkernel_sizepaddingbiasaffine@      r   strider   r      333333?   r   r   r   cpumap_location
state_dictTstrict)super__init__r   
SequentialConv2dBatchNorm2dReLUDropoutfeaturestorchhubload_state_dict_from_urlr   deviceload_state_dictevalselfr   pretrained_dict	__class__ J/home/ubuntu/.local/lib/python3.10/site-packages/kornia/feature/hardnet.pyr$   <   s8   
zHardNet.__init__ư>xepsc                 C   V   t | stj| ddd\}}ntj| ddd}tj| ddd}| |  | |  S zNormalize the input by batch.)T)dimkeepdimr   r+   std_meanmeanstddetachr9   r:   spmpr6   r6   r7   _normalize_input\   
   zHardNet._normalize_inputinputc                 C   sB   t |g d | |}| |}||dd}tj|ddS N)B132rP   r   r?   r   )r@   )r   rJ   r*   viewsizeF	normalize)r2   rL   x_norm
x_featuresx_outr6   r6   r7   forwardi   s
   

zHardNet.forwardF)r8   )__name__
__module____qualname____doc__
patch_sizeboolr$   staticmethodr+   TensorfloatrJ   rX   __classcell__r6   r6   r4   r7   r	   #   s     r	   c                       s|   e Zd ZdZdZddeddf fddZed	eddfd
dZ	edde
jdede
jfddZde
jde
jfddZ  ZS )HardNet8aU  Module, which computes HardNet8 descriptors of given grayscale patches of 32x32.

    This is based on the original code from paper "Improving the HardNet Descriptor".
    See :cite:`HardNet2020` for more details.

    Args:
        pretrained: Download and set pretrained weights to the model.

    Returns:
        torch.Tensor: HardNet8 descriptor of the patches.

    Shape:
        - Input: :math:`(B, 1, 32, 32)`
        - Output: :math:`(B, 128)`

    Examples:
        >>> input = torch.rand(16, 1, 32, 32)
        >>> hardnet = HardNet8()
        >>> descs = hardnet(input) # 16x128

    r
   Fr   r   Nc                    s  t    ttjddddddtjdddt tjddddddtjdddt tjddddddd	tjdddt tjddddddtjdddt tjdd
ddddd	tjd
ddt tjd
d
ddddtjd
ddt tjd
dddddtjdddt tdtjdddddtjddd| _| j	| j
 | dtjdd
tjd | dtjdtjd |rtjjtd tdd}| j|dd |   d S )Nr   r
   r   Fr   r   r   r   r   r      r   i   r   r   
components)dtyperD   r   r   r   Tr!   )r#   r$   r   r%   r&   r'   r(   r)   r*   applyweights_initregister_bufferr+   onesrb   zerosr,   r-   r   r.   r/   r0   r1   r4   r6   r7   r$      sD   
zHardNet8.__init__mc                 C   sH   t | tjr tjj| jjdd | jd ur"tj| jjd d S d S d S )Ng333333?)gaing{Gz?)	
isinstancer   r&   initorthogonal_weightdatar   	constant_)rm   r6   r6   r7   ri      s   
zHardNet8.weights_initHz>r9   r:   c                 C   r;   r<   rB   rG   r6   r6   r7   rJ      rK   zHardNet8._normalize_inputrL   c                 C   s|   t |g d | |}| |}tjtj| j}tjtj| j}t	
||dd}t|| |}t	j
|ddS rM   )r   rJ   r*   r+   jitannotatera   rD   rf   rS   rT   rQ   rR   mm)r2   rL   rU   rV   rD   rf   x_prePCApcar6   r6   r7   rX      s   

zHardNet8.forwardrY   )ru   )rZ   r[   r\   r]   r^   r_   r$   r`   objectri   r+   ra   rb   rJ   rX   rc   r6   r6   r4   r7   rd   q   s    &rd   )typingr   r+   torch.nn.functionalr   
functionalrS   kornia.core.checkr   kornia.utils.helpersr   r   str__annotations__Moduler	   rd   r6   r6   r6   r7   <module>   s   N