16 Commits

Author SHA1 Message Date
Tran Xen 9977168136 Merge pull request #68 from glucauze/v1.2.4
V1.2.4 :

Fix default settings by marking only managed field as do_not_save.

See the discussion here : #62
2023-08-24 19:35:23 +02:00
Tran Xen 2e718ee4ae fix default settings by not marking non managed fields as do_not_save 2023-08-24 19:20:31 +02:00
Tran Xen d0c56ae6ef remove override_settings in inpainting i2i_pp.py as they are not supported in some cases, i.e. sdnext for return_mask_composite and cause bugs 2023-08-24 15:47:24 +02:00
Tran Xen c4badb7894 Merge pull request #66 from glucauze/v1.2.3
fix install
2023-08-24 10:02:25 +02:00
Tran Xen 54adcc0fc6 fix install 2023-08-24 09:54:57 +02:00
Tran Xen a6ccd6fd40 Merge pull request #63 from glucauze/v1.2.3
change model link
2023-08-23 18:00:51 +02:00
Tran Xen b11037173b change model link 2023-08-23 18:00:08 +02:00
Tran Xen abdcf4a494 Merge pull request #61 from glucauze/v1.2.3
speed up ui, BREAKING : see changelog
2023-08-23 14:21:52 +02:00
Tran Xen 6ba60f6332 speed up ui, BREAKING : see changelog 2023-08-23 14:16:03 +02:00
Tran Xen 6d69f69509 speed up ui, BREAKING : see changelog 2023-08-23 14:14:21 +02:00
Tran Xen 32eeed8bd7 Merge pull request #57 from glucauze/v1.2.2a
change model url
2023-08-21 22:23:54 +02:00
Tran Xen 7830eb1da9 change model url 2023-08-21 22:21:55 +02:00
Tran Xen d1a82d520d Merge pull request #53 from glucauze/v1.2.2a
remove javascript since it's not really relevant to the extension
2023-08-17 23:51:32 +02:00
Tran Xen aba00ba381 remove javascript, use https://github.com/w-e-w/sdwebui-close-confirmation-dialogue.git instead 2023-08-17 23:46:33 +02:00
Tran Xen 272dca83b8 Merge pull request #49 from glucauze/v1.2.2a
fix bug in improved mask
2023-08-17 12:14:20 +02:00
Tran Xen 04a0a5c46c fix bug in improved mask 2023-08-17 10:41:04 +02:00
16 changed files with 110 additions and 67 deletions
+4 -4
View File
@@ -1,8 +1,4 @@
repos: repos:
- repo: https://github.com/psf/black
rev: 23.7.0
hooks:
- id: black
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0 rev: v4.4.0
hooks: hooks:
@@ -11,3 +7,7 @@ repos:
- id: check-docstring-first - id: check-docstring-first
- id: detect-private-key - id: detect-private-key
- id: fix-byte-order-marker - id: fix-byte-order-marker
- repo: https://github.com/psf/black
rev: 23.7.0
hooks:
- id: black
+16
View File
@@ -1,3 +1,19 @@
# 1.2.3
Speed up ui : change the way default settings are manage by not storing them in ui-config.json
Migration : YOU NEED TO recreate ui-config.json (delete) or at least remove any faceswaplab reference to be able to use default settings again.
See this for explainations : https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/6109
# 1.2.2
+ Add NSFW filter option in settings (1 == disable)
+ Improve install speed
+ Install gpu requirements by default if --use-cpu is not used
+ Fix improved mask + color correction
+ Remove javascript, use https://github.com/w-e-w/sdwebui-close-confirmation-dialogue.git instead to prevent gradio from closing.
# 1.2.1 : # 1.2.1 :
Add GPU support option : see https://github.com/glucauze/sd-webui-faceswaplab/pull/24 Add GPU support option : see https://github.com/glucauze/sd-webui-faceswaplab/pull/24
+6
View File
@@ -1,7 +1,13 @@
# FaceSwapLab for a1111/Vlad # FaceSwapLab for a1111/Vlad
V1.2.3 : Breaking change for settings, please read changelog.
Please read the documentation here : https://glucauze.github.io/sd-webui-faceswaplab/ Please read the documentation here : https://glucauze.github.io/sd-webui-faceswaplab/
You can also read the [doc discussion section](https://github.com/glucauze/sd-webui-faceswaplab/discussions/categories/guide-doc)
See [CHANGELOG.md](CHANGELOG.md) for changes in last versions.
FaceSwapLab is an extension for Stable Diffusion that simplifies face-swapping. It has evolved from sd-webui-faceswap and some part of sd-webui-roop. However, a substantial amount of the code has been rewritten to improve performance and to better manage masks. FaceSwapLab is an extension for Stable Diffusion that simplifies face-swapping. It has evolved from sd-webui-faceswap and some part of sd-webui-roop. However, a substantial amount of the code has been rewritten to improve performance and to better manage masks.
Some key features include the ability to reuse faces via checkpoints, multiple face units, batch process images, sort faces based on size or gender, and support for vladmantic. It also provides a face inpainting feature. Some key features include the ability to reuse faces via checkpoints, multiple face units, batch process images, sort faces based on size or gender, and support for vladmantic. It also provides a face inpainting feature.
+2
View File
@@ -5,6 +5,8 @@ permalink: /doc/
toc: true toc: true
--- ---
You can also read the [doc discussion section](https://github.com/glucauze/sd-webui-faceswaplab/discussions/categories/guide-doc)
## TLDR: I Just Want Good Results: ## TLDR: I Just Want Good Results:
1. Put a face in the reference. 1. Put a face in the reference.
+8 -2
View File
@@ -2,12 +2,18 @@ import launch
import os import os
import sys import sys
import pkg_resources import pkg_resources
from modules import shared
from packaging.version import parse from packaging.version import parse
def check_install() -> None: def check_install() -> None:
use_gpu = not getattr(shared.cmd_opts, "use-cpu", False) use_gpu = True
try:
from modules import shared
use_gpu = not getattr(shared.cmd_opts, "use-cpu", False)
except:
# On some platform previous lines may failed (modules.shared not initialized), just ignore and use GPU requirements
pass
if use_gpu and sys.platform != "darwin": if use_gpu and sys.platform != "darwin":
print("Faceswaplab : Use GPU requirements") print("Faceswaplab : Use GPU requirements")
-4
View File
@@ -1,4 +0,0 @@
window.onbeforeunload = function() {
// Prevent the stable diffusion window from being closed by mistake
return "Are you sure ?";
};
-5
View File
@@ -8,8 +8,3 @@ def preload(parser: ArgumentParser) -> None:
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
help="Set the log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)", help="Set the log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)",
) )
parser.add_argument(
"--faceswaplab_gpu",
action="store_true",
help="Enable GPU if set, disable if not set",
)
+1 -1
View File
@@ -20,7 +20,7 @@ def check_configuration() -> None:
models_dir = MODELS_DIR models_dir = MODELS_DIR
faces_dir = FACES_DIR faces_dir = FACES_DIR
model_url = "https://huggingface.co/henryruhs/roop/resolve/main/inswapper_128.onnx" model_url = "https://github.com/facefusion/facefusion-assets/releases/download/models/inswapper_128.onnx"
model_name = os.path.basename(model_url) model_name = os.path.basename(model_url)
model_path = os.path.join(models_dir, model_name) model_path = os.path.join(models_dir, model_name)
+4 -1
View File
@@ -109,7 +109,10 @@ class FaceSwapScript(scripts.Script):
components += faceswaplab_unit_ui.faceswap_unit_ui(is_img2img, i) components += faceswaplab_unit_ui.faceswap_unit_ui(is_img2img, i)
post_processing = faceswaplab_tab.postprocessing_ui() post_processing = faceswaplab_tab.postprocessing_ui()
# If the order is modified, the before_process should be changed accordingly. # If the order is modified, the before_process should be changed accordingly.
return components + post_processing
components = components + post_processing
return components
def read_config( def read_config(
self, p: StableDiffusionProcessing, *components: Tuple[Any, ...] self, p: StableDiffusionProcessing, *components: Tuple[Any, ...]
+1 -1
View File
@@ -16,7 +16,7 @@ REFERENCE_PATH = os.path.join(
) )
# Defining the version flag for the application # Defining the version flag for the application
VERSION_FLAG: str = "v1.2.2" VERSION_FLAG: str = "v1.2.4"
# Defining the path for 'sd-webui-faceswaplab' inside the 'extensions' directory # Defining the path for 'sd-webui-faceswaplab' inside the 'extensions' directory
EXTENSION_PATH = os.path.join("extensions", "sd-webui-faceswaplab") EXTENSION_PATH = os.path.join("extensions", "sd-webui-faceswaplab")
+11 -9
View File
@@ -63,16 +63,18 @@ inpainting_steps : {options.inpainting_steps}
"prompt": prompt, "prompt": prompt,
"negative_prompt": negative_prompt, "negative_prompt": negative_prompt,
"denoising_strength": options.inpainting_denoising_strengh, "denoising_strength": options.inpainting_denoising_strengh,
"override_settings": {
"return_mask_composite": False,
"save_images_before_face_restoration": False,
"save_images_before_highres_fix": False,
"save_images_before_color_correction": False,
"save_mask": False,
"save_mask_composite": False,
"samples_save": False,
},
} }
# Remove the following as they are not always supported on all platform :
# "override_settings": {
# "return_mask_composite": False,
# "save_images_before_face_restoration": False,
# "save_images_before_highres_fix": False,
# "save_images_before_color_correction": False,
# "save_mask": False,
# "save_mask_composite": False,
# "samples_save": False,
# },
current_model_checkpoint = shared.opts.sd_model_checkpoint current_model_checkpoint = shared.opts.sd_model_checkpoint
if options.inpainting_model and options.inpainting_model != "Current": if options.inpainting_model and options.inpainting_model != "Current":
# Change checkpoint # Change checkpoint
@@ -216,18 +216,11 @@ class UpscaledINSwapper(INSwapper):
bgr_fake, inswapper_options=options, k=k bgr_fake, inswapper_options=options, k=k
) )
if options.improved_mask: fake_diff: CV2ImgU8 = None # type: ignore
if k == 1:
logger.warning(
"Please note that improved mask does not work well without upscaling. Set upscaling to Lanczos at least if you want speed and want to use improved mask."
)
logger.info("improved_mask") if not options.improved_mask:
mask = get_face_mask(aimg, bgr_fake) # If improved mask is not used, we should compute before sharpen and color correction (better diff)
bgr_fake = merge_images_with_mask(aimg, bgr_fake, mask) fake_diff = compute_diff(bgr_fake, aimg=aimg)
# compute fake_diff before sharpen and color correction (better result)
fake_diff = compute_diff(bgr_fake, aimg)
if options.sharpen: if options.sharpen:
logger.info("sharpen") logger.info("sharpen")
@@ -244,6 +237,24 @@ class UpscaledINSwapper(INSwapper):
) )
bgr_fake = pil_to_cv2(bgr_fake_pil) bgr_fake = pil_to_cv2(bgr_fake_pil)
if options.improved_mask:
if k == 1:
logger.warning(
"Please note that improved mask does not work well without upscaling. Set upscaling to Lanczos at least if you want speed and want to use improved mask."
)
logger.info("improved_mask")
mask = get_face_mask(aimg, bgr_fake)
# save_img_debug(cv2_to_pil(bgr_fake), "Before Mask")
bgr_fake = merge_images_with_mask(aimg, bgr_fake, mask)
# save_img_debug(cv2_to_pil(bgr_fake), "After Mask")
fake_diff = compute_diff(bgr_fake, aimg=aimg)
assert (
fake_diff is not None
), "fake diff is None, this should not happen"
logger.info("*" * 80) logger.info("*" * 80)
else: else:
@@ -266,6 +277,7 @@ class UpscaledINSwapper(INSwapper):
(target_img.shape[1], target_img.shape[0]), (target_img.shape[1], target_img.shape[0]),
borderValue=0.0, borderValue=0.0,
) )
fake_diff = cv2.warpAffine( fake_diff = cv2.warpAffine(
fake_diff, fake_diff,
IM, IM,
@@ -65,4 +65,7 @@ def face_inpainting_ui(
inpaiting_model, inpaiting_model,
] ]
for component in gradio_components:
setattr(component, "do_not_save_to_config", True)
return gradio_components return gradio_components
@@ -15,18 +15,19 @@ def postprocessing_ui() -> List[gr.components.Component]:
face_restorer_name = gr.Radio( face_restorer_name = gr.Radio(
label="Restore Face", label="Restore Face",
choices=["None"] + [x.name() for x in shared.face_restorers], choices=["None"] + [x.name() for x in shared.face_restorers],
value=lambda: get_sd_option( value=get_sd_option(
"faceswaplab_pp_default_face_restorer", "faceswaplab_pp_default_face_restorer",
shared.face_restorers[0].name(), shared.face_restorers[0].name(),
), ),
type="value", type="value",
elem_id="faceswaplab_pp_face_restorer", elem_id="faceswaplab_pp_face_restorer",
) )
with gr.Column(): with gr.Column():
face_restorer_visibility = gr.Slider( face_restorer_visibility = gr.Slider(
0, 0,
1, 1,
value=lambda: get_sd_option( value=get_sd_option(
"faceswaplab_pp_default_face_restorer_visibility", 1 "faceswaplab_pp_default_face_restorer_visibility", 1
), ),
step=0.001, step=0.001,
@@ -36,7 +37,7 @@ def postprocessing_ui() -> List[gr.components.Component]:
codeformer_weight = gr.Slider( codeformer_weight = gr.Slider(
0, 0,
1, 1,
value=lambda: get_sd_option( value=get_sd_option(
"faceswaplab_pp_default_face_restorer_weight", 1 "faceswaplab_pp_default_face_restorer_weight", 1
), ),
step=0.001, step=0.001,
@@ -45,7 +46,7 @@ def postprocessing_ui() -> List[gr.components.Component]:
) )
upscaler_name = gr.Dropdown( upscaler_name = gr.Dropdown(
choices=[upscaler.name for upscaler in shared.sd_upscalers], choices=[upscaler.name for upscaler in shared.sd_upscalers],
value=lambda: get_sd_option("faceswaplab_pp_default_upscaler", "None"), value=get_sd_option("faceswaplab_pp_default_upscaler", "None"),
label="Upscaler", label="Upscaler",
elem_id="faceswaplab_pp_upscaler", elem_id="faceswaplab_pp_upscaler",
) )
@@ -60,9 +61,7 @@ def postprocessing_ui() -> List[gr.components.Component]:
upscaler_visibility = gr.Slider( upscaler_visibility = gr.Slider(
0, 0,
1, 1,
value=lambda: get_sd_option( value=get_sd_option("faceswaplab_pp_default_upscaler_visibility", 1),
"faceswaplab_pp_default_upscaler_visibility", 1
),
step=0.1, step=0.1,
label="Upscaler visibility (if scale = 1)", label="Upscaler visibility (if scale = 1)",
elem_id="faceswaplab_pp_upscaler_visibility", elem_id="faceswaplab_pp_upscaler_visibility",
@@ -123,7 +122,7 @@ def postprocessing_ui() -> List[gr.components.Component]:
label="sd model (experimental)", label="sd model (experimental)",
elem_id="faceswaplab_pp_inpainting_sd_model", elem_id="faceswaplab_pp_inpainting_sd_model",
) )
return [ components = [
face_restorer_name, face_restorer_name,
face_restorer_visibility, face_restorer_visibility,
codeformer_weight, codeformer_weight,
@@ -138,3 +137,8 @@ def postprocessing_ui() -> List[gr.components.Component]:
inpainting_sampler, inpainting_sampler,
inpaiting_model, inpaiting_model,
] ]
# Ask sd to not store in ui-config.json
for component in components:
setattr(component, "do_not_save_to_config", True)
return components
+15 -18
View File
@@ -17,7 +17,7 @@ def faceswap_unit_advanced_options(
face_restorer_name = gr.Radio( face_restorer_name = gr.Radio(
label="Restore Face", label="Restore Face",
choices=["None"] + [x.name() for x in shared.face_restorers], choices=["None"] + [x.name() for x in shared.face_restorers],
value=lambda: get_sd_option( value=get_sd_option(
"faceswaplab_default_upscaled_swapper_face_restorer", "faceswaplab_default_upscaled_swapper_face_restorer",
"None", "None",
), ),
@@ -28,7 +28,7 @@ def faceswap_unit_advanced_options(
face_restorer_visibility = gr.Slider( face_restorer_visibility = gr.Slider(
0, 0,
1, 1,
value=lambda: get_sd_option( value=get_sd_option(
"faceswaplab_default_upscaled_swapper_face_restorer_visibility", "faceswaplab_default_upscaled_swapper_face_restorer_visibility",
1.0, 1.0,
), ),
@@ -39,7 +39,7 @@ def faceswap_unit_advanced_options(
codeformer_weight = gr.Slider( codeformer_weight = gr.Slider(
0, 0,
1, 1,
value=lambda: get_sd_option( value=get_sd_option(
"faceswaplab_default_upscaled_swapper_face_restorer_weight", 1.0 "faceswaplab_default_upscaled_swapper_face_restorer_weight", 1.0
), ),
step=0.001, step=0.001,
@@ -48,33 +48,25 @@ def faceswap_unit_advanced_options(
) )
upscaler_name = gr.Dropdown( upscaler_name = gr.Dropdown(
choices=[upscaler.name for upscaler in shared.sd_upscalers], choices=[upscaler.name for upscaler in shared.sd_upscalers],
value=lambda: get_sd_option( value=get_sd_option("faceswaplab_default_upscaled_swapper_upscaler", ""),
"faceswaplab_default_upscaled_swapper_upscaler", ""
),
label="Upscaler", label="Upscaler",
elem_id=f"{id_prefix}_face{unit_num}_upscaler", elem_id=f"{id_prefix}_face{unit_num}_upscaler",
) )
improved_mask = gr.Checkbox( improved_mask = gr.Checkbox(
lambda: get_sd_option( get_sd_option("faceswaplab_default_upscaled_swapper_improved_mask", False),
"faceswaplab_default_upscaled_swapper_improved_mask", False
),
interactive=True, interactive=True,
label="Use improved segmented mask (use pastenet to mask only the face)", label="Use improved segmented mask (use pastenet to mask only the face)",
elem_id=f"{id_prefix}_face{unit_num}_improved_mask", elem_id=f"{id_prefix}_face{unit_num}_improved_mask",
) )
color_corrections = gr.Checkbox( color_corrections = gr.Checkbox(
lambda: get_sd_option( get_sd_option("faceswaplab_default_upscaled_swapper_fixcolor", False),
"faceswaplab_default_upscaled_swapper_fixcolor", False
),
interactive=True, interactive=True,
label="Use color corrections", label="Use color corrections",
elem_id=f"{id_prefix}_face{unit_num}_color_corrections", elem_id=f"{id_prefix}_face{unit_num}_color_corrections",
) )
sharpen_face = gr.Checkbox( sharpen_face = gr.Checkbox(
lambda: get_sd_option( get_sd_option("faceswaplab_default_upscaled_swapper_sharpen", False),
"faceswaplab_default_upscaled_swapper_sharpen", False
),
interactive=True, interactive=True,
label="sharpen face", label="sharpen face",
elem_id=f"{id_prefix}_face{unit_num}_sharpen_face", elem_id=f"{id_prefix}_face{unit_num}_sharpen_face",
@@ -82,13 +74,13 @@ def faceswap_unit_advanced_options(
erosion_factor = gr.Slider( erosion_factor = gr.Slider(
0.0, 0.0,
10.0, 10.0,
lambda: get_sd_option("faceswaplab_default_upscaled_swapper_erosion", 1.0), get_sd_option("faceswaplab_default_upscaled_swapper_erosion", 1.0),
step=0.01, step=0.01,
label="Upscaled swapper mask erosion factor, 1 = default behaviour.", label="Upscaled swapper mask erosion factor, 1 = default behaviour.",
elem_id=f"{id_prefix}_face{unit_num}_erosion_factor", elem_id=f"{id_prefix}_face{unit_num}_erosion_factor",
) )
return [ components = [
face_restorer_name, face_restorer_name,
face_restorer_visibility, face_restorer_visibility,
codeformer_weight, codeformer_weight,
@@ -99,6 +91,11 @@ def faceswap_unit_advanced_options(
erosion_factor, erosion_factor,
] ]
for component in components:
setattr(component, "do_not_save_to_config", True)
return components
def faceswap_unit_ui( def faceswap_unit_ui(
is_img2img: bool, unit_num: int = 1, id_prefix: str = "faceswaplab" is_img2img: bool, unit_num: int = 1, id_prefix: str = "faceswaplab"
@@ -137,7 +134,7 @@ def faceswap_unit_ui(
elem_id=f"{id_prefix}_face{unit_num}_refresh_checkpoints", elem_id=f"{id_prefix}_face{unit_num}_refresh_checkpoints",
) )
def refresh_fn(selected: str) -> None: def refresh_fn(selected: str):
return gr.Dropdown.update( return gr.Dropdown.update(
value=selected, choices=get_face_checkpoints() value=selected, choices=get_face_checkpoints()
) )
+2 -1
View File
@@ -5,7 +5,6 @@ import cv2
import numpy as np import numpy as np
from math import isqrt, ceil from math import isqrt, ceil
import torch import torch
from ifnude import detect
from modules import processing from modules import processing
import base64 import base64
from collections import Counter from collections import Counter
@@ -31,6 +30,8 @@ def check_against_nsfw(img: PILImage) -> bool:
if NSFW_SCORE_THRESHOLD >= 1: if NSFW_SCORE_THRESHOLD >= 1:
return False return False
from ifnude import detect
shapes: List[bool] = [] shapes: List[bool] = []
chunks: List[Dict[str, Union[int, float]]] = detect(img) chunks: List[Dict[str, Union[int, float]]] = detect(img)