From 0901ab9ed431df122de767f1232c5d145564275b Mon Sep 17 00:00:00 2001
From: Gourieff <777@lovemet.ru>
Date: Sat, 16 Sep 2023 22:13:58 +0700
Subject: [PATCH] FIX: Many different
Different fixes and improvements
+VersionUP (beta1)
---
requirements.txt | 4 +-
scripts/reactor_api.py | 4 +-
scripts/reactor_faceswap.py | 60 ++++++---
scripts/reactor_helpers.py | 57 ++++++++
scripts/reactor_swapper.py | 261 ++++++++++++++++++++++--------------
scripts/reactor_version.py | 2 +-
6 files changed, 261 insertions(+), 127 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index b4c4fa8..ec0cdf7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
insightface==0.7.3
-onnx==1.14.0
-onnxruntime==1.15.0
+onnx>=1.14.0
+onnxruntime>=1.15.0
opencv-python>=4.7.0.72
diff --git a/scripts/reactor_api.py b/scripts/reactor_api.py
index ea3db93..1917075 100644
--- a/scripts/reactor_api.py
+++ b/scripts/reactor_api.py
@@ -14,7 +14,7 @@ from modules.api import api
import gradio as gr
-from scripts.reactor_swapper import UpscaleOptions, swap_face
+from scripts.reactor_swapper import EnhancementOptions, swap_face
from scripts.reactor_logger import logger
@@ -78,7 +78,7 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
gender_s = gender_source
gender_t = gender_target
restore_first_bool = True if restore_first == 1 else False
- up_options = UpscaleOptions(do_restore_first=restore_first_bool, scale=scale, upscaler=get_upscaler(upscaler), upscale_visibility=upscale_visibility,face_restorer=get_face_restorer(face_restorer),restorer_visibility=restorer_visibility)
+ up_options = EnhancementOptions(do_restore_first=restore_first_bool, scale=scale, upscaler=get_upscaler(upscaler), upscale_visibility=upscale_visibility,face_restorer=get_face_restorer(face_restorer),restorer_visibility=restorer_visibility)
use_model = get_full_model(model)
if use_model is None:
Exception("Model not found")
diff --git a/scripts/reactor_faceswap.py b/scripts/reactor_faceswap.py
index c68f511..eeeb31d 100644
--- a/scripts/reactor_faceswap.py
+++ b/scripts/reactor_faceswap.py
@@ -17,10 +17,10 @@ from modules.paths_internal import models_path
from modules.images import save_image
from scripts.reactor_logger import logger
-from scripts.reactor_swapper import UpscaleOptions, swap_face, check_process_halt, reset_messaged
+from scripts.reactor_swapper import EnhancementOptions, swap_face, check_process_halt, reset_messaged
from scripts.reactor_version import version_flag, app_title
from scripts.console_log_patch import apply_logging_patch
-from scripts.reactor_helpers import make_grid
+from scripts.reactor_helpers import make_grid, get_image_path
MODELS_PATH = None
@@ -51,7 +51,7 @@ class FaceSwapScript(scripts.Script):
with gr.Accordion(f"{app_title}", open=False):
with gr.Tab("Main"):
with gr.Column():
- img = gr.inputs.Image(type="pil")
+ img = gr.Image(type="pil")
enable = gr.Checkbox(False, label="Enable", info=f"The Fast and Simple FaceSwap Extension - {version_flag}")
save_original = gr.Checkbox(False, label="Save Original", info="Save the original image(s) made before swapping; If you use \"img2img\" - this option will affect with \"Swap in generated\" only")
gr.Markdown("
")
@@ -110,9 +110,11 @@ class FaceSwapScript(scripts.Script):
label="1. Restore Face -> 2. Upscale (-Uncheck- if you want vice versa)",
info="Postprocessing Order"
)
- upscaler_name = gr.inputs.Dropdown(
+ upscaler_name = gr.Dropdown(
choices=[upscaler.name for upscaler in shared.sd_upscalers],
label="Upscaler",
+ value="None",
+ info="Won't scale if you choose -Swap in Source- via img2img, only 1x-postprocessing will affect (texturing, denoising, restyling etc.)"
)
gr.Markdown("
")
with gr.Row():
@@ -127,13 +129,13 @@ class FaceSwapScript(scripts.Script):
logger.warning(
"You should at least have one model in models directory, please read the doc here : https://github.com/Gourieff/sd-webui-reactor/"
)
- model = gr.inputs.Dropdown(
+ model = gr.Dropdown(
choices=models,
label="Model not found, please download one and reload WebUI",
)
else:
- model = gr.inputs.Dropdown(
- choices=models, label="Model", default=models[0]
+ model = gr.Dropdown(
+ choices=models, label="Model", value=models[0]
)
console_logging_level = gr.Radio(
["No log", "Minimum", "Default"],
@@ -178,8 +180,8 @@ class FaceSwapScript(scripts.Script):
return None
@property
- def upscale_options(self) -> UpscaleOptions:
- return UpscaleOptions(
+ def enhancement_options(self) -> EnhancementOptions:
+ return EnhancementOptions(
do_restore_first = self.restore_first,
scale=self.upscaler_scale,
upscaler=self.upscaler,
@@ -253,17 +255,21 @@ class FaceSwapScript(scripts.Script):
for i in range(len(p.init_images)):
if len(p.init_images) > 1:
logger.info("Swap in %s", i)
- result = swap_face(
+ result, output, swapped = swap_face(
self.source,
p.init_images[i],
source_faces_index=self.source_faces_index,
faces_index=self.faces_index,
model=self.model,
- upscale_options=self.upscale_options,
+ enhancement_options=self.enhancement_options,
gender_source=self.gender_source,
gender_target=self.gender_target,
)
p.init_images[i] = result
+ # result_path = get_image_path(p.init_images[i], p.outpath_samples, "", p.all_seeds[i], p.all_prompts[i], "txt", p=p, suffix="-swapped")
+ # if len(output) != 0:
+ # with open(result_path, 'w', encoding="utf8") as f:
+ # f.writelines(output)
if shared.state.interrupted or shared.state.skipped:
return
@@ -286,6 +292,7 @@ class FaceSwapScript(scripts.Script):
orig_infotexts : List[str] = processed.infotexts[processed.index_of_first_image:]
result_images: List = processed.images
+ # result_info: List = processed.infotexts
if self.swap_in_generated:
logger.info("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
@@ -296,25 +303,31 @@ class FaceSwapScript(scripts.Script):
break
if len(orig_images) > 1:
logger.info("Swap in %s", i)
- result = swap_face(
+ result, output, swapped = swap_face(
self.source,
img,
source_faces_index=self.source_faces_index,
faces_index=self.faces_index,
model=self.model,
- upscale_options=self.upscale_options,
+ enhancement_options=self.enhancement_options,
gender_source=self.gender_source,
gender_target=self.gender_target,
)
- if result is not None:
- suffix = "-swapped"
+ if result is not None and swapped > 0:
result_images.append(result)
+ suffix = "-swapped"
try:
- save_image(result, p.outpath_samples, "", p.all_seeds[0], p.all_prompts[0], "png",info=info, p=p, suffix=suffix)
+ img_path = save_image(result, p.outpath_samples, "", p.all_seeds[0], p.all_prompts[0], "png",info=info, p=p, suffix=suffix)
except:
logger.error("Cannot save a result image - please, check SD WebUI Settings (Saving and Paths)")
- else:
+ elif result is None:
logger.error("Cannot create a result image")
+
+ # if len(output) != 0:
+ # split_fullfn = os.path.splitext(img_path[0])
+ # fullfn = split_fullfn[0] + ".txt"
+ # with open(fullfn, 'w', encoding="utf8") as f:
+ # f.writelines(output)
if shared.opts.return_grid and len(result_images) > 2 and postprocess_run:
grid = make_grid(result_images)
@@ -324,7 +337,8 @@ class FaceSwapScript(scripts.Script):
except:
logger.error("Cannot save a grid - please, check SD WebUI Settings (Saving and Paths)")
- processed.images = result_images
+ processed.images = result_images
+ # processed.infotexts = result_info
def postprocess_batch(self, p, *args, **kwargs):
if self.enable and not self.save_original:
@@ -343,13 +357,13 @@ class FaceSwapScript(scripts.Script):
if self.source is not None:
logger.info("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(
+ result, output, swapped = 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,
+ enhancement_options=self.enhancement_options,
gender_source=self.gender_source,
gender_target=self.gender_target,
)
@@ -358,5 +372,11 @@ class FaceSwapScript(scripts.Script):
pp.info = {}
p.extra_generation_params.update(pp.info)
script_pp.image = pp.image
+
+ # if len(output) != 0:
+ # result_path = get_image_path(script_pp.image, p.outpath_samples, "", p.all_seeds[0], p.all_prompts[0], "txt", p=p, suffix="-swapped")
+ # if len(output) != 0:
+ # with open(result_path, 'w', encoding="utf8") as f:
+ # f.writelines(output)
except:
logger.error("Cannot create a result image")
diff --git a/scripts/reactor_helpers.py b/scripts/reactor_helpers.py
index 672418b..f683c0a 100644
--- a/scripts/reactor_helpers.py
+++ b/scripts/reactor_helpers.py
@@ -1,8 +1,12 @@
+import os
from collections import Counter
from PIL import Image
from math import isqrt, ceil
from typing import List
+from modules.images import FilenameGenerator, get_next_sequence_number
+from modules import shared, script_callbacks
+
def make_grid(image_list: List):
# Count the occurrences of each image size in the image_list
@@ -43,3 +47,56 @@ def make_grid(image_list: List):
# Return None if there are no images or only one image in the image_list
return None
+
+def get_image_path(image, path, basename, seed=None, prompt=None, extension='png', p=None, suffix=""):
+
+ namegen = FilenameGenerator(p, seed, prompt, image)
+
+ save_to_dirs = shared.opts.save_to_dirs
+
+ if save_to_dirs:
+ dirname = namegen.apply(shared.opts.directories_filename_pattern or "[prompt_words]").lstrip(' ').rstrip('\\ /')
+ path = os.path.join(path, dirname)
+
+ os.makedirs(path, exist_ok=True)
+
+ if seed is None:
+ file_decoration = ""
+ elif shared.opts.save_to_dirs:
+ file_decoration = shared.opts.samples_filename_pattern or "[seed]"
+ else:
+ file_decoration = shared.opts.samples_filename_pattern or "[seed]-[prompt_spaces]"
+
+ file_decoration = namegen.apply(file_decoration) + suffix
+
+ add_number = shared.opts.save_images_add_number or file_decoration == ''
+
+ if file_decoration != "" and add_number:
+ file_decoration = f"-{file_decoration}"
+
+ if add_number:
+ basecount = get_next_sequence_number(path, basename)
+ fullfn = None
+ for i in range(500):
+ fn = f"{basecount + i:05}" if basename == '' else f"{basename}-{basecount + i:04}"
+ fullfn = os.path.join(path, f"{fn}{file_decoration}.{extension}")
+ if not os.path.exists(fullfn):
+ break
+ else:
+ fullfn = os.path.join(path, f"{file_decoration}.{extension}")
+
+ pnginfo = {}
+
+ params = script_callbacks.ImageSaveParams(image, p, fullfn, pnginfo)
+ # script_callbacks.before_image_saved_callback(params)
+
+ fullfn = params.filename
+
+ fullfn_without_extension, extension = os.path.splitext(params.filename)
+ if hasattr(os, 'statvfs'):
+ max_name_len = os.statvfs(path).f_namemax
+ fullfn_without_extension = fullfn_without_extension[:max_name_len - max(4, len(extension))]
+ params.filename = fullfn_without_extension + extension
+ fullfn = params.filename
+
+ return fullfn
diff --git a/scripts/reactor_swapper.py b/scripts/reactor_swapper.py
index 6bb0014..e83f7b4 100644
--- a/scripts/reactor_swapper.py
+++ b/scripts/reactor_swapper.py
@@ -8,7 +8,6 @@ import numpy as np
from PIL import Image
import insightface
-import onnxruntime
from modules.face_restoration import FaceRestoration
from modules.upscaler import UpscalerData
@@ -21,11 +20,11 @@ import warnings
np.warnings = warnings
np.warnings.filterwarnings('ignore')
-providers = onnxruntime.get_available_providers()
+providers = ["CPUExecutionProvider"]
@dataclass
-class UpscaleOptions:
+class EnhancementOptions:
do_restore_first: bool = True
scale: int = 1
upscaler: UpscalerData = None
@@ -34,24 +33,6 @@ class UpscaleOptions:
restorer_visibility: float = 0.5
-def cosine_distance(vector1: np.ndarray, vector2: np.ndarray) -> float:
- vec1 = vector1.flatten()
- vec2 = vector2.flatten()
-
- dot_product = np.dot(vec1, vec2)
- norm1 = np.linalg.norm(vec1)
- norm2 = np.linalg.norm(vec2)
-
- cosine_distance = 1 - (dot_product / (norm1 * norm2))
- return cosine_distance
-
-
-def cosine_similarity(test_vec: np.ndarray, source_vecs: List[np.ndarray]) -> float:
- cos_dist = sum(cosine_distance(test_vec, source_vec) for source_vec in source_vecs)
- average_cos_dist = cos_dist / len(source_vecs)
- return average_cos_dist
-
-
MESSAGED_STOPPED = False
MESSAGED_SKIPPED = False
@@ -102,76 +83,88 @@ def getFaceSwapModel(model_path: str):
return FS_MODEL
-def upscale_image(image: Image, upscale_options: UpscaleOptions):
+def restore_face(image: Image, enhancement_options: EnhancementOptions):
+ result_image = image
+
+ if check_process_halt(msgforced=True):
+ return result_image
+
+ if enhancement_options.face_restorer is not None:
+ original_image = result_image.copy()
+ logger.info("Restoring the face with %s", enhancement_options.face_restorer.name())
+ numpy_image = np.array(result_image)
+ numpy_image = enhancement_options.face_restorer.restore(numpy_image)
+ restored_image = Image.fromarray(numpy_image)
+ result_image = Image.blend(
+ original_image, restored_image, enhancement_options.restorer_visibility
+ )
+
+ return result_image
+
+def upscale_image(image: Image, enhancement_options: EnhancementOptions):
+ result_image = image
+
+ if check_process_halt(msgforced=True):
+ return result_image
+
+ if enhancement_options.upscaler is not None and enhancement_options.upscaler.name != "None":
+ original_image = result_image.copy()
+ logger.info(
+ "Upscaling with %s scale = %s",
+ enhancement_options.upscaler.name,
+ enhancement_options.scale,
+ )
+ result_image = enhancement_options.upscaler.scaler.upscale(
+ original_image, enhancement_options.scale, enhancement_options.upscaler.data_path
+ )
+ if enhancement_options.scale == 1:
+ result_image = Image.blend(
+ original_image, result_image, enhancement_options.upscale_visibility
+ )
+
+ return result_image
+
+def enhance_image(image: Image, enhancement_options: EnhancementOptions):
result_image = image
if check_process_halt(msgforced=True):
return result_image
- if upscale_options.do_restore_first:
- if upscale_options.face_restorer is not None:
- original_image = result_image.copy()
- logger.info("Restoring the face with %s", upscale_options.face_restorer.name())
- numpy_image = np.array(result_image)
- numpy_image = upscale_options.face_restorer.restore(numpy_image)
- restored_image = Image.fromarray(numpy_image)
- result_image = Image.blend(
- original_image, restored_image, upscale_options.restorer_visibility
- )
- if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
- original_image = result_image.copy()
- logger.info(
- "Upscaling with %s scale = %s",
- upscale_options.upscaler.name,
- upscale_options.scale,
- )
- result_image = upscale_options.upscaler.scaler.upscale(
- original_image, upscale_options.scale, upscale_options.upscaler.data_path
- )
- if upscale_options.scale == 1:
- result_image = Image.blend(
- original_image, result_image, upscale_options.upscale_visibility
- )
+ if enhancement_options.do_restore_first:
+
+ result_image = restore_face(result_image, enhancement_options)
+ result_image = upscale_image(result_image, enhancement_options)
+
else:
- if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
- original_image = result_image.copy()
- logger.info(
- "Upscaling with %s scale = %s",
- upscale_options.upscaler.name,
- upscale_options.scale,
- )
- result_image = upscale_options.upscaler.scaler.upscale(
- image, upscale_options.scale, upscale_options.upscaler.data_path
- )
- if upscale_options.scale == 1:
- result_image = Image.blend(
- original_image, result_image, upscale_options.upscale_visibility
- )
- if upscale_options.face_restorer is not None:
- original_image = result_image.copy()
- logger.info("Restoring the face with %s", upscale_options.face_restorer.name())
- numpy_image = np.array(result_image)
- numpy_image = upscale_options.face_restorer.restore(numpy_image)
- restored_image = Image.fromarray(numpy_image)
- result_image = Image.blend(
- original_image, restored_image, upscale_options.restorer_visibility
- )
+
+ result_image = upscale_image(result_image, enhancement_options)
+ result_image = restore_face(result_image, enhancement_options)
return result_image
-
-def get_face_gender(
- face,
- face_index,
- gender_condition,
- operated: str
-):
+def get_gender(face, face_index):
gender = [
x.sex
for x in face
]
gender.reverse()
- face_gender = gender[face_index]
+ try:
+ face_gender = gender[face_index]
+ except:
+ logger.error("Gender Detection: No face with index = %s was found", face_index)
+ return "None"
+ return face_gender
+
+def get_face_gender(
+ face,
+ face_index,
+ gender_condition,
+ operated: str,
+ gender_detected,
+):
+ face_gender = gender_detected
+ if face_gender == "None":
+ return None, 0
logger.info("%s Face %s: Detected Gender -%s-", operated, face_index, face_gender)
if (gender_condition == 1 and face_gender == "F") or (gender_condition == 2 and face_gender == "M"):
logger.info("OK - Detected Gender matches Condition")
@@ -183,10 +176,22 @@ def get_face_gender(
logger.info("WRONG - Detected Gender doesn't match Condition")
return sorted(face, key=lambda x: x.bbox[0])[face_index], 1
+def get_face_age(face, face_index):
+ age = [
+ x.age
+ for x in face
+ ]
+ age.reverse()
+ try:
+ face_age = age[face_index]
+ except:
+ logger.error("Age Detection: No face with index = %s was found", face_index)
+ return "None"
+ return face_age
-def reget_face_single(img_data, det_size, face_index):
+def reget_face_single(img_data, det_size, face_index, gender_source, gender_target):
det_size_half = (det_size[0] // 2, det_size[1] // 2)
- return get_face_single(img_data, face_index=face_index, det_size=det_size_half)
+ return get_face_single(img_data, face_index=face_index, det_size=det_size_half, gender_source=gender_source, gender_target=gender_target)
def get_face_single(img_data: np.ndarray, face_index=0, det_size=(640, 640), gender_source=0, gender_target=0):
@@ -198,23 +203,39 @@ def get_face_single(img_data: np.ndarray, face_index=0, det_size=(640, 640), gen
if os.path.exists(buffalo_path):
os.remove(buffalo_path)
+ face_age = "None"
+ try:
+ face_age = get_face_age(face, face_index)
+ except:
+ logger.error("Cannot detect any Age for Face index = %s", face_index)
+
+ face_gender = "None"
+ try:
+ face_gender = get_gender(face, face_index)
+ gender_detected = face_gender
+ face_gender = "Female" if face_gender == "F" else ("Male" if face_gender == "M" else "None")
+ except:
+ logger.error("Cannot detect any Gender for Face index = %s", face_index)
+
if gender_source != 0:
if len(face) == 0 and det_size[0] > 320 and det_size[1] > 320:
- return reget_face_single(img_data, det_size, face_index)
- return get_face_gender(face,face_index,gender_source,"Source")
+ return reget_face_single(img_data, det_size, face_index, gender_source, gender_target)
+ faces, wrong_gender = get_face_gender(face,face_index,gender_source,"Source",gender_detected)
+ return faces, wrong_gender, face_age, face_gender
if gender_target != 0:
if len(face) == 0 and det_size[0] > 320 and det_size[1] > 320:
- return reget_face_single(img_data, det_size, face_index)
- return get_face_gender(face,face_index,gender_target,"Target")
+ return reget_face_single(img_data, det_size, face_index, gender_source, gender_target)
+ faces, wrong_gender = get_face_gender(face,face_index,gender_target,"Target",gender_detected)
+ return faces, wrong_gender, face_age, face_gender
if len(face) == 0 and det_size[0] > 320 and det_size[1] > 320:
- return reget_face_single(img_data, det_size, face_index)
+ return reget_face_single(img_data, det_size, face_index, gender_source, gender_target)
try:
- return sorted(face, key=lambda x: x.bbox[0])[face_index], 0
+ return sorted(face, key=lambda x: x.bbox[0])[face_index], 0, face_age, face_gender
except IndexError:
- return None, 0
+ return None, 0, face_age, face_gender
def swap_face(
@@ -223,7 +244,7 @@ def swap_face(
model: Union[str, None] = None,
source_faces_index: List[int] = [0],
faces_index: List[int] = [0],
- upscale_options: Union[UpscaleOptions, None] = None,
+ enhancement_options: Union[EnhancementOptions, None] = None,
gender_source: int = 0,
gender_target: int = 0,
):
@@ -250,52 +271,88 @@ def swap_face(
source_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
target_img = cv2.cvtColor(np.array(target_img), cv2.COLOR_RGB2BGR)
- source_face, wrong_gender = get_face_single(source_img, face_index=source_faces_index[0], gender_source=gender_source)
+ output: List = []
+ output_info: str = ""
+ swapped = 0
+
+ logger.info("Detecting Source Face, Index = %s", source_faces_index[0])
+ source_face, wrong_gender, source_age, source_gender = get_face_single(source_img, face_index=source_faces_index[0], gender_source=gender_source)
+ if source_age != "None" or source_gender != "None":
+ logger.info("Detected: -%s- y.o. %s", source_age, source_gender)
+
+ output_info = f"SourceFaceIndex={source_faces_index[0]};Age={source_age};Gender={source_gender}\n"
+ output.append(output_info)
if len(source_faces_index) != 0 and len(source_faces_index) != 1 and len(source_faces_index) != len(faces_index):
logger.info("Source Faces must have no entries (default=0), one entry, or same number of entries as target faces.")
elif source_face is not None:
-
+
result = target_img
face_swapper = getFaceSwapModel(model)
source_face_idx = 0
- swapped = 0
-
for face_num in faces_index:
if len(source_faces_index) > 1 and source_face_idx > 0:
- source_face, wrong_gender = get_face_single(source_img, face_index=source_faces_index[source_face_idx], gender_source=gender_source)
+
+ logger.info("Detecting Source Face, Index = %s", source_faces_index[source_face_idx])
+ source_face, wrong_gender, source_age, source_gender = get_face_single(source_img, face_index=source_faces_index[source_face_idx], gender_source=gender_source)
+ if source_age != "None" or source_gender != "None":
+ logger.info("Detected: -%s- y.o. %s", source_age, source_gender)
+
+ output_info = f"SourceFaceIndex={source_faces_index[source_face_idx]};Age={source_age};Gender={source_gender}\n"
+ output.append(output_info)
+
source_face_idx += 1
if source_face is not None and wrong_gender == 0:
- target_face, wrong_gender = get_face_single(target_img, face_index=face_num, gender_target=gender_target)
+ logger.info("Detecting Target Face, Index = %s", face_num)
+ target_face, wrong_gender, target_age, target_gender = get_face_single(target_img, face_index=face_num, gender_target=gender_target)
+ if target_age != "None" or target_gender != "None":
+ logger.info("Detected: -%s- y.o. %s", target_age, target_gender)
+
+ output_info = f"TargetFaceIndex={face_num};Age={target_age};Gender={target_gender}\n"
+ output.append(output_info)
+
if target_face is not None and wrong_gender == 0:
+ logger.info("Swapping Source into Target")
result = face_swapper.get(result, target_face, source_face)
swapped += 1
+
elif wrong_gender == 1:
wrong_gender = 0
+
if source_face_idx == len(source_faces_index):
result_image = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
- if upscale_options is not None:
- result_image = upscale_image(result_image, upscale_options)
- return result_image
+
+ if enhancement_options is not None and len(source_faces_index) > 1:
+ result_image = enhance_image(result_image, enhancement_options)
+
+ return result_image, output, swapped
+
else:
logger.info(f"No target face found for {face_num}")
+
elif wrong_gender == 1:
wrong_gender = 0
+
if source_face_idx == len(source_faces_index):
result_image = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
- if upscale_options is not None:
- result_image = upscale_image(result_image, upscale_options)
- return result_image
+
+ if enhancement_options is not None and len(source_faces_index) > 1:
+ result_image = enhance_image(result_image, enhancement_options)
+
+ return result_image, output, swapped
+
else:
logger.info(f"No source face found for face number {source_face_idx}.")
result_image = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
- if upscale_options is not None and swapped > 0:
- result_image = upscale_image(result_image, upscale_options)
+
+ if enhancement_options is not None and swapped > 0:
+ result_image = enhance_image(result_image, enhancement_options)
else:
logger.info("No source face(s) found")
- return result_image
+
+ return result_image, output, swapped
diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py
index afa1304..a8e5920 100644
--- a/scripts/reactor_version.py
+++ b/scripts/reactor_version.py
@@ -1,5 +1,5 @@
app_title = "ReActor"
-version_flag = "v0.4.1"
+version_flag = "v0.4.2-b1"
from scripts.reactor_logger import logger, get_Run, set_Run