a
    þd×0  ã                   @   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„ Z	G dd„ dej
ƒZG dd„ dej
ƒZd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S )é    Nc                 C   sD  | j \}}}}|| }t || ¡}|  |||¡}tj|dd}tj|| || fdd}	|	jtjdd}	| ¡ }
| || |¡}|||
d f }|||
d f }t	|
| dkƒrÀ||df }n|||
| f }t	|
| dkƒrî||df }n|||
| f }t 
tj|| || fdd¡}|d	9 }|	| ||d¡7 }	|	d
7 }	|	S )Né   )ZaxisF)Úcopyé   i   iÿ  r   g      Ð?g      à?)ÚshapeÚnpÚarangeÚreshapeZargmaxÚstackZastypeÚfloatZravelÚanyÚsign)ÚheatmapsÚBÚNÚHÚWZHWZBN_rangeZheatlineZindexesÚpredsZinrZx_upZx_downZy_upZy_downZ
think_diff© r   úf/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/facexlib/alignment/awing_arch.pyÚcalculate_points   s,     r   c                       s(   e Zd Zd‡ fdd„	Zd	dd„Z‡  ZS )
ÚAddCoordsThé@   Fc                    s*   t t| ƒ ¡  || _|| _|| _|| _d S ©N)Úsuperr   Ú__init__Úx_dimÚy_dimÚwith_rÚwith_boundary)Úselfr   r   r   r   ©Ú	__class__r   r   r   .   s
    zAddCoordsTh.__init__Nc                 C   sf  |j d }tjd| jgtj|jd}| d¡}tj| jtj|jd d¡}| d¡}t 	| 
¡ | 
¡ ¡}| d¡}tjd| jgtj|jd}| d¡}tj| jtj|jd d¡}| d¡}t 	| 
¡ | 
¡ ¡}	|	 d¡}	| dddd¡}|	 dddd¡}	|| jd  }|	| jd  }	|d d }|	d d }	| |ddd¡}|	 |ddd¡}	| jr¸|dur¸t |dd…dd…dd…dd…f dd	¡}
t |¡}t |
d
k||¡}t |
d
k|	|¡}| jrâ|durâ| |j¡}| |j¡}tj|||	gdd}| jr<t t |d¡t |	d¡ ¡}|t |¡ }tj||gdd}| jrb|durbtj|||gdd}|S )z8
        input_tensor: (batch, c, x_dim, y_dim)
        r   r   )ZdtypeÚdeviceéÿÿÿÿé   r   Ng        g      ð?gš™™™™™©?)Zdim)r   ÚtorchZonesr   Úint32r"   Z	unsqueezer   r   Úmatmulr
   ZpermuteÚrepeatr   ÚclampZ
zeros_likeÚwhereÚtoÚcatr   ÚsqrtÚpowÚmax)r   Úinput_tensorÚheatmapZbatch_size_tensorZxx_onesZxx_rangeZ
xx_channelZyy_onesZyy_rangeZ
yy_channelÚboundary_channelZzero_tensorZxx_boundary_channelZyy_boundary_channelÚretÚrrr   r   r   Úforward5   sJ    






*
zAddCoordsTh.forward)r   r   FF)N©Ú__name__Ú
__module__Ú__qualname__r   r5   Ú__classcell__r   r   r    r   r   ,   s   r   c                       s,   e Zd ZdZd‡ fdd„	Zd	dd„Z‡  ZS )
ÚCoordConvThz CoordConv layer as in the paper.Fc           	         s^   t t| ƒ ¡  t||||d| _|d7 }|r4|d7 }|rD|sD|d7 }tj|d|i|¤Ž| _d S )N)r   r   r   r   r   r   Úin_channels)r   r;   r   r   Ú	addcoordsÚnnÚConv2dÚconv)	r   r   r   r   r   r<   Ú	first_oneÚargsÚkwargsr    r   r   r   q   s    zCoordConvTh.__init__Nc                 C   s>   |   ||¡}|d d …dd …d d …d d …f }|  |¡}||fS )Néþÿÿÿ)r=   r@   )r   r0   r1   r3   Úlast_channelr   r   r   r5   {   s     
zCoordConvTh.forward)F)N)r7   r8   r9   Ú__doc__r   r5   r:   r   r   r    r   r;   n   s   
r;   r   Fc              	   C   s   t j| |d||||dS )z3x3 convolution with paddingr$   )Úkernel_sizeÚstrideÚpaddingÚbiasÚdilation)r>   r?   )Ú	in_planesÚ
out_planesZstrdrI   rJ   rK   r   r   r   Úconv3x3‚   s    rN   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )Ú
BasicBlockr   Nc                    sF   t t| ƒ ¡  t|||ƒ| _tjdd| _t||ƒ| _|| _	|| _
d S )NT)Zinplace)r   rO   r   rN   Úconv1r>   ÚReLUÚreluÚconv2Ú
downsamplerH   )r   ZinplanesZplanesrH   rT   r    r   r   r   Š   s    zBasicBlock.__init__c                 C   sL   |}|   |¡}|  |¡}|  |¡}| jd ur6|  |¡}||7 }|  |¡}|S r   )rP   rR   rS   rT   )r   ÚxÚresidualÚoutr   r   r   r5   ”   s    





zBasicBlock.forward)r   N)r7   r8   r9   Z	expansionr   r5   r:   r   r   r    r   rO   ‡   s   
rO   c                       s$   e Zd Z‡ fdd„Zdd„ Z‡  ZS )Ú	ConvBlockc                    sÚ   t t| ƒ ¡  t |¡| _t|t|d ƒƒ| _t t|d ƒ¡| _	tt|d ƒt|d ƒddd| _
t t|d ƒ¡| _tt|d ƒt|d ƒddd| _||krÐt t |¡t d¡tj||dddd¡| _nd | _d S )Nr   é   r   )rI   rK   TF)rG   rH   rJ   )r   rX   r   r>   ÚBatchNorm2dÚbn1rN   ÚintrP   Úbn2rS   Úbn3Úconv3Z
SequentialrQ   r?   rT   )r   rL   rM   r    r   r   r   §   s    ""ýzConvBlock.__init__c                 C   s–   |}|   |¡}t |d¡}|  |¡}|  |¡}t |d¡}|  |¡}|  |¡}t |d¡}|  |¡}t 	|||fd¡}| j
d urŠ|  
|¡}||7 }|S )NTr   )r[   ÚFrR   rP   r]   rS   r^   r_   r%   r,   rT   )r   rU   rV   Zout1Zout2Zout3r   r   r   r5   ¹   s    







zConvBlock.forwardr6   r   r   r    r   rX   ¥   s   rX   c                       s6   e Zd Zd
‡ fdd„	Zdd„ Zdd„ Zdd	„ Z‡  ZS )Ú	HourGlassFc                    sN   t t| ƒ ¡  || _|| _|| _tddddd|ddddd
| _|  | j¡ d S )Nr   Té   r   r   )
r   r   r   r   r<   rA   Úout_channelsrG   rH   rI   )	r   ra   r   Únum_modulesÚdepthÚfeaturesr;   Ú	coordconvÚ_generate_network)r   rd   re   Znum_featuresrA   r    r   r   r   Ô   s"    özHourGlass.__init__c                 C   s„   |   dt|ƒ tddƒ¡ |   dt|ƒ tddƒ¡ |dkrL|  |d ¡ n|   dt|ƒ tddƒ¡ |   dt|ƒ tddƒ¡ d S )NÚb1_rb   Úb2_r   Úb2_plus_Úb3_)Ú
add_moduleÚstrrX   rh   )r   Úlevelr   r   r   rh   æ   s    zHourGlass._generate_networkc                 C   s¦   |}| j dt|ƒ  |ƒ}tj|ddd}| j dt|ƒ  |ƒ}|dkrZ|  |d |¡}n|}| j dt|ƒ  |ƒ}|}| j dt|ƒ  |ƒ}tj|ddd	}|| S )
Nri   r   ©rH   rj   r   rk   rl   Znearest)Zscale_factorÚmode)Ú_modulesrn   r`   Ú
avg_pool2dÚ_forwardZinterpolate)r   ro   ÚinpZup1Zlow1Zlow2Zlow3Zup2r   r   r   rt   ò   s    zHourGlass._forwardc                 C   s"   |   ||¡\}}|  | j|¡|fS r   )rg   rt   re   )r   rU   r1   rE   r   r   r   r5     s    zHourGlass.forward)F)r7   r8   r9   r   rh   rt   r5   r:   r   r   r    r   ra   Ò   s   ra   c                       s.   e Zd Zd‡ fdd„	Zdd„ Zd	d
„ Z‡  ZS )ÚFANr   FéD   Úcudac                    s¼  t t| ƒ ¡  || _|| _|| _|| _|| _| jrPtdddddddddd	| _	ntdddddddddd	| _	t
 d¡| _tdd	ƒ| _td	d	ƒ| _td	dƒ| _t| jƒD ]}|d
krºd}nd}|  dt|ƒ tddd|ƒ¡ |  dt|ƒ tddƒ¡ |  dt|ƒ t
jddddd
d¡ |  dt|ƒ t
 d¡¡ |  dt|ƒ t
jd|d ddd
d¡ || jd k r¦|  dt|ƒ t
jddddd
d¡ |  dt|ƒ t
j|d dddd
d¡ q¦d S )Nrb   TFr$   r   é   r   )	r   r   r   r   r<   rc   rG   rH   rI   é€   r   Úmr   rY   Útop_m_Ú	conv_last)rG   rH   rI   Úbn_endÚlÚblÚal)r   rv   r   r"   rd   Ú
gray_scaleÚend_reluÚnum_landmarksr;   rP   r>   rZ   r[   rX   rS   r_   Úconv4Úrangerm   rn   ra   r?   )r   rd   rƒ   r‚   r„   r"   Z	hg_modulerA   r    r   r   r     s^    ÷
÷
$($ÿzFAN.__init__c                 C   sX  |   |¡\}}t |  |¡d¡}tj|  |¡ddd}|  |¡}|  |¡}|}g }g }d }t| j	ƒD ]ê}| j
dt|ƒ  ||ƒ\}}	|}
| j
dt|ƒ  |
ƒ}
t | j
dt|ƒ  | j
dt|ƒ  |
ƒƒd¡}
| j
dt|ƒ  |
ƒ}| jrôt |¡}| |¡ | |	¡ || j	d	 k rd| j
d
t|ƒ  |
ƒ}
| j
dt|ƒ  |ƒ}||
 | }qd||fS )NTr   rp   r{   r|   r~   r}   r   r   r€   r   )rP   r`   rR   r[   rs   rS   r_   r…   r†   rd   rr   rn   rƒ   Úappend)r   rU   Ú_ÚpreviousÚoutputsZboundary_channelsZtmp_outÚiÚhgr2   ZllZtmp_out_r   r   r   r5   D  s0    

0


zFAN.forwardc                 C   sê   |j \}}}|d |d ddf}t |d¡}|dd d d…f }t t | d¡¡¡ ¡ }| 	| j
¡}| d¡ d¡ |  |¡\}}|d d d …d d…d d …d d …f }| ¡  ¡  ¡ }	t|	ƒ dd¡}
|
|d d… 9 }
|
|d	d … 7 }
|
S )
Nr   r   )rb   rb   .r#   )r   r   r   g     ào@r   rD   )r   Úcv2Úresizer%   Z
from_numpyr   ZascontiguousarrayZ	transposer
   r+   r"   Zdiv_Z
unsqueeze_r5   ÚdetachÚcpuÚnumpyr   r   )r   Úimgr   r   rˆ   Úoffsetru   rŠ   rW   r   Úpredr   r   r   Úget_landmarksg  s    $zFAN.get_landmarks)r   FFrw   rx   )r7   r8   r9   r   r5   r•   r:   r   r   r    r   rv     s   5#rv   )r   r   Fr   )r   r‘   r   r%   Ztorch.nnr>   Ztorch.nn.functionalZ
functionalr`   r   ÚModuler   r;   rN   rO   rX   ra   rv   r   r   r   r   Ú<module>   s   $B
-;