a
    þdR  ã                   @   sz   d dl Z d dl mZ d dlmZ d dlmZ ddlmZ G dd„ dej	ƒZ
G d	d
„ d
ej	ƒZe ¡ G dd„ dej	ƒƒZdS )é    N)Únn)Ú
functional)ÚARCH_REGISTRYé   )Ú	flow_warpc                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )ÚBasicModulezŽBasic module of SPyNet.

    Note that unlike the architecture in spynet_arch.py, the basic module
    here contains batch normalization.
    c                    sÆ   t t| ƒ ¡  t tjdddddddt d¡tjdd	tjdd
dddddt d
¡tjdd	tjd
ddddddt d¡tjdd	tjdddddddt d¡tjdd	tjdddddd¡| _d S )Né   é    é   r   é   F)Úin_channelsÚout_channelsÚkernel_sizeÚstrideÚpaddingZbiasT©Zinplaceé@   é   é   )r   r   r   r   r   )	Úsuperr   Ú__init__r   Z
SequentialÚConv2dZBatchNorm2dÚReLUÚbasic_module)Úself©Ú	__class__© ú_/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/archs/tof_arch.pyr      s    ÷zBasicModule.__init__c                 C   s
   |   |¡S )a  
        Args:
            tensor_input (Tensor): Input tensor with shape (b, 8, h, w).
                8 channels contain:
                [reference image (3), neighbor image (3), initial flow (2)].

        Returns:
            Tensor: Estimated flow with shape (b, 2, h, w)
        )r   )r   Ztensor_inputr   r   r   Úforward   s    
zBasicModule.forward©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú__classcell__r   r   r   r   r   	   s   r   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )Ú	SPyNetTOFa/  SPyNet architecture for TOF.

    Note that this implementation is specifically for TOFlow. Please use
    spynet_arch.py for general use. They differ in the following aspects:
        1. The basic modules here contain BatchNorm.
        2. Normalization and denormalization are not done here, as
            they are done in TOFlow.
    Paper:
        Optical Flow Estimation using a Spatial Pyramid Network
    Code reference:
        https://github.com/Coldog2333/pytoflow

    Args:
        load_path (str): Path for pretrained SPyNet. Default: None.
    Nc                    sL   t t| ƒ ¡  t dd„ tdƒD ƒ¡| _|rH|  tj	|dd„ dd ¡ d S )Nc                 S   s   g | ]
}t ƒ ‘qS r   )r   )Ú.0Ú_r   r   r   Ú
<listcomp>>   ó    z&SPyNetTOF.__init__.<locals>.<listcomp>é   c                 S   s   | S ©Nr   )ZstorageÚlocr   r   r   Ú<lambda>@   r*   z$SPyNetTOF.__init__.<locals>.<lambda>)Zmap_locationÚparams)
r   r&   r   r   Z
ModuleListÚranger   Zload_state_dictÚtorchÚload)r   Z	load_pathr   r   r   r   ;   s    zSPyNetTOF.__init__c           
      C   sä   |  ¡ \}}}}|g}|g}tdƒD ]@}| dtj|d dddd¡ | dtj|d dddd¡ q$|d  |d|d |d ¡}tdƒD ]T}tj|ddd	d
d }	|	| j| t 	|| t
|| |	 dddd¡ƒ|	gd¡ƒ }qŠ|S )zì
        Args:
            ref (Tensor): Reference image with shape of (b, 3, h, w).
            supp: The supporting image to be warped: (b, 3, h, w).

        Returns:
            Tensor: Estimated optical flow: (b, 2, h, w).
        r   r   r   F)Úinputr   r   Zcount_include_padr   r+   ZbilinearT)r3   Zscale_factorÚmodeZalign_cornersg       @r   )Úsizer0   ÚinsertÚFZ
avg_pool2dZ	new_zerosZinterpolater   r1   Úcatr   Úpermute)
r   ÚrefZsuppÚnum_batchesr(   ÚhÚwÚflowÚiZflow_upr   r   r   r   B   s    	 
*ÿzSPyNetTOF.forward)Nr    r   r   r   r   r&   *   s   r&   c                       s:   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zd	d
„ Z‡  ZS )ÚTOFlowa"  PyTorch implementation of TOFlow.

    In TOFlow, the LR frames are pre-upsampled and have the same size with
    the GT frames.
    Paper:
        Xue et al., Video Enhancement with Task-Oriented Flow, IJCV 2018
    Code reference:
        1. https://github.com/anchen1011/toflow
        2. https://github.com/Coldog2333/pytoflow

    Args:
        adapt_official_weights (bool): Whether to adapt the weights translated
            from the official implementation. Set to false if you want to
            train from scratch. Default: False
    Fc              	      sÈ   t t| ƒ ¡  || _|rdnd| _|  dt g d¢¡ dddd¡¡ |  dt g d¢¡ dddd¡¡ t	ƒ | _
t dd	d
dd¡| _t d	d	d
dd¡| _t d	d	d¡| _t d	dd¡| _tjdd| _d S )Nr   r   Úmean)g
×£p=
ß?gÉv¾Ÿ/Ý?g–C‹lçûÙ?r   Ústd)gZd;ßOÍ?gyé&1¬Ì?gÍÌÌÌÌÌÌ?é   r   é	   r+   Tr   )r   r@   r   Úadapt_official_weightsÚref_idxZregister_bufferr1   ZTensorÚviewr&   Úspynetr   r   Úconv_1Úconv_2Úconv_3Úconv_4r   Úrelu)r   rE   r   r   r   r   o   s    ""zTOFlow.__init__c                 C   s   || j  | j S r,   )rA   rB   ©r   Úimgr   r   r   Ú	normalizeƒ   s    zTOFlow.normalizec                 C   s   || j  | j S r,   )rB   rA   rN   r   r   r   Údenormalize†   s    zTOFlow.denormalizec                 C   sb  | j r,|dd…g d¢dd…dd…dd…f }| ¡ \}}}}}|  | dd||¡¡}| ||d||¡}|dd…| jdd…dd…dd…f }g }tdƒD ]d}	|	| jkr°| |¡ q–|dd…|	dd…dd…dd…f }
|  ||
¡}| t|
| 	dddd¡ƒ¡ q–t
j|dd	}| |d||¡}|  |  |¡¡}|  |  |¡¡}|  |  |¡¡}|  |¡| }|  |¡S )
zˆ
        Args:
            lrs: Input lr frames: (b, 7, 3, h, w).

        Returns:
            Tensor: SR frame: (b, 3, h, w).
        N)r   r   r   r   r+   é   é   éÿÿÿÿr   r
   r   r   r   )Zdim)rE   r5   rP   rG   rF   r0   ÚappendrH   r   r9   r1   ÚstackrM   rI   rJ   rK   rL   rQ   )r   Zlrsr;   Znum_lrsr(   r<   r=   Zlr_refZ
lr_alignedr?   Zlr_suppr>   Úhrr   r   r   r   ‰   s(    	&$
"zTOFlow.forward)F)	r!   r"   r#   r$   r   rP   rQ   r   r%   r   r   r   r   r@   ]   s
   r@   )r1   r   Ztorch.nnr   r7   Zbasicsr.utils.registryr   Z	arch_utilr   ÚModuler   r&   Úregisterr@   r   r   r   r   Ú<module>   s   !3