o
    ߥiE                     @   s   d dl Z d dlZd dlZd dlmZ d dlm  mZ d dl	m
Z
 d dlmZ d dlmZmZ dd ZG dd dejZG d	d
 d
ejZG dd dejZG dd dejZdd ZG dd dejZG dd dejZG dd dejZdS )    N)Models)MODELS)	ModelFileTasksc                    sp   t   dd  }t fdd|D }t|} fddt|D }dd t|t|D }tj|ddS )N   c                    s   g | ]
}t j| jd qS ))device)torcharanger   ).0sizeoffset ]/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/cv/virual_tryon/sdafnet.py
<listcomp>   s    z apply_offset.<locals>.<listcomp>c                    s0   g | ]\}}|  d  dd|df  qS )r   N.)float	unsqueeze)r
   dimgridr   r   r   r      s    c                 S   s$   g | ]\}}||d  d  d  qS )g      ?g       @r   )r
   r   r   r   r   r   r      s    r   )listr   r   meshgridreversed	enumeratezipstack)r   sizes	grid_listr   r   r   apply_offset   s   
r   c                       $   e Zd Z fddZdd Z  ZS )ResBlockc                    sd   t t|   tt|tjddtj||ddddt|tjddtj||dddd| _d S )NTinplace      F)kernel_sizepaddingbias)	superr!   __init__nn
SequentialBatchNorm2dReLUConv2dblock)selfin_channels	__class__r   r   r*   #   s   

zResBlock.__init__c                 C   s   |  || S Nr0   r1   xr   r   r   forward/   s   zResBlock.forward__name__
__module____qualname__r*   r9   __classcell__r   r   r3   r   r!   !       r!   c                       r    )
Downsamplec                    sB   t t|   tt|tjddtj||ddddd| _d S )NTr"   r$   r   r%   F)r&   strider'   r(   )	r)   r@   r*   r+   r,   r-   r.   r/   r0   )r1   r2   out_channelsr3   r   r   r*   5   s   
zDownsample.__init__c                 C   
   |  |S r5   r6   r7   r   r   r   r9   A      
zDownsample.forwardr:   r   r   r3   r   r@   3   r?   r@   c                       s,   e Zd Zg df fdd	Zdd Z  ZS )FeatureEncoder@         rI   rI   c                    s   t t|   g | _t|D ]/\}}|dkr%tt||t|t|}ntt||d  |t|t|}| j	| qt
| j| _d S )Nr   r%   )r)   rE   r*   encodersr   r+   r,   r@   r!   append
ModuleList)r1   r2   chnsiout_chnsencoderr3   r   r   r*   G   s   zFeatureEncoder.__init__c                 C   s&   g }| j D ]}||}|| q|S r5   )rJ   rK   )r1   r8   encoder_featuresrP   r   r   r   r9   Y   s
   
zFeatureEncoder.forwardr:   r   r   r3   r   rE   E   s    rE   c                       s.   e Zd Zg ddf fdd	Zdd Z  ZS )RefinePyramidrF   rI   c                    s   t t|   || _g | _tt|D ]}tj||dd}| j	| qt
| j| _g | _tt|D ]}tj||ddd}| j	| q4t
| j| _d S )Nr%   )r&   r$   )r&   r'   )r)   rR   r*   rM   adaptiver   r   r+   r/   rK   rL   smoothrangelen)r1   rM   fpn_dimin_chnsadaptive_layerrN   smooth_layerr3   r   r   r*   c   s   zRefinePyramid.__init__c                 C   sx   |}g }d }t tt|D ]'\}}| j| |}|d ur'|tj|ddd }| j| |}|}|| qtt|S )Nr   nearestscale_factormode)	r   r   r   rS   FinterpolaterT   rK   tuple)r1   r8   conv_ftr_listfeature_listlast_featurerN   conv_ftrfeaturer   r   r   r9   u   s   zRefinePyramid.forwardr:   r   r   r3   r   rR   a   s    rR   c                 C   sx   t ||d}|  \}}}}t | |d}	tj|	| ddddddd}
|
|d||| }tt 	||d}|S )	Nr%   r   r   r$   bilinearborderr^   padding_moder   )
r   repeat_interleaver   r_   grid_sampledetachpermutereshapesumsplit)featoffsetsatt_mapssample_kout_chBCHW
multi_featmulti_warp_featmulti_att_warp_featatt_warp_featr   r   r   DAWarp   s   r   c                       s.   e Zd Zdg df fdd	Zdd Z  ZS )MFEBlockr$   )rH   rG       c              
      s   t t|   g }tt|D ]8}|dkr&|tjj||| dddd n|tjj||d  || |d|d d |tjj	ddd q|tjj|d	 ||d|d d tjj
| | _d S )
Nr   r$   r%   r2   rB   r&   rA   r'   r   F皙?r#   negative_sloper   )r)   r   r*   rU   rV   rK   r   r+   r/   	LeakyReLUr,   layers)r1   r2   rB   r&   num_filtersr   rN   r3   r   r   r*      sF   
zMFEBlock.__init__c                 C   rC   r5   )r   )r1   inputr   r   r   r9      rD   zMFEBlock.forwardr:   r   r   r3   r   r      s
    #r   c                       s.   e Zd Zd	 fdd	Z			d
ddZ  ZS )	DAFlowNetrI   r%   c                    sP  t t|   g | _g | _g | _|| _|| _t|D ]6}t	d| | jd dd}t	d| | jd d}t	d| | jd d}| j
| | j
| | j
| qt| j| _t| j| _t| j| _tjtjjddd	d	d
tjjdddtjjdddd	d	d| _tjtjjdddd	d	dtjjdddtjjddd	d	d| _d S )Nr   r$      )r2   rB   r&   )r2   rB      rG   r   r%   )rB   r&   rA   Fr   r   r   )rB   r&   rA   r'   )r2   rB   r&   rA   )r)   r   r*   	Self_MFEs
Cross_MFEsRefine_MFEskrv   rU   r   rK   r+   rL   r   r,   r/   r   lights_decoderlights_encoder)r1   num_pyramidrW   	head_numsrN   Self_MFE_layerCross_MFE_layerRefine_MFE_layerr3   r   r   r*      sX   	

zDAFlowNet.__init__FTc           !      C   sJ  d}d}	|rg }
t t|D ]}|t|d |  }|t|d |  }| \}}}}|	durH|rHt||	|| j| j}t|||| j| j}n|}|}t||gd}| j| |}t	j
|dd| jd dddddf dd}t|ddd| jd ddddf dd||}|	durt	j|	|ddd}n|d	d
dd}|}	t||	|| j| j}t||gd}| j| |}t	j
|dd| jd dddddf dd}t|ddd| jd ddddf dd||}|durt	j||ddd}n|d	d
dd}|}t|||| j| j}t||gd}| j| |}t	j
|dd| jd dddddf dd}t|ddd| jd ddddf dd||}t|dd| jd | jd ddddf dd||}t	j|	|ddd}	t	j||ddd}t	j|	ddd}	t	j|ddd}t	j|ddd| jddddf ddd}t	j|dd| jdddddf ddd}|r&t	j||d |d fdd}t	j||d |d fdd}|r| |}| |}t||	|| jd}t|||| jd}| || } nt||	|| jd
}t|||| jd
}|| } |
|  qt	j|| dd dd}t	j|	| dd dd}	t	j|| dd dd}t	j|| dd dd}|r| |}| |}t||	|| jd}t|||| jd}| || } nt||	|| jd
}t|||| jd
}|| } |r| |fS | S )a  
        Args:
            source_image: cloth rgb image for tryon
            reference_image: model rgb image for try on
            source_feats: cloth FPN features
            reference_feats: model and pose features
            return_all: bool return all intermediate try-on results in training phase
            warp_feature: use DAFlow for both features and images
            use_light_en_de: use shallow encoder and decoder to project the images from RGB to high dimensional space

        Nr%   r   r   r   rg   rh   ri   r   r$      r\   )r^   rG   )rU   rV   r   r   r   rv   r   catr   r_   softmaxr   ro   rl   rn   r   r   r`   r   r   rK   )!r1   source_imagereference_imagesource_featsreference_feats
return_allwarp_featureuse_light_en_delast_multi_self_offsetslast_multi_cross_offsetsresults_allrN   feat_sourcefeat_refrw   rx   ry   rz   cross_att_mapsatt_source_featself_att_mapsatt_reference_feat
input_featoffsets_attrs   rt   cross_offsetsself_offsetscur_source_imagecur_reference_imagewarp_att_source_imagewarp_att_reference_imageresult_tryonr   r   r   r9      sL  

&(
0(

00$$



zDAFlowNet.forward)rI   r%   )FTTr:   r   r   r3   r   r      s    1r   c                       s.   e Zd Zd	 fdd	Z			d
ddZ  ZS )SDAFNet_Tryonr$   r   c                    sX   t t|   g d}t||| _t||| _t|| _t|| _t	t
||d| _d S )NrF   )r   )r)   r   r*   rE   source_featuresreference_featuresrR   
source_FPNreference_FPNr   rV   dafnet)r1   ref_in_channelsource_in_channelr   r   r3   r   r   r*     s   

zSDAFNet_Tryon.__init__TFc           
   	   C   s<   |  | |}| | |}| j|||||||d}	|	S )N)r   r   r   )r   r   r   r   r   )
r1   	ref_inputr   	ref_imager   r   r   r   r   resultr   r   r   r9     s   zSDAFNet_Tryon.forward)r$   r   )TFTr:   r   r   r3   r   r     s    r   )randomnumpynpr   torch.nnr+   torch.nn.functional
functionalr_   modelscope.metainfor   modelscope.modelsr   modelscope.utils.constantr   r   r   Moduler!   r@   rE   rR   r   r   r   r   r   r   r   r   <module>   s$    () ^