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 eej  rdnd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_nmscudacpuc                 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        )stage1stage2stage3)name	min_sizesstepsvarianceclipZ
loc_weightZ	gpu_train
batch_sizeZngpuepochZdecay1Zdecay2
image_sizereturn_layers
in_channelout_channelResnet50      d   F   Z   iH  )layer2layer3layer4z
mobile0.25resnet50znetwork_name=)NotImplementedError)network_nameZcfg_mnetZcfg_re50 r;   g/var/www/html/stable-diffusion-webui/repositories/CodeFormer/facelib/detection/retinaface/retinaface.pygenerate_config   sZ    r=   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 )
RetinaFacer8   Ftestc           
         s  t t|   || _t|}|d | _d| | _|| _|| _d\| _	| _
d\| _| _| _tdggdggdggggt| _tdd	| _d }|d d
krt }t||d | _n4|d dkrd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| _&| t | '  | jr| (  d S )Nr$   Zretinaface_)i@  if  )g      ?NNg      Z@g     @]@g     ^@T)Zdefault_squarer   r,   r/   r   F)
pretrainedr-   r   r1   r   r.   r    )Zfpn_numZ
inchannels))superr>   __init__half_inferencer=   backbone
model_namecfgphasetarget_sizemax_sizeresizescalescale1torchtensortodevicemean_tensorr   	referencer   r   bodyZtorchvision.modelsmodelsr8   r   fpnr   ssh1ssh2ssh3r
   	ClassHeadr	   BboxHeadr   LandmarkHeadevalhalf)
selfr:   r]   rG   rF   rD   rT   in_channels_stage2in_channels_listout_channels	__class__r;   r<   rB   K   sH    
&
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;   )rZ   .0ifeaturer^   r;   r<   
<listcomp>       z&RetinaFace.forward.<locals>.<listcomp>dimc                    s   g | ]\}} j | |qS r;   )rY   rd   rh   r;   r<   ri      rj   c                    s   g | ]\}} j | |qS r;   )r[   rd   rh   r;   r<   ri      rj   train)rS   rD   listvaluesrU   rV   rW   rX   rM   cat	enumeraterG   Fsoftmax)r^   inputsoutrU   Zfeature1Zfeature2Zfeature3featuresZbbox_regressionsZclassificationstmpZldm_regressionsoutputr;   rh   r<   forwardx   s     


  
zRetinaFace.forwardc           
   
   C   s   |j dd  \}}tj||||gtjdt| _||||||||||g
}tj|tjdt| _|t}| jrz|	 }| |\}}}t
| j|j dd  d}| t}	||||	fS )Nr   dtype)r+   )shaperM   rN   float32rO   rP   rK   rL   rC   r]   r   rF   rz   )
r^   ru   heightwidthrx   locconf	landmarksZpriorboxpriorsr;   r;   r<   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   fxfyinterpolation)
isinstancer   cv2cvtColornpasarrayCOLOR_RGB2BGRastyper~   minr}   maxfloatrH   roundrI   rJ   INTER_LINEAR	transposerM   
from_numpy	unsqueeze)r^   imageuse_origin_sizeim_size_minim_size_maxrJ   r;   r;   r<   	transform   s    zRetinaFace.transform皙?皙?Tc                 C   s  |  ||\}| _|t}| 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 )	z5
        Params:
            imgs: BGR image
        r   r'   Nr   rn   F)copyaxis)r   rJ   rO   rP   rC   r]   rQ   _RetinaFace__detect_facesr   datasqueezerF   rK   r   numpyr   rL   r   whereargsorthstacknewaxisr   r~   r   concatenate)r^   r   conf_thresholdnms_thresholdr   r   r   r   r   boxesscoresindsorderbounding_boxeskeepr;   r;   r<   detect_faces   s*    

 (
zRetinaFace.detect_facesNc                    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;   )re   jlandmarkr;   r<   ri      rj   z,RetinaFace.__align_multi.<locals>.<listcomp>   )p   r   )	crop_sizer   )lenranger   r   arrayrR   appendr   )r^   r   r   r   limitfacesZfacial5pointsZwarped_facer;   r   r<   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)r^   imgr   r   Zrltr   r   r;   r;   r<   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;   )r   r   r   r   r   re   framer;   r;   r<   ri     rj   z0RetinaFace.batched_transform.<locals>.<listcomp>r{   r   r   )scale_factorc              
      s$   g | ]}t j|d d   t jdqS )Nr   )r   rJ   r   r   rJ   r;   r<   ri   &  s   r    )r   r    r   r   )r   r   r   r   r~   r   r}   r   r   rH   r   rI   rs   interpolater   
contiguousrM   r   )r^   framesr   Zfrom_PILr   r   r;   r   r<   batched_transform	  s*    


zRetinaFace.batched_transformc                 C   s  |  ||\}| _|t}|| 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r8|	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   rn   r   rk   r{   )r   rJ   rO   rP   rQ   r   r   r   rF   rK   r   rL   rM   rq   r   zipr}   r   r   r   r~   r   r   r   )r^   r   r   r   r   Zb_locZb_confZb_landmarksr   Zfinal_bounding_boxesZfinal_landmarksZb_indiceZb_loc_and_confpredZlandmr   r   r   r   r;   r;   r<   batched_detect_faces4  s.    



"

zRetinaFace.batched_detect_faces)r8   Fr?   )r   r   T)N)r   N)r   r   T)__name__
__module____qualname__rB   rz   r   r   r   r   r   r   r   __classcell__r;   r;   rb   r<   r>   I   s   -   
/

+r>   )$r   r   r   rM   torch.nnnnZtorch.nn.functional
functionalrs   PILr   Ztorchvision.models._utilsr   Zfacelib.detection.align_transr   r   Z+facelib.detection.retinaface.retinaface_netr   r   r   r	   r
   r   Z-facelib.detection.retinaface.retinaface_utilsr   r   r   r   r   r   rP   r   is_availabler=   Moduler>   r;   r;   r;   r<   <module>   s     8