| import os, glob
|
|
|
| from PIL import Image
|
|
|
| import modules.scripts as scripts
|
|
|
| from modules import scripts, scripts_postprocessing
|
| from modules.processing import (
|
| StableDiffusionProcessing,
|
| StableDiffusionProcessingImg2Img,
|
| )
|
| from modules.shared import state
|
| from scripts.reactor_logger import logger
|
| from scripts.reactor_swapper import (
|
| swap_face,
|
| swap_face_many,
|
| get_current_faces_model,
|
| analyze_faces,
|
| half_det_size,
|
| providers
|
| )
|
| import folder_paths
|
| import comfy.model_management as model_management
|
|
|
|
|
| def get_models():
|
| swappers = [
|
| "insightface",
|
| "reswapper"
|
| ]
|
| models_list = []
|
| for folder in swappers:
|
| models_folder = folder + "/*"
|
| models_path = os.path.join(folder_paths.models_dir,models_folder)
|
| models = glob.glob(models_path)
|
| models = [x for x in models if x.endswith(".onnx") or x.endswith(".pth")]
|
| models_list.extend(models)
|
| return models_list
|
|
|
|
|
| class FaceSwapScript(scripts.Script):
|
|
|
| def process(
|
| self,
|
| p: StableDiffusionProcessing,
|
| img,
|
| enable,
|
| source_faces_index,
|
| faces_index,
|
| model,
|
| swap_in_source,
|
| swap_in_generated,
|
| gender_source,
|
| gender_target,
|
| face_model,
|
| faces_order,
|
| face_boost_enabled,
|
| face_restore_model,
|
| face_restore_visibility,
|
| codeformer_weight,
|
| interpolation,
|
| ):
|
| self.enable = enable
|
| if self.enable:
|
|
|
| self.source = img
|
| self.swap_in_generated = swap_in_generated
|
| self.gender_source = gender_source
|
| self.gender_target = gender_target
|
| self.model = model
|
| self.face_model = face_model
|
| self.faces_order = faces_order
|
| self.face_boost_enabled = face_boost_enabled
|
| self.face_restore_model = face_restore_model
|
| self.face_restore_visibility = face_restore_visibility
|
| self.codeformer_weight = codeformer_weight
|
| self.interpolation = interpolation
|
| self.source_faces_index = [
|
| int(x) for x in source_faces_index.strip(",").split(",") if x.isnumeric()
|
| ]
|
| self.faces_index = [
|
| int(x) for x in faces_index.strip(",").split(",") if x.isnumeric()
|
| ]
|
| if len(self.source_faces_index) == 0:
|
| self.source_faces_index = [0]
|
| if len(self.faces_index) == 0:
|
| self.faces_index = [0]
|
|
|
| if self.gender_source is None or self.gender_source == "no":
|
| self.gender_source = 0
|
| elif self.gender_source == "female":
|
| self.gender_source = 1
|
| elif self.gender_source == "male":
|
| self.gender_source = 2
|
|
|
| if self.gender_target is None or self.gender_target == "no":
|
| self.gender_target = 0
|
| elif self.gender_target == "female":
|
| self.gender_target = 1
|
| elif self.gender_target == "male":
|
| self.gender_target = 2
|
|
|
|
|
| if isinstance(p, StableDiffusionProcessingImg2Img) and swap_in_source:
|
| logger.status(f"Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
|
|
|
| if len(p.init_images) == 1:
|
|
|
| result = swap_face(
|
| self.source,
|
| p.init_images[0],
|
| source_faces_index=self.source_faces_index,
|
| faces_index=self.faces_index,
|
| model=self.model,
|
| gender_source=self.gender_source,
|
| gender_target=self.gender_target,
|
| face_model=self.face_model,
|
| faces_order=self.faces_order,
|
| face_boost_enabled=self.face_boost_enabled,
|
| face_restore_model=self.face_restore_model,
|
| face_restore_visibility=self.face_restore_visibility,
|
| codeformer_weight=self.codeformer_weight,
|
| interpolation=self.interpolation,
|
| )
|
| p.init_images[0] = result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| elif len(p.init_images) > 1:
|
| result = swap_face_many(
|
| self.source,
|
| p.init_images,
|
| source_faces_index=self.source_faces_index,
|
| faces_index=self.faces_index,
|
| model=self.model,
|
| gender_source=self.gender_source,
|
| gender_target=self.gender_target,
|
| face_model=self.face_model,
|
| faces_order=self.faces_order,
|
| face_boost_enabled=self.face_boost_enabled,
|
| face_restore_model=self.face_restore_model,
|
| face_restore_visibility=self.face_restore_visibility,
|
| codeformer_weight=self.codeformer_weight,
|
| interpolation=self.interpolation,
|
| )
|
| p.init_images = result
|
|
|
| logger.status("--Done!--")
|
|
|
|
|
|
|
| def postprocess_batch(self, p, *args, **kwargs):
|
| if self.enable:
|
| images = kwargs["images"]
|
|
|
| def postprocess_image(self, p, script_pp: scripts.PostprocessImageArgs, *args):
|
| if self.enable and self.swap_in_generated:
|
| if self.source is not None:
|
| logger.status(f"Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
|
| image: Image.Image = script_pp.image
|
| result = swap_face(
|
| self.source,
|
| image,
|
| source_faces_index=self.source_faces_index,
|
| faces_index=self.faces_index,
|
| model=self.model,
|
| upscale_options=self.upscale_options,
|
| gender_source=self.gender_source,
|
| gender_target=self.gender_target,
|
| )
|
| try:
|
| pp = scripts_postprocessing.PostprocessedImage(result)
|
| pp.info = {}
|
| p.extra_generation_params.update(pp.info)
|
| script_pp.image = pp.image
|
| except:
|
| logger.error(f"Cannot create a result image")
|
|
|