a
    d$4                     @   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lmZmZmZmZmZmZ d dlmZmZmZmZmZmZ dd ZG d	d
 d
ejZ dS )    N)Image)IntermediateLayerGetter)get_reference_facial_pointswarp_and_crop_face)FPNSSHMobileNetV1make_bbox_headmake_class_headmake_landmark_head)PriorBoxbatched_decodebatched_decode_landmdecodedecode_landm
py_cpu_nmsc                 C   s   dddgddgddggg dd	d
gdddddddddddddddd}dddgddgddggg dd	d
gdddddddddddddddd}| dkr|S | d kr|S t d!|  d S )"Nmobilenet0.25       @         i   )   r   r   g?g?Fg       @T            i        )Zstage1Zstage2Zstage3)nameZ	min_sizesZstepsvarianceZclipZ
loc_weightZ	gpu_trainZ
batch_sizeZngpuepochZdecay1Zdecay2
image_sizereturn_layers
in_channelout_channelResnet50      d   F   Z   iH  )Zlayer2Zlayer3Zlayer4z
mobile0.25resnet50znetwork_name=)NotImplementedError)network_nameZcfg_mnetZcfg_re50 r/   f/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/facexlib/detection/retinaface.pygenerate_config   sZ    r1   c                       sf   e Zd Zd fdd	Zdd Zd	d
 Zdd ZdddZdddZdddZ	dd Z
dddZ  ZS )
RetinaFacer,   FtestNc                    s  |d u r t t j rdndn|| _tt|   || _t|}|d | _	d| | _
|| _|| _d\| _| _d\| _| _| _t jdggdggd	gggg| jd
| _tdd| _d }|d dkrt }t||d | _n6|d dkrdd lm} |jdd}t||d | _|d }|d |d |d g}	|d }
t|	|
| _t|
|
| _t|
|
| _ t|
|
| _!t"d|d d| _#t$d|d d| _%t&d|d d| _'| (| j | )  | jr| *  d S )Ncudacpur   Zretinaface_)i@  if  )g      ?NNg      Z@g     @]@g     ^@)deviceT)Zdefault_squarer   r#   r&   r   F)Z
pretrainedr$   r   r(   r   r%   r   )Zfpn_numZ
inchannels)+torchr6   r4   Zis_availablesuperr2   __init__half_inferencer1   backboneZ
model_namecfgphasetarget_sizemax_sizeresizescalescale1tensormean_tensorr   	referencer   r   bodyZtorchvision.modelsmodelsr,   r   fpnr   ssh1ssh2ssh3r
   	ClassHeadr	   BboxHeadr   LandmarkHeadtoevalhalf)selfr.   rQ   r=   r6   r<   r;   rG   Zin_channels_stage2Zin_channels_listZout_channels	__class__r/   r0   r9   I   sJ    &
&zRetinaFace.__init__c                    s     |} jdks jdkr*t| } |} |d } |d } |d }|||g}tj	 fddt
|D dd}tj	 fd	dt
|D dd}	 fd
dt
|D }
tj	|
dd} jdkr||	|f}n|tj|	dd|f}|S )Nr   r&   r   r   r   c                    s   g | ]\}} j | |qS r/   )rM   .0ifeaturerR   r/   r0   
<listcomp>       z&RetinaFace.forward.<locals>.<listcomp>Zdimc                    s   g | ]\}} j | |qS r/   )rL   rU   rY   r/   r0   rZ      r[   c                    s   g | ]\}} j | |qS r/   )rN   rU   rY   r/   r0   rZ      r[   Ztrain)rF   r;   listvaluesrH   rI   rJ   rK   r7   cat	enumerater=   FZsoftmax)rR   inputsoutrH   Zfeature1Zfeature2Zfeature3featuresZbbox_regressionsZclassificationstmpZldm_regressionsoutputr/   rY   r0   forwardx   s     


  
zRetinaFace.forwardc           
   
   C   s   |j dd  \}}tj||||gtj| jd| _||||||||||g
}tj|tj| jd| _|| j}| jrx|	 }| |\}}}t
| j|j dd  d}| | j}	||||	fS )Nr   )dtyper6   )r"   )shaper7   rC   float32r6   rA   rB   rO   r:   rQ   r   r<   rh   )
rR   rc   heightwidthrf   locconf	landmarksZpriorboxpriorsr/   r/   r0   Z__detect_faces   s    zRetinaFace.__detect_facesc                 C   s   t |tjr tt|tj}|tj}t	|j
dd }t|j
dd }t| jt| }t|| | jkrt| jt| }|rdn|}|dkrtj|d d ||tjd}|ddd}t|d}||fS )Nr   r   r   ZfxZfyinterpolation)
isinstancer   cv2cvtColornpasarrayCOLOR_RGB2BGRastyperk   minrj   maxfloatr>   roundr?   r@   INTER_LINEAR	transposer7   
from_numpy	unsqueeze)rR   imageuse_origin_sizeim_size_minim_size_maxr@   r/   r/   r0   	transform   s    zRetinaFace.transform皙?皙?Tc                 C   s  |  ||\}| _|| j}| jr,| }|| j }| |\}}}}t|j	
d|j	| jd }	|	| j | j }	|	  }	|
dj	  d d df }
t|
d|| jd }|| j | j }|  }t|
|kd }|	| || |
|   }	}}
|
 d d d }|	| || |
|   }	}}
t|	|
d d tjf fjtjdd}t||}||d d f ||  }}tj||fddS )Nr   r    r   r]   F)copyZaxis)r   r@   rO   r6   r:   rQ   rD   _RetinaFace__detect_facesr   dataZsqueezer<   rA   r5   numpyr   rB   rw   whereZargsortZhstackZnewaxisrz   rk   r   concatenate)rR   r   conf_thresholdnms_thresholdr   rn   ro   rp   rq   boxesZscoresindsorderbounding_boxeskeepr/   r/   r0   detect_faces   s*    
 (
zRetinaFace.detect_facesc                    s   t |dk rg g fS |r0|d | }|d | }g }|D ]<  fddtdD }tt||| jdd}|| q8tj||fdd|fS )Nr   c                    s(   g | ] } d |   d | d  gqS )r   r   r/   )rV   jZlandmarkr/   r0   rZ      r[   z,RetinaFace.__align_multi.<locals>.<listcomp>   )p   r   )Z	crop_sizer   )lenranger   rw   arrayrE   appendr   )rR   r   r   rp   limitZfacesZfacial5pointsZwarped_facer/   r   r0   Z__align_multi   s    zRetinaFace.__align_multic                 C   sH   | j ||d}|d d ddf |d d dd f  }}| ||||S )N)r   r   r   )r   _RetinaFace__align_multi)rR   imgr   r   Zrltr   rp   r/   r/   r0   align_multi   s    *zRetinaFace.align_multic                    s  t |d tjrdnd}|r:dd |D }tj|tjd}t|d jdd }t|d jdd }t| j	t|  t
 | | jkrt| jt|  |rdn   dkr|stj| d	}n fd
d|D }|s|dddd }n|d}t|}| fS )z
        Arguments:
            frames: a list of PIL.Image, or torch.Tensor(shape=[n, h, w, c],
                type=np.float32, BGR format).
            use_origin_size: whether to use origin size.
        r   TFc                 S   s    g | ]}t t|t jqS r/   )ru   rv   rw   rx   ry   rV   framer/   r/   r0   rZ     r[   z0RetinaFace.batched_transform.<locals>.<listcomp>ri   r   r   )Zscale_factorc              
      s$   g | ]}t j|d d   t jdqS )Nrr   )ru   r@   r   r   r@   r/   r0   rZ   "  s   r   )r   r   r   r   )rt   r   rw   rx   rk   r{   rj   r|   r}   r>   r~   r?   rb   Zinterpolater   
contiguousr7   r   )rR   framesr   Zfrom_PILr   r   r/   r   r0   batched_transform  s*    


zRetinaFace.batched_transformc                 C   s  |  ||\}| _|| j}|| j }| |\}}}}g g  }	}
|d}t||| jd | j	 | j }t
||| jd | j | j }|dddddf }||k}tj||dfdd }t|||D ]\}}}||ddf ||ddf  }}|jd dkr:|	tjg tjd |
tjg tjd q|  |   }}t||}||ddf ||  }}|	| |
| q|	|
fS )	a  
        Arguments:
            frames: a list of PIL.Image, or np.array(shape=[n, h, w, c],
                type=np.uint8, BGR format).
            conf_threshold: confidence threshold.
            nms_threshold: nms threshold.
            use_origin_size: whether to use origin size.
        Returns:
            final_bounding_boxes: list of np.array ([n_boxes, 5],
                type=np.float32).
            final_landmarks: list of np.array ([n_boxes, 10], type=np.float32).
        r   r    Nr   r]   r   r\   r   )r   r@   rO   r6   rD   r   r   r   r<   rA   r   rB   r7   r`   r}   ziprj   r   rw   r   rk   r5   r   r   )rR   r   r   r   r   Zb_locZb_confZb_landmarksrq   Zfinal_bounding_boxesZfinal_landmarksZb_indiceZb_loc_and_confpredZlandmr   r   r   rp   r/   r/   r0   batched_detect_faces0  s.    


"

zRetinaFace.batched_detect_faces)r,   Fr3   N)r   r   T)N)r   N)r   r   T)__name__
__module____qualname__r9   rh   r   r   r   r   r   r   r   __classcell__r/   r/   rS   r0   r2   G   s   /   
+

+r2   )!ru   r   rw   r7   Ztorch.nnnnZtorch.nn.functionalZ
functionalrb   ZPILr   Ztorchvision.models._utilsr   Zfacexlib.detection.align_transr   r   Z!facexlib.detection.retinaface_netr   r   r   r	   r
   r   Z#facexlib.detection.retinaface_utilsr   r   r   r   r   r   r1   Moduler2   r/   r/   r/   r0   <module>   s     8