a
    
dBT                     @   sz   d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZmZ dd Zddd	ZG d
d deZdS )    N)	normalize)init_detection_model)init_parsing_model)
img2tensorimwritec                 C   s   dd }g }| D ]V}||d |}||d |}||d |}||d |}	|| |	|  }
| |
 q|t|}| | |fS )Nc                 S   s    | dk rdS | |kr|S | S d S )Nr    )vallengthr   r   e/var/www/html/stable-diffusion-webui/repositories/CodeFormer/facelib/utils/face_restoration_helper.pyget_location   s
    z&get_largest_face.<locals>.get_locationr            )appendindexmax)	det_faceshwr   Z
face_areasdet_faceleftrighttopbottomZ	face_arealargest_idxr   r   r
   get_largest_face   s    r   c           	      C   s   |d urt |}nt |d |d g}g }| D ]L}t |d |d  d |d |d  d g}t j|| }|| q2|t|}| | |fS )Nr   r   r   r   )nparraylinalgnormr   r   min)	r   r   r   centercenter_distr   Zface_centerdist
center_idxr   r   r
   get_center_face"   s    .r%   c                   @   sb   e Zd ZdZd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dd ZdS )!FaceRestoreHelperz6Helper for the face restoration pipeline (base class).   r   r   retinaface_resnet50pngFNc
           
      C   s  || _ || _|| _| jd dkr.| jd dks6J dt|| jd  t|| jd  f| _| j rtddgddgddgg| _n*td	d
gddgddgddgddgg| _| j|d  | _| jd dkr| jd d df  || jd d  d 7  < | jd dkr2| jd d df  || jd d  d 7  < || _|| _	| j	du rPd| _ g | _
g | _g | _g | _g | _g | _g | _|	d u rttj rdnd| _n|	| _t|d| jd| _|| _td| jd| _d S )Nr   r   zcrop ration only supports >=1      i?  i  is  gZwgh@gCVzNm@gqs@g.1n@g%
p@gAOs@gH0[(i@g46w@gW[ls@g<;k2w@      @r   TFcudacpu)halfdeviceZparsenet)
model_namer1   )template_3pointsupscale_factor
crop_ratioint	face_sizer   r   face_templatesave_extpad_blurall_landmarks_5r   affine_matricesinverse_affine_matricescropped_facesrestored_facespad_input_imgstorchr1   r.   is_availabler   face_det	use_parser   
face_parse)
selfr4   r7   r5   	det_modelr9   r3   r:   rD   r1   r   r   r
   __init__3   s@    
$& ,,
zFaceRestoreHelper.__init__c                 C   s
   || _ d S N)r4   )rF   r4   r   r   r
   set_upscale_factoro   s    z$FaceRestoreHelper.set_upscale_factorc                 C   s   t |trt|}t|dkr.|d d }t|jdkrLt|tj	}n(|jd dkrt|ddddddf }|| _
t| j
jdd d	k rd
t| j
jdd  }tj| j
d||tjd| _
dS )z*img can be image path or cv2 loaded image.   i     r      Nr   r   r'   r-   r   r   )fxfyinterpolation)
isinstancestrcv2imreadr   r   lenshapecvtColorCOLOR_GRAY2BGR	input_imgr    resizeINTER_LINEAR)rF   imgfr   r   r
   
read_imager   s    

zFaceRestoreHelper.read_image{Gz?c           $         s  |d u rd}| j }np| j jdd \}}	|t||	 }td|}t|| t|	|  }}	|dk rhtjntj}
tj| j |	|f|
d}t	
  | j|}W d    n1 s0    Y  |d u s|jd dkrdS || }|D ] tj d  d   d  d  g}|d ur ||k r q| jrJt fd	d
tdddD }n t fdd
tdddD }| j| | j dd  qt| jdkrdS |r| j j\}}	}t| j||	\| _}| j| g| _n6|r| j j\}}	}t| j||	\| _}| j| g| _| jrg | _| jD ]}|dd d f }|dd d f }|| d }|dd d f |dd d f  d }|| }|| }|t|ddg  }|tj|  }d}|ttj| d | tj| d | 9 }t|ddg }||d  }t|| | || | || | || | g}tj| d }ttt|d d}ttt|d d df ttt|d d df tt t|d d df tt t|d d df f}t|d  | dt|d  | dt|d | j jd  | dt|d | j jd  | dg}t|dkrt!| j |d |d f|d |d fdfd} |d d df  |d 7  < |d d df  |d 7  < | j\}}	}tj"d |d |	d df \}}}t#dt$t%||d  t%|	d | |d   dt$t%||d  t%|d | |d   }!t|| }"|"d dkrT|"d7 }"tj&| d|"|"fd}#| 'd} | |#|  t(|!d d dd 7 } | tj)| dd|  t(|!dd 7 } t(| dd } | j|  n| jt*| j  q"t| jS )!Nr   r   r   rQ            	   c                    s    g | ]} |  |d   gqS r   r   .0ibboxr   r
   
<listcomp>       z:FaceRestoreHelper.get_face_landmarks_5.<locals>.<listcomp>      c                    s    g | ]} |  |d   gqS rf   r   rg   rj   r   r
   rl      rm            ?r   rM   g      ?g       @g?g?rN   reflectg      ?)ksizefloat32g      @g        )r   r   axisrL   )+rZ   rW   r    r   r6   rT   
INTER_AREAr\   r[   rA   no_gradrC   Zdetect_facesr   r   r   r3   r   ranger;   r   r   rV   r   r%   r:   r@   flipudhypotstackrintfloorceilpadogridmaximumminimumru   	boxFilterastypeclipmediancopy)$rF   Zonly_keep_largestonly_center_facer[   Z
blur_ratioeye_dist_thresholdscalerZ   r   r   interpbboxesZeye_distlandmark_r   r$   	landmarkseye_left	eye_righteye_avg	mouth_avg
eye_to_eyeeye_to_mouthx
rect_scaleycquadqsizeborderr   Zpad_imgmaskblurblur_imgr   rj   r
   get_face_landmarks_5   s    

*(" $*2T."
"$z&FaceRestoreHelper.get_face_landmarks_5constantc           
      C   s  | j r:t| jt| jks:J dt| j dt| j t| jD ]\}}tj|| jtjdd }| j	
| |dkrtj}n|dkrtj}n|dkrtj}| j r| j| }n| j}tj||| j|dd	}| j
| |d
urDtj|d }| d|dd| j }	t||	 qDd
S )z1Align and warp faces with face template.
        zMismatched samples: z and )methodr   r   Z
reflect101rs   )         )
borderModeborderValueNr   02d.)r:   rV   r@   r;   	enumeraterT   estimateAffinePartial2Dr8   LMEDSr<   r   BORDER_CONSTANTBORDER_REFLECT101BORDER_REFLECTrZ   
warpAffiner7   r>   ospathsplitextr9   r   )
rF   Zsave_cropped_pathborder_modeidxr   affine_matrixrZ   cropped_facer   	save_pathr   r   r
   align_warp_face   s4    
z!FaceRestoreHelper.align_warp_facec                 C   sn   t | jD ]^\}}t|}|| j9 }| j| |dur
tj	|\}}| d|dd}t
|| q
dS )zGet inverse affine matrix.Nr   r   z.pth)r   r<   rT   invertAffineTransformr4   r=   r   r   r   r   rA   save)rF   Zsave_inverse_affine_pathr   r   inverse_affiner   r   r   r   r   r
   get_inverse_affine  s    

z$FaceRestoreHelper.get_inverse_affinec                 C   s   | j | d S rI   )r?   r   )rF   facer   r   r
   add_restored_face*  s    z#FaceRestoreHelper.add_restored_facec           )   
   C   s  | j j\}}}t|| j t|| j  }}	|d u rNtj| j |	|ftjd}ntj||	|ftjd}t| j	t| j
ksJ dg }
t| j	| j
D ]l\}}|d ur |j|| jdd }|| j }|d d df  | j9  < | jd | j | jd | j f}n:| jdkrd| j }nd}|d d df  |7  < | j}t|||	|f}tj|tjd}t|||	|f}t|ttd| j td| j ftj}|d d d d d f | }t|}|r4|\}}tj||d	ftjd}td
t| }d|||| ||| d d f< t|||	|f}|
| t|d d }|d }t|t||ftj}|d }t||d |d fd}t|jdkr|d d d d d f }|d d d d d f }| jrttj|dtjd}t|dd ddd}t|dddd t|d| j}t   | !|d }W d    n1 sH0    Y  |j"dd# $ % }t&|j}g d} t'| D ]\}!}"|"|||!k< qt|dd}t|dd}d}#d|d |#d d f< d||# d d d f< d|d d d |#f< d|d d |# d f< |d }t||}tj|||	|fd	d}|d d d d d f }$|$|k d}%|$|% |d|%   }t|jd	kr|jd dkr|d d d d d	d f }&|| d| |d d d d dd	f   }tj(||&fdd}q|| d| |  }qt)|dkr |tj*}n|tj}|rtjg |jtjd}'d|'d d d d df< d|'d d d d df< d|'d d d d df< |
D ]}||' d| |  }q|d urt+j,-|d }(|( d| j. }t/|| |S )Nra   z;length of restored_faces and affine_matrices are different.)Zoutscaler   r   r   rq   )dtyper   ix     )r'   r'   ru   g     o@T)bgr2rgbru   )rq   rq   rq   )inplace)dim)r   rL   rL   rL   rL   rL   rL   rL   rL   rL   rL   rL   rL   rL   r   rL   r   r   r   )e   r   ro   
   )flagsr6   rM   rv   rK   rL   r   )0rZ   rW   r6   r4   rT   r[   r\   INTER_LANCZOS4rV   r?   r=   zipenhancer7   r   r   onesru   erodeuint8sumsqrtr   GaussianBlurrD   r   r   r   rA   	unsqueezetor1   ry   rE   argmaxsqueezer/   numpyzerosr   concatenater   uint16r   r   r   r9   r   ))rF   r   Zupsample_imgZdraw_boxZface_upsamplerr   r   r   Zh_upZw_upZinv_mask_bordersrestored_facer   r7   extra_offsetinv_restoredr   inv_maskinv_mask_erosionZpasted_facetotal_face_areamask_borderr   Zinv_mask_borderw_edgeerosion_radiusinv_mask_center	blur_sizeinv_soft_maskZ
face_inputoutZ
parse_maskZMASK_COLORMAPr   colorthresZinv_soft_parse_maskZ	fuse_maskalphaZ	img_colorr   r   r   r
   paste_faces_to_input_image.  s    


"&
"

. *

z,FaceRestoreHelper.paste_faces_to_input_imagec                 C   s.   g | _ g | _g | _g | _g | _g | _g | _d S rI   )r;   r?   r<   r>   r=   r   r@   )rF   r   r   r
   	clean_all  s    zFaceRestoreHelper.clean_all)r'   r(   r)   r*   FFFN)FFNr`   N)Nr   )N)NNFN)__name__
__module____qualname____doc__rH   rJ   r_   r   r   r   r   r   r   r   r   r   r
   r&   0   s0           
<     
x
 

 r&   )r   r   N)rT   r   r   r   rA   !torchvision.transforms.functionalr   Zfacelib.detectionr   Zfacelib.parsingr   Zfacelib.utils.miscr   r   r   r%   objectr&   r   r   r   r
   <module>   s   
