From c745fa2911d1d75c75a1490f7c1e4fc61bc6467f Mon Sep 17 00:00:00 2001 From: Art Gourieff <85128026+Gourieff@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:26:57 +0700 Subject: [PATCH] UPDATE: Force Upscale even if no face FR #116 --- README.md | 6 +++++- README_RU.md | 6 +++++- example/api_example.py | 1 + example/api_external.curl | 3 ++- example/api_external.json | 3 ++- reactor_ui/reactor_upscale_ui.py | 20 ++++++++++++++------ scripts/reactor_api.py | 8 +++++--- scripts/reactor_faceswap.py | 17 ++++++++++++++--- scripts/reactor_swapper.py | 3 ++- scripts/reactor_version.py | 2 +- 10 files changed, 51 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index c9ba481..672e137 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ logo - ![Version](https://img.shields.io/badge/version-0.6.1_beta2-green?style=for-the-badge&labelColor=darkgreen) + ![Version](https://img.shields.io/badge/version-0.6.1_beta3-green?style=for-the-badge&labelColor=darkgreen) Support Me on Boosty @@ -40,6 +40,10 @@ ## What's new in the latest updates +### 0.6.1 BETA3 + +- 'Force Upscale' option inside the 'Upscale' tab: ReActor will run the Upscaler even if there's no face is detected (FR https://github.com/Gourieff/sd-webui-reactor/issues/116) + ### 0.6.1 BETA2 - 'Save original' option works fine now when you select 'Multiple Images' or 'Source Folder' diff --git a/README_RU.md b/README_RU.md index 6154eb2..f595cc6 100644 --- a/README_RU.md +++ b/README_RU.md @@ -2,7 +2,7 @@ logo - ![Version](https://img.shields.io/badge/версия-0.6.1_beta2-green?style=for-the-badge&labelColor=darkgreen) + ![Version](https://img.shields.io/badge/версия-0.6.1_beta3-green?style=for-the-badge&labelColor=darkgreen) Поддержать проект на Boosty @@ -39,6 +39,10 @@ ## Что нового в последних обновлениях +### 0.6.1 BETA3 + +- Опция 'Force Upscale' внутри вкладки 'Upscale': апскейл выполнится, даже если не было обнаружено ни одного лица (FR https://github.com/Gourieff/sd-webui-reactor/issues/116) + ### 0.6.1 BETA2 - Опция 'Save original' теперь работает правильно, когда вы выбираете 'Multiple Images' или 'Source Folder' diff --git a/example/api_example.py b/example/api_example.py index 3c9e3c4..f683ee5 100644 --- a/example/api_example.py +++ b/example/api_example.py @@ -49,6 +49,7 @@ "C:\PATH_TO_FACES_IMAGES", #24 The path to the folder containing source faces images, don't forger to set #22 to 2 None, #25 skip it for API True, #26 Randomly select an image from the path + True, #27 Force Upscale even if no face found ] # The args for ReActor can be found by diff --git a/example/api_external.curl b/example/api_external.curl index 4033d84..4c096e7 100644 --- a/example/api_external.curl +++ b/example/api_external.curl @@ -24,5 +24,6 @@ curl -X POST \ "select_source": 1, "face_model": "elena.safetensors", "source_folder": "C:/faces", - "random_image": 1 + "random_image": 1, + "upscale_force": 1 }' diff --git a/example/api_external.json b/example/api_external.json index 542da69..d483c4f 100644 --- a/example/api_external.json +++ b/example/api_external.json @@ -20,5 +20,6 @@ "select_source": 1, "face_model": "elena.safetensors", "source_folder": "C:/faces", - "random_image": 1 + "random_image": 1, + "upscale_force": 1 } \ No newline at end of file diff --git a/reactor_ui/reactor_upscale_ui.py b/reactor_ui/reactor_upscale_ui.py index 71216a4..f5256d8 100644 --- a/reactor_ui/reactor_upscale_ui.py +++ b/reactor_ui/reactor_upscale_ui.py @@ -9,11 +9,19 @@ def update_upscalers_list(selected: str): # TAB UPSCALE def show(show_br: bool = True): with gr.Tab("Upscale"): - restore_first = gr.Checkbox( - True, - label="1. Restore Face -> 2. Upscale (-Uncheck- if you want vice versa)", - info="Postprocessing Order" - ) + with gr.Row(): + restore_first = gr.Checkbox( + True, + label="1. Restore Face -> 2. Upscale (-Uncheck- if you want vice versa)", + info="Postprocessing Order", + scale=2 + ) + upscale_force = gr.Checkbox( + False, + label="Force Upscale", + info="Upscale anyway - even if no face found", + scale=1 + ) with gr.Row(): upscaler_name = gr.Dropdown( choices=[upscaler.name for upscaler in shared.sd_upscalers], @@ -36,4 +44,4 @@ def show(show_br: bool = True): upscaler_visibility = gr.Slider( 0, 1, 1, step=0.1, label="Upscaler Visibility (if scale = 1)" ) - return restore_first, upscaler_name, upscaler_scale, upscaler_visibility \ No newline at end of file + return restore_first, upscaler_name, upscaler_scale, upscaler_visibility, upscale_force diff --git a/scripts/reactor_api.py b/scripts/reactor_api.py index 6e0b69c..c38ad13 100644 --- a/scripts/reactor_api.py +++ b/scripts/reactor_api.py @@ -1,7 +1,7 @@ ''' Thanks SpenserCai for the original version of the roop api script ----------------------------------- ---- ReActor External API v1.0.3 --- +--- ReActor External API v1.0.4 --- ----------------------------------- ''' import os, glob @@ -76,7 +76,8 @@ async def reactor_image( select_source: int = Body(0,title="Select Source, 0 - Image, 1 - Face Model, 2 - Source Folder"), face_model: str = Body("None",title="Filename of the face model (from 'models/reactor/faces'), e.g. elena.safetensors"), source_folder: str = Body("",title="The path to the folder containing source faces images"), - random_image: int = Body(0,title="Randomly select an image from the path") + random_image: int = Body(0,title="Randomly select an image from the path"), + upscale_force: int = Body(0,title="Force Upscale even if no face found") ): s_image = api.decode_base64_to_image(source_image) if select_source == 0 else None t_image = api.decode_base64_to_image(target_image) @@ -87,7 +88,8 @@ async def reactor_image( restore_first_bool = True if restore_first == 1 else False mask_face = True if mask_face == 1 else False random_image = False if random_image == 0 else True - 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,codeformer_weight=codeformer_weight) + upscale_force = False if upscale_force == 0 else True + 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,codeformer_weight=codeformer_weight,upscale_force=upscale_force) 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 61adcf0..cb4b9dd 100644 --- a/scripts/reactor_faceswap.py +++ b/scripts/reactor_faceswap.py @@ -66,7 +66,7 @@ def ui(self, is_img2img): img, imgs, select_source, face_model, source_folder, save_original, mask_face, source_faces_index, gender_source, faces_index, gender_target, face_restorer_name, face_restorer_visibility, codeformer_weight, swap_in_source, swap_in_generated, random_image = ui_main.show(is_img2img=is_img2img, **msgs) # TAB UPSCALE - restore_first, upscaler_name, upscaler_scale, upscaler_visibility = ui_upscale.show() + restore_first, upscaler_name, upscaler_scale, upscaler_visibility, upscale_force = ui_upscale.show() # TAB TOOLS ui_tools.show() @@ -104,6 +104,7 @@ def ui(self, is_img2img): source_folder, imgs, random_image, + upscale_force ] @@ -124,13 +125,14 @@ def face_restorer(self) -> FaceRestoration: @property def enhancement_options(self) -> EnhancementOptions: return EnhancementOptions( - do_restore_first = self.restore_first, + do_restore_first=self.restore_first, scale=self.upscaler_scale, upscaler=self.upscaler, face_restorer=self.face_restorer, upscale_visibility=self.upscaler_visibility, restorer_visibility=self.face_restorer_visibility, codeformer_weight=self.codeformer_weight, + upscale_force=self.upscale_force ) def process( @@ -163,6 +165,7 @@ def process( source_folder, imgs, random_image, + upscale_force, ): self.enable = enable if self.enable: @@ -198,6 +201,7 @@ def process( self.source_folder = source_folder self.source_imgs = imgs self.random_image = random_image + self.upscale_force = upscale_force if self.gender_source is None or self.gender_source == "No": self.gender_source = 0 if self.gender_target is None or self.gender_target == "No": @@ -222,6 +226,8 @@ def process( self.mask_face = False if self.random_image is None: self.random_image = False + if self.upscale_force is None: + self.upscale_force = False logger.debug("*** Set Device") set_Device(self.device) @@ -444,7 +450,7 @@ def ui(self): img, imgs, select_source, face_model, source_folder, save_original, mask_face, source_faces_index, gender_source, faces_index, gender_target, face_restorer_name, face_restorer_visibility, codeformer_weight, swap_in_source, swap_in_generated, random_image = ui_main.show(is_img2img=False, show_br=False, **msgs) # TAB UPSCALE - restore_first, upscaler_name, upscaler_scale, upscaler_visibility = ui_upscale.show(show_br=False) + restore_first, upscaler_name, upscaler_scale, upscaler_visibility, upscale_force = ui_upscale.show(show_br=False) # TAB TOOLS ui_tools.show() @@ -477,6 +483,7 @@ def ui(self): 'source_folder': source_folder, 'imgs': imgs, 'random_image': random_image, + 'upscale_force': upscale_force, } return args @@ -504,6 +511,7 @@ def enhancement_options(self) -> EnhancementOptions: upscale_visibility=self.upscaler_visibility, restorer_visibility=self.face_restorer_visibility, codeformer_weight=self.codeformer_weight, + upscale_force=self.upscale_force, ) def process(self, pp: scripts_postprocessing.PostprocessedImage, **args): @@ -532,6 +540,7 @@ def process(self, pp: scripts_postprocessing.PostprocessedImage, **args): self.source_folder = args['source_folder'] self.source_imgs = args['imgs'] self.random_image = args['random_image'] + self.upscale_force = args['upscale_force'] if self.gender_source is None or self.gender_source == "No": self.gender_source = 0 if self.gender_target is None or self.gender_target == "No": @@ -550,6 +559,8 @@ def process(self, pp: scripts_postprocessing.PostprocessedImage, **args): self.mask_face = False if self.random_image is None: self.random_image = False + if self.upscale_force is None: + self.upscale_force = False current_job_number = shared.state.job_no + 1 job_count = shared.state.job_count diff --git a/scripts/reactor_swapper.py b/scripts/reactor_swapper.py index 6d771ee..9a9641f 100644 --- a/scripts/reactor_swapper.py +++ b/scripts/reactor_swapper.py @@ -64,6 +64,7 @@ class EnhancementOptions: face_restorer: FaceRestoration = None restorer_visibility: float = 0.5 codeformer_weight: float = 0.5 + upscale_force: bool = False MESSAGED_STOPPED = False @@ -713,7 +714,7 @@ def operate( result_image = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_BGR2RGB)) - if enhancement_options is not None and swapped > 0: + if (enhancement_options is not None and swapped > 0) or enhancement_options.upscale_force: if mask_face and entire_mask_image is not None: result_image = enhance_image_and_mask(result_image, enhancement_options,Image.fromarray(target_img_orig),Image.fromarray(entire_mask_image).convert("L")) else: diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py index e119b0b..0728bcd 100644 --- a/scripts/reactor_version.py +++ b/scripts/reactor_version.py @@ -1,5 +1,5 @@ app_title = "ReActor" -version_flag = "v0.6.1-b2" +version_flag = "v0.6.1-b3" from scripts.reactor_logger import logger, get_Run, set_Run from scripts.reactor_globals import DEVICE