o
    oi8                     @   s8  d Z ddlZddlZddlmZmZmZmZmZm	Z	m
Z
mZ ddlZddlm  mZ ddlmZ ddlmZmZ ddlmZmZ G dd deZG d	d
 d
eZG dd deZG dd deZG dd deZG dd deZdedefddZG dd deZG dd deZG dd deZG dd deZ dS )z%Implements several backbone networks.    N)AnyDictList
NamedTupleOptionalTupleTypeUnion)nn)pixel_shufflesoftmax)ModuleTensorc                   @   sB   e Zd ZU eed< eed< eed< eed< eed< ee ed< dS )HourglassConfigdepth
num_stacks
num_blocksnum_classesinput_channelsheadN)__name__
__module____qualname__int__annotations__r   r    r   r   R/home/ubuntu/.local/lib/python3.10/site-packages/kornia/feature/sold2/backbones.pyr       s   
 r   c                       sP   e Zd ZdZ	ddededed	ed
eddf fddZdedefddZ  ZS )HourglassBackbonea  Hourglass network, taken from https://github.com/zhou13/lcnn.

    Args:
        input_channel: number of input channels.
        depth: number of residual blocks per hourglass module.
        num_stacks: number of hourglass modules stacked together.
        num_blocks: number of layers in each residual block.
        num_classes: number of heads for the output of a hourglass module.

                input_channelr   r   r   r   returnNc              	      s0   t    t| _tt|||||| jd| _d S )N)r   )super__init__MultitaskHeadr   hgr   net)selfr"   r   r   r   r   	__class__r   r   r%   6   s   
 zHourglassBackbone.__init__input_imagesc                 C   s
   |  |S N)r(   )r)   r,   r   r   r   forward=   s   
zHourglassBackbone.forward)r   r   r    r   r!   	r   r   r   __doc__r   r%   r   r.   __classcell__r   r   r*   r   r   *   s"    r   c                       s8   e Zd Zdeddf fddZdedefddZ  ZS )	r&   r   r#   Nc                    s   t    t|d }dgdgdgg}g }ttj|g }|D ]}|t	tj
||dddtjddtj
||dd qt|| _d S )	Nr   r    r      )kernel_sizepaddingTinplacer3   )r$   r%   r   	functoolsreduceoperatoriconcatappendr
   
SequentialConv2dReLU
ModuleListheads)r)   r   m	head_sizerA   _iteroutput_channelsr*   r   r   r%   B   s   

zMultitaskHead.__init__xc                    s   t j fdd| jD ddS )Nc                    s   g | ]}| qS r   r   ).0r   rF   r   r   
<listcomp>T   s    z)MultitaskHead.forward.<locals>.<listcomp>r   dim)torchcatrA   r)   rF   r   rH   r   r.   S   s   zMultitaskHead.forward)r   r   r   r   r%   r   r.   r1   r   r   r*   r   r&   A   s    r&   c                       s\   e Zd Z	ddededeeeeef f dee ddf
 fdd	Zd
e	de	fddZ
  ZS )Bottleneck2Dr   Ninplanesplanesstride
downsampler#   c                    s   t    t|| _tj||dd| _t|| _tj||d|dd| _t|| _	tj||d dd| _
tjdd| _|| _|| _d S )Nr   r7   r2   r3   rR   r4   r    Tr5   )r$   r%   r
   BatchNorm2dbn1r>   conv1bn2conv2bn3conv3r?   relurS   rR   )r)   rP   rQ   rR   rS   r*   r   r   r%   X   s   

zBottleneck2D.__init__rF   c                 C   s~   |}|  |}| |}| |}| |}| |}| |}| |}| |}| |}| jd ur9| |}||7 }|S r-   )rV   r\   rW   rX   rY   rZ   r[   rS   )r)   rF   residualoutr   r   r   r.   g   s   










zBottleneck2D.forward)r   N)r   r   r   r   r	   r   r   r   r%   r   r.   r1   r   r   r*   r   rO   W   s    rO   c                       s   e Zd Zddee dededededdf fd	d
Zdee dededefddZdee dededede	j
f
ddZdededefddZdedefddZ  ZS )	Hourglassr    blockr   rQ   r   	expansionr#   Nc                    s2   t    || _|| _|| _| ||||| _d S r-   )r$   r%   r   r`   ra   _make_hour_glassr'   )r)   r`   r   rQ   r   ra   r*   r   r   r%      s
   
zHourglass.__init__c                 C   s4   g }t d|D ]}|||| j | qtj| S )Nr   )ranger<   ra   r
   r=   )r)   r`   r   rQ   layers_r   r   r   _make_residual   s   
zHourglass._make_residualc           	   	   C   sn   g }t |D ]+}g }t dD ]}|| ||| q|dkr)|| ||| |t| qt|S )Nr2   r   )rc   r<   rf   r
   r@   )	r)   r`   r   rQ   r   hgliresre   r   r   r   rb      s   
zHourglass._make_hour_glassnrF   c           	      C   s   | j |d  d |}tj|ddd}| j |d  d |}|dkr+| |d |}n| j |d  d |}| j |d  d |}tj||jdd  d}|| }|S )Nr   r   r    rR   r2   )size)r'   F
max_pool2d_hour_glass_forwardinterpolateshape)	r)   rj   rF   up1low1low2low3up2r^   r   r   r   ro      s   zHourglass._hour_glass_forwardc                 C   s   |  | j|S r-   )ro   r   rN   r   r   r   r.      s   zHourglass.forwardr    )r   r   r   r   rO   r   r%   r   rf   r
   r@   rb   r   ro   r.   r1   r   r   r*   r   r_   ~   s    ,$r_   c                       s   e Zd ZdZ	ddee dee dedededed	ed
eddf fddZ	ddee dedede	ee
eef f def
ddZdededefddZdedefddZ  ZS )HourglassNetz,Hourglass model from Newell et al ECCV 2016.r    r`   r   r   r   r   r   r   ra   r#   Nc	                    s  t    d| _d| _|| _|| _tj|| jdddd| _t	| j| _
tjdd| _| || jd	| _| || jd	| _| || jd	| _tjddd
| _| j| j }	g g g g g g f\}
}}}}}t|D ]D}|
t||| j| || || j| || |	|	 |||	 ||d	 k r|tj|	|	d	d |tj||	d	d qft|
| _t|| _t|| _t|| _t|| _t|| _d S )N@         r    r2   rT   Tr5   r   rk   r7   )r$   r%   rP   	num_featsr   ra   r
   r>   rW   rU   rV   r?   r\   rf   layer1layer2layer3	MaxPool2dmaxpoolrc   r<   r_   _make_fcr@   r'   ri   fcscorefc_score_)r)   r`   r   r   r   r   r   r   ra   chrg   ri   r   r   r   r   rh   r*   r   r   r%      s:   
zHourglassNet.__init__r   rQ   blocksrR   c                 C   s   d }|dks| j || j krttj| j || j d|d}g }||| j ||| || j | _ td|D ]}||| j | q6tj| S )Nr   )r3   rR   )rP   ra   r
   r=   r>   r<   rc   )r)   r`   rQ   r   rR   rS   rd   re   r   r   r   rf      s    
zHourglassNet._make_residualrP   	outplanesc                 C   s*   t |}t j||dd}t ||| jS )Nr   r7   )r
   rU   r>   r=   r\   )r)   rP   r   bnconvr   r   r   r      s   
zHourglassNet._make_fcrF   c                 C   s   g }|  |}| |}| |}| |}| |}| |}| |}t| jD ]>}| j	| |}| j
| |}| j| |}| j| |}|| || jd k rh| j| |}| j| |}|| | }q*|S )Nr   )rW   rV   r\   r}   r   r~   r   rc   r   r'   ri   r   r   r<   r   r   )r)   rF   r^   rh   yr   r   r   r   r   r   r.      s(   







zHourglassNet.forwardrw   )r   )r   r   r   r0   r   rO   r   r   r%   r	   r   rf   r   r   r.   r1   r   r   r*   r   rx      sH    	
,
rx   cfgr#   c              	   C   s"   t t| j| j| j| j| j| jdS )zCreate HourglassNet.)r   r   r   r   r   r   )rx   rO   r   r   r   r   r   r   )r   r   r   r   r'     s   r'   c                       sB   e Zd ZdZddededdf fdd	Zd
edefddZ  ZS )SuperpointDecoderzJunction decoder based on the SuperPoint architecture.

    Args:
        input_feat_dim: channel size of the input features.

    Returns:
        the junction heatmap, with shape (B, H, W).

    rz      input_feat_dim	grid_sizer#   Nc                    sN   t    tjdd| _tj|ddddd| _tjddddd	d| _|| _d S )
NTr5      r2   r    r   rT   A   r   )	r$   r%   r
   r?   r\   r>   convPaconvPbr   )r)   r   r   r*   r   r   r%     s
   

zSuperpointDecoder.__init__input_featuresc                 C   s^   |  | |}| |}t|dd}t|d d d dd d d d f | jd d df }|S )Nr   rJ   r   )r\   r   r   r   r   r   )r)   r   featsemi	junc_prob	junc_predr   r   r   r.   %  s
   
4zSuperpointDecoder.forward)rz   r   r/   r   r   r*   r   r     s    
r   c                	       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e fddZdedefddZ	  Z
S )PixelShuffleDecodera$  Pixel shuffle decoder used to predict the line heatmap.

    Args:
        input_feat_dim: channel size of the input features.
        num_upsample: how many upsamples are performed.
        output_channel: number of output channels.

    Returns:
        the (B, 1, H, W) line heatmap.

    rz   r    r   num_upsampleoutput_channelr#   Nc                    s   t    | || _td| _g }|ttj	|| jd ddddt
| jd tjdd | jdd D ]}|ttj	||ddddt
|tjdd q9|ttj	| jd |dddd t|| _d S )	Nr    r   r2   r   rT   Tr5   r   )r$   r%   get_channel_confchannel_confr
   PixelShuffle
pixshuffler<   r=   r>   rU   r?   r@   conv_block_lst)r)   r   r   r   r   channelr*   r   r   r%   <  s.   

	
	zPixelShuffleDecoder.__init__c                 C   s   |dkrg dS g dS )z2Get num of channels based on number of upsampling.r    )r   ry      )r   ry   r   r   r   )r)   r   r   r   r   r   _  s   z$PixelShuffleDecoder.get_channel_confr   c                 C   s`   |}| j d d D ]}||}| |}q	| j d |}t|ddd d dd d d d f }|S )Nr   r   rJ   )r   r   r   )r)   r   r^   r`   heatmapr   r   r   r.   e  s   $zPixelShuffleDecoder.forward)rz   r    r    )r   r   r   r0   r   r%   r   r   r   r.   r1   r   r   r*   r   r   /  s
     #r   c                       s>   e Zd ZdZddeddf fddZdedefd	d
Z  ZS )SuperpointDescriptorzDescriptor decoder based on the SuperPoint arcihtecture.

    Args:
        input_feat_dim: channel size of the input features.

    Returns:
        the semi-dense descriptors with shape (B, 128, H/4, W/4).

    rz   r   r#   Nc                    sH   t    tjdd| _tj|ddddd| _tjdddddd| _d S )	NTr5   r   r2   r   rT   rz   r   )r$   r%   r
   r?   r\   r>   r   r   )r)   r   r*   r   r   r%   ~  s   
zSuperpointDescriptor.__init__r   c                 C   s   |  | |}| |}|S r-   )r\   r   r   )r)   r   r   r   r   r   r   r.     s   
zSuperpointDescriptor.forward)rz   r/   r   r   r*   r   r   s  s    
r   c                       sL   e Zd ZdZdeeef ddf fddZdedeeef fdd	Z	  Z
S )
SOLD2Netu  Full network for SOLD².

    Args:
        model_cfg: the configuration as a Dict.

    Returns:
        a Dict with the following values:
            junctions: heatmap of junctions.
            heatmap: line heatmap.
            descriptors: semi-dense descriptors.

    	model_cfgr#   Nc                    sf   t    || _tdi | jd | _d}t|| jd | _t|dd| _d| jv r1t	|| _
d S d S )Nbackbone_cfgr   r   r    )r   use_descriptorr   )r$   r%   r   r   backbone_netr   junction_decoderr   heatmap_decoderr   descriptor_decoder)r)   r   feat_channelr*   r   r   r%     s   

zSOLD2Net.__init__r,   c                 C   sD   |  |}| |}| |}||d}d| jv r | ||d< |S )N)	junctionsr   r   descriptors)r   r   r   r   r   )r)   r,   featuresr   heatmapsoutputsr   r   r   r.     s   




zSOLD2Net.forward)r   r   r   r0   r   strr   r%   r   r.   r1   r   r   r*   r   r     s    "r   )!r0   r8   r:   typingr   r   r   r   r   r   r   r	   rL   torch.nn.functionalr
   
functionalrm   r   r   kornia.corer   r   r   r   r&   rO   r_   rx   r'   r   r   r   r   r   r   r   r   <module>   s(   (
'+[D