|
from chain_img_processor import ChainImgProcessor, ChainImgPlugin |
|
import os |
|
import gfpgan |
|
import threading |
|
from PIL import Image |
|
from numpy import asarray |
|
import cv2 |
|
|
|
from roop.utilities import resolve_relative_path, conditional_download |
|
modname = os.path.basename(__file__)[:-3] |
|
|
|
model_gfpgan = None |
|
THREAD_LOCK_GFPGAN = threading.Lock() |
|
|
|
|
|
|
|
def start(core:ChainImgProcessor): |
|
manifest = { |
|
"name": "GFPGAN", |
|
"version": "1.4", |
|
|
|
"default_options": {}, |
|
"img_processor": { |
|
"gfpgan": GFPGAN |
|
} |
|
} |
|
return manifest |
|
|
|
def start_with_options(core:ChainImgProcessor, manifest:dict): |
|
pass |
|
|
|
|
|
class GFPGAN(ChainImgPlugin): |
|
|
|
def init_plugin(self): |
|
global model_gfpgan |
|
|
|
if model_gfpgan is None: |
|
model_path = resolve_relative_path('../models/GFPGANv1.4.pth') |
|
model_gfpgan = gfpgan.GFPGANer(model_path=model_path, upscale=1, device=self.device) |
|
|
|
|
|
|
|
def process(self, frame, params:dict): |
|
import copy |
|
|
|
global model_gfpgan |
|
|
|
if model_gfpgan is None: |
|
return frame |
|
|
|
if "face_detected" in params: |
|
if not params["face_detected"]: |
|
return frame |
|
|
|
temp_frame = copy.copy(frame) |
|
if "processed_faces" in params: |
|
for face in params["processed_faces"]: |
|
start_x, start_y, end_x, end_y = map(int, face['bbox']) |
|
padding_x = int((end_x - start_x) * 0.5) |
|
padding_y = int((end_y - start_y) * 0.5) |
|
start_x = max(0, start_x - padding_x) |
|
start_y = max(0, start_y - padding_y) |
|
end_x = max(0, end_x + padding_x) |
|
end_y = max(0, end_y + padding_y) |
|
temp_face = temp_frame[start_y:end_y, start_x:end_x] |
|
if temp_face.size: |
|
with THREAD_LOCK_GFPGAN: |
|
_, _, temp_face = model_gfpgan.enhance( |
|
temp_face, |
|
paste_back=True |
|
) |
|
temp_frame[start_y:end_y, start_x:end_x] = temp_face |
|
else: |
|
with THREAD_LOCK_GFPGAN: |
|
_, _, temp_frame = model_gfpgan.enhance( |
|
temp_frame, |
|
paste_back=True |
|
) |
|
|
|
if not "blend_ratio" in params: |
|
return temp_frame |
|
|
|
temp_frame = Image.blend(Image.fromarray(frame), Image.fromarray(temp_frame), params["blend_ratio"]) |
|
return asarray(temp_frame) |
|
|