a
    d                     @   s   d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ ejejejeZG d	d
 d
ZdS )    N)
img2tensor
tensor2img)load_file_from_url)FaceRestoreHelper)	normalize)GFPGANBilinear)GFPGANv1)GFPGANv1Cleanc                   @   s,   e Zd ZdZdddZe dd
dZdS )GFPGANera  Helper for restoration with GFPGAN.

    It will detect and crop faces, and then resize the faces to 512x512.
    GFPGAN is used to restored the resized faces.
    The background is upsampled with the bg_upsampler.
    Finally, the faces will be pasted back to the upsample background image.

    Args:
        model_path (str): The path to the GFPGAN model. It can be urls (will first download it automatically).
        upscale (float): The upscale of the final output. Default: 2.
        arch (str): The GFPGAN architecture. Option: clean | original. Default: clean.
        channel_multiplier (int): Channel multiplier for large networks of StyleGAN2. Default: 2.
        bg_upsampler (nn.Module): The upsampler for the background. Default: None.
       cleanNc           
      C   sX  || _ || _|d u r,ttj r&dndn|| _|dkrZtdd|d ddddddd	
| _nl|d
krtdd|d ddddddd	
| _nD|dkrt	dd|d ddddddd	
| _n|dkrddl
m} | | _t|ddddd| jdd| _|drt|tjtddd d}t|}d|v r"d}	nd}	| jj||	 dd | j  | j| j| _d S )Ncudacpur      F   T   )
Zout_sizeZnum_style_featchannel_multiplierZdecoder_load_pathZfix_decoderZnum_mlpZinput_is_latentZdifferent_wZnarrowZsft_halfZbilinearoriginalRestoreFormerr   )r   )r   r   Zretinaface_resnet50Zpngzgfpgan/weights)Z	face_sizeZ
crop_ratioZ	det_modelZsave_extZ	use_parsedeviceZmodel_rootpathzhttps://)urlZ	model_dirprogress	file_nameZ
params_emaparams)strict)upscalebg_upsamplertorchr   r   Zis_availabler	   gfpganr   r   Zgfpgan.archs.restoreformer_archr   r   face_helper
startswithr   ospathjoinROOT_DIRloadZload_state_dictevalto)
selfZ
model_pathr   archr   r   r   r   Zloadnetkeyname r+   U/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/gfpgan/utils.py__init__    s    &






zGFPGANer.__init__FT      ?c                 C   s  | j   |r&t|d}|g| j _n&| j | | j j|dd | j   | j jD ]}t|d ddd}t	|dddd |
d	| j}z,| j|d
|dd	 }t|d	ddd}	W n8 ty }
 z td|
 d |}	W Y d }
~
n
d }
~
0 0 |	d}	| j |	 qT|sj|rj| jd ur:| jj|| jdd	 }nd }| j d  | j j|d}| j j| j j|fS | j j| j jd fS d S )N)r   r      )only_center_faceZeye_dist_thresholdg     o@T)Zbgr2rgbfloat32)r.   r.   r.   )Zinplacer   F)Z
return_rgbweight)r   )Zrgb2bgrZmin_maxz	Failed inference for GFPGAN: .Zuint8)Zoutscale)Zupsample_img)r   Z	clean_allcv2resizeZcropped_facesZ
read_imageZget_face_landmarks_5Zalign_warp_facer   r   Z	unsqueezer'   r   r   r   ZsqueezeRuntimeErrorprintZastypeZadd_restored_facer   enhancer   Zget_inverse_affineZpaste_faces_to_input_imageZrestored_faces)r(   imgZhas_alignedr0   Z
paste_backr2   Zcropped_faceZcropped_face_toutputZrestored_faceerrorZbg_imgZrestored_imgr+   r+   r,   r9   e   s6    


zGFPGANer.enhance)r   r   r   NN)FFTr.   )__name__
__module____qualname____doc__r-   r   Zno_gradr9   r+   r+   r+   r,   r
      s   
Er
   )r5   r!   r   Zbasicsr.utilsr   r   Zbasicsr.utils.download_utilr   Z&facexlib.utils.face_restoration_helperr   Z!torchvision.transforms.functionalr   Z!gfpgan.archs.gfpgan_bilinear_archr   Zgfpgan.archs.gfpganv1_archr   Z gfpgan.archs.gfpganv1_clean_archr	   r"   dirnameabspath__file__r$   r
   r+   r+   r+   r,   <module>   s   