diff --git a/README.md b/README.md
index df8b848..cb37f07 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# Roop-GE* 0.2.4b for StableDiffusion
-### NSFW (uncensored) version (use it on your own responsibility) of [original sd-webui-roop](https://github.com/s0md3v/sd-webui-roop) with a lot of improvements
+# ReActor 0.3.0 for StableDiffusion
+### The Fast and Simple "[roop-based](https://github.com/s0md3v/sd-webui-roop)" FaceSwap Extension with a lot of improvements and without NSFW filter (uncensored, use it on your own responsibility)
-> *Will be renamed soon! Stay tuned! (GE - Gourieff Edition, aka "NSFW-Roop")
+> Ex "Roop-GE" (GE - Gourieff Edition, aka "NSFW-Roop"), the extension was renamed with the version 0.3.0
---
-[**Disclaimer**](#disclaimer) | [**Installation**](#installation) | [**Usage**](#usage) | [**Troubleshooting**](#troubleshooting) | [**Updating**](#updating)
+[**Disclaimer**](#disclaimer) | [**Installation**](#installation) | [**Usage**](#usage) | [**Troubleshooting**](#troubleshooting) | [**Updating**](#updating) | [**ComfyUI**](#comfyui)
---
@@ -35,8 +35,8 @@ Users of this software are expected to use this software responsibly while abidi
2. In web-ui, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-roop-nsfw` in the "Install from URL" tab and click "Install"
3. Please, wait for several minutes until the installation process will be finished
4. Check the last message in your SD-WebUI Console:
-* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C) and start it again.
-* If you see the message "Done!", just go to the "Installed" tab (*if you have any other Roop extension enabled - disable it, otherwise this extension won't work*), click "Apply and restart UI"
+* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C or CMD+C) and start it again - or just go to the "Installed" tab (*if you have any other Roop-based extension enabled - disable it, otherwise this extension won't work*), click "Apply and restart UI"
+* If you see the message "Done!", just go to the "Installed" tab (*if you have any other Roop-based extension enabled - disable it, otherwise this extension won't work*), click "Apply and restart UI" - or you can just simply reload the UI
5. Enjoy!
If you use [SD.Next](https://github.com/vladmandic/automatic):
@@ -47,28 +47,29 @@ Users of this software are expected to use this software responsibly while abidi
4. Run SD.Next, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-roop-nsfw` in the "Install from URL" tab and click "Install"
5. Please, wait for several minutes until the installation process will be finished
6. Check the last message in your SD.Next Console:
-* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C) and start it again.
-* If you see the message "Done!", just go to the "Installed" tab (*if you have any other Roop extension enabled - disable it, otherwise this extension won't work*), click "Restart the UI"
+* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C or CMD+C) and start it again - or just go to the "Installed" tab (*if you have any other Roop-based extension enabled - disable it, otherwise this extension won't work*), click "Restart the UI"
7. Stop SD.Next, go to the `automatic\extensions\sd-webui-roop-nsfw` directory - if you see there `models\roop` folder with the file `inswapper_128.onnx`, just move the file to the `automatic\models\roop` folder
8. Run your SD.Next WebUI and enjoy!
If you use [Cagliostro Colab UI](https://github.com/Linaqruf/sd-notebook-collection):
-1. In active web-ui, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-roop-nsfw` in the "Install from URL" tab and click "Install"
+1. In active WebUI, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-roop-nsfw` in the "Install from URL" tab and click "Install"
2. Please, wait for several minutes until the installation process will be finished
-3. When you see the message "--- PLEASE, RESTART the Server! ---" in your Colab Notebook Start UI section ("Start Cagliostro Colab UI") - just go to the "Installed" tab and click "Apply and restart UI" (*if you have any other Roop extension enabled - disable it before restart, otherwise this extension won't work*)
+3. When you see the message "--- PLEASE, RESTART the Server! ---" (in your Colab Notebook Start UI section "Start Cagliostro Colab UI") - just go to the "Installed" tab and click "Apply and restart UI" (*if you have any other Roop-based extension enabled - disable it before restart, otherwise this extension won't work*)
4. Enjoy!
## Usage
-1. Under "Roop-GE" drop-down menu, import an image containing a face;
+1. Under "ReActor" drop-down menu, import an image containing a face;
2. Turn on the "Enable" checkbox;
3. That's it, now the generated result will have the face you selected.
-**You can use Roop-GE with Webui API:**
+
+
+**You can use ReActor with Webui API:**
1. Check the [SD Web API Wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API) for how to use API;
-2. Call `requests.get(url=f'{address}/sdapi/v1/script-info')` to find the args that Roop-GE needs;
-3. Define Roop-GE script args and add like this `"alwayson_scripts": {"roop-ge":{"args":args}}` in the payload;
+2. Call `requests.get(url=f'{address}/sdapi/v1/script-info')` to find the args that ReActor needs;
+3. Define ReActor script args and add like this `"alwayson_scripts": {"reactor":{"args":args}}` in the payload;
4. Call the API, there's an [full usage example](./example/api_example.py) in example folder.
### The result face is blurry
@@ -116,12 +117,12 @@ Please, check the path where "inswapper_128.onnx" model is stored. It must be in
- `pip install onnxruntime==1.15.0`
- `pip install opencv-python==4.7.0.72`
- `pip install tqdm`
-7. Type `deactivate`, you can close your Terminal or Console and start your sd-webui, Roop should start OK - if not, welcome to Issues section.
+7. Type `deactivate`, you can close your Terminal or Console and start your sd-webui, ReActor should start OK - if not, welcome to Issues section.
**III. "TypeError: UpscaleOptions.init() got an unexpected keyword argument 'do_restore_first'"**
-First of all - you need to disable any other Roop extensions:
-- Go to 'Extensions -> Installed' tab and uncheck any Roop except this one
+First of all - you need to disable any other Roop-based extensions:
+- Go to 'Extensions -> Installed' tab and uncheck any Roop-based extensions except this one
- Click 'Apply and restart UI'
@@ -140,8 +141,8 @@ and put it to the `stable-diffusion-webui\models\roop` replacing existing one
**VI. "ValueError: This ORT build has ['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'] enabled"**
-1. Go to the `G:\stable-diffusion-webui\venv\lib\site-packages` and see if there are any folders with names start from "~" (for example "~rotobuf"), delete them
-2. Go to the `G:\stable-diffusion-webui\venv\Scripts` run CMD there and type `activate` in your Console
+1. Go to the `stable-diffusion-webui\venv\lib\site-packages` and see if there are any folders with names start from "~" (for example "~rotobuf"), delete them
+2. Go to the `stable-diffusion-webui\venv\Scripts` run CMD there and type `activate` in your Console
3. Then:
- `python -m pip install -U pip`
- `pip uninstall -y onnx onnxruntime onnxruntime-gpu onnxruntime-silicon`
@@ -149,14 +150,14 @@ and put it to the `stable-diffusion-webui\models\roop` replacing existing one
**VII. "ImportError: cannot import name 'builder' from 'google.protobuf.internal'"**
-1. Go to the `G:\stable-diffusion-webui\venv\lib\site-packages` and see if there are any folders with names start from "~" (for example "~rotobuf"), delete them
-2. Go to the `G:\stable-diffusion-webui\venv\Scripts` run CMD there and type `activate` in your Console
+1. Go to the `stable-diffusion-webui\venv\lib\site-packages` and see if there are any folders with names start from "~" (for example "~rotobuf"), delete them
+2. Go to the `stable-diffusion-webui\venv\Scripts` run CMD there and type `activate` in your Console
3. Then:
- `python -m pip install -U pip`
- `pip uninstall protobuf`
- `pip install protobuf==3.20.3`
-If this method doesn't help - there is some other extension that has a higher version of protobuf dependence and sd-webui installs it on startup requirements check
+If this method doesn't help - there is some other extension that has a higher version of protobuf dependence and SD WebUI installs it on startup requirements check
**VIII. (For Windows users) If you still cannot build Insightface for some reasons or just don't want to install Visual Studio or VS C++ Build Tools - do the following:**
@@ -169,3 +170,8 @@ If this method doesn't help - there is some other extension that has a higher ve
## Updating
A good and quick way to check for Extensions updates: https://github.com/Gourieff/sd-webui-extensions-updater
+
+## ComfyUI
+
+You can use ReActor with ComfyUI
+For the installation instruction follow the [ReActor Node repo](https://github.com/Gourieff/comfyui-reactor-node)
diff --git a/example/api_example.py b/example/api_example.py
index 0b3eac1..8d202e5 100644
--- a/example/api_example.py
+++ b/example/api_example.py
@@ -20,17 +20,17 @@ img_bytes = io.BytesIO()
im.save(img_bytes, format='PNG')
img_base64 = base64.b64encode(img_bytes.getvalue()).decode('utf-8')
-# Roop-GE arguments:
+# ReActor arguments:
args=[
img_base64, #0
- True, #1 Enable Roop-GE
+ True, #1 Enable ReActor
'0', #2 Comma separated face number(s) from swap-source image
'0', #3 Comma separated face number(s) for target image (result)
'C:\stable-diffusion-webui\models/roop\inswapper_128.onnx', #4 model path
'CodeFormer', #4 Restore Face: None; CodeFormer; GFPGAN
1, #5 Restore visibility value
True, #7 Restore face -> Upscale
- '4x_NMKD-Superscale-SP_178000_G', #8 Upscaler (type 'None' if doesn't need), see full list here: http://127.0.0.1:7860/sdapi/v1/script-info -> roop-ge -> sec.8
+ '4x_NMKD-Superscale-SP_178000_G', #8 Upscaler (type 'None' if doesn't need), see full list here: http://127.0.0.1:7860/sdapi/v1/script-info -> reactor -> sec.8
2, #9 Upscaler scale value
1, #10 Upscaler visibility (if scale = 1)
False, #11 Swap in source image
@@ -38,7 +38,7 @@ args=[
1, #13 Console Log Level (0 - min, 1 - med or 2 - max)
]
-# The args for roop-ge can be found by
+# The args for ReActor can be found by
# requests.get(url=f'{address}/sdapi/v1/script-info')
prompt = "(8k, best quality, masterpiece, highly detailed:1.1),realistic photo of fantastic happy woman,hairstyle of blonde and red short bob hair,modern clothing,cinematic lightning,film grain,dynamic pose,bokeh,dof"
@@ -55,7 +55,7 @@ payload = {
"width": 512,
"height": 768,
"restore_faces": False,
- "alwayson_scripts": {"roop-ge":{"args":args}}
+ "alwayson_scripts": {"reactor":{"args":args}}
}
try:
diff --git a/example/demo_crop.jpg b/example/demo_crop.jpg
index 9ba6630..a76dd62 100644
Binary files a/example/demo_crop.jpg and b/example/demo_crop.jpg differ
diff --git a/install.py b/install.py
index c60b3f0..8f9f599 100644
--- a/install.py
+++ b/install.py
@@ -35,7 +35,7 @@ def is_installed (
def download(url, path):
request = urllib.request.urlopen(url)
total = int(request.headers.get('Content-Length', 0))
- with tqdm(total=total, desc='Downloading', unit='B', unit_scale=True, unit_divisor=1024) as progress:
+ with tqdm(total=total, desc='Downloading...', unit='B', unit_scale=True, unit_divisor=1024) as progress:
urllib.request.urlretrieve(url, path, reporthook=lambda count, block_size, total_size: progress.update(block_size))
if not os.path.exists(models_dir):
@@ -44,7 +44,7 @@ if not os.path.exists(models_dir):
if not os.path.exists(model_path):
download(model_url, model_path)
-print("Checking Roop-GE requirements...")
+print("Checking ReActor (ex Roop-GE) requirements...", end=' ')
with open(req_file) as file:
install_count = 0
for package in file:
@@ -58,9 +58,9 @@ with open(req_file) as file:
run_pip(package)
except Exception as e:
print(e)
- print(f"Warning: Failed to install {package}, Roop-GE will not work.")
+ print(f"\nERROR: Failed to install {package} - ReActor won't start")
raise e
if install_count > 0:
print(f'\n--- PLEASE, RESTART the Server! ---\n')
else:
- print('Done!')
+ print('Ok')
diff --git a/scripts/faceswap.py b/scripts/faceswap.py
index 32e300c..025be5f 100644
--- a/scripts/faceswap.py
+++ b/scripts/faceswap.py
@@ -13,7 +13,7 @@ from modules.face_restoration import FaceRestoration
from scripts.logger import logger
from scripts.swapper import UpscaleOptions, swap_face
-from scripts.version import version_flag
+from scripts.version import version_flag, app_title
from scripts.console_log_patch import apply_logging_patch
import os
@@ -36,16 +36,16 @@ def get_models():
class FaceSwapScript(scripts.Script):
def title(self):
- return f"Roop-GE"
+ return f"{app_title}"
def show(self, is_img2img):
return scripts.AlwaysVisible
def ui(self, is_img2img):
- with gr.Accordion(f"Roop-GE {version_flag}", open=False):
+ with gr.Accordion(f"{app_title} (ex Roop-GE)", open=False):
with gr.Column():
img = gr.inputs.Image(type="pil")
- enable = gr.Checkbox(False, label="Enable", info="The Extension will be renamed to a cool new name in a future update! Stay tuned!")
+ enable = gr.Checkbox(False, label="Enable", info=f"The Fast and Simple \"roop-based\" FaceSwap Extension - {version_flag}")
with gr.Row():
source_faces_index = gr.Textbox(
value="0",
@@ -201,10 +201,10 @@ class FaceSwapScript(scripts.Script):
if self.source is not None:
apply_logging_patch(console_logging_level)
if isinstance(p, StableDiffusionProcessingImg2Img) and swap_in_source:
- logger.info(f"Roop-GE is enabled, face index %s", self.faces_index)
+ logger.info(f"Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
for i in range(len(p.init_images)):
- logger.info(f"Swap in source %s", i)
+ logger.info(f"Swap in %s", i)
result = swap_face(
self.source,
p.init_images[i],
@@ -224,6 +224,7 @@ class FaceSwapScript(scripts.Script):
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.info(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,
diff --git a/scripts/globals.py b/scripts/globals.py
new file mode 100644
index 0000000..d41b27e
--- /dev/null
+++ b/scripts/globals.py
@@ -0,0 +1 @@
+IS_RUN: bool = False
diff --git a/scripts/logger.py b/scripts/logger.py
index 55529c3..7bd8922 100644
--- a/scripts/logger.py
+++ b/scripts/logger.py
@@ -3,11 +3,13 @@ import copy
import sys
from modules import shared
+from scripts.globals import IS_RUN
class ColoredFormatter(logging.Formatter):
COLORS = {
"DEBUG": "\033[0;36m", # CYAN
+ "STATUS": "\033[38;5;137m", # Calm ORANGE
"INFO": "\033[0;32m", # GREEN
"WARNING": "\033[0;33m", # YELLOW
"ERROR": "\033[0;31m", # RED
@@ -24,18 +26,29 @@ class ColoredFormatter(logging.Formatter):
# Create a new logger
-logger = logging.getLogger("Roop-GE")
+logger = logging.getLogger("ReActor")
logger.propagate = False
+# Custom Level name
+logging.addLevelName(logging.INFO, "STATUS")
+
# Add handler if we don't have one.
if not logger.handlers:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(
- ColoredFormatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+ ColoredFormatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s","%H:%M:%S")
)
logger.addHandler(handler)
# Configure logger
-loglevel_string = getattr(shared.cmd_opts, "roop_loglevel", "INFO")
+loglevel_string = getattr(shared.cmd_opts, "reactor_loglevel", "INFO")
loglevel = getattr(logging, loglevel_string.upper(), "info")
logger.setLevel(loglevel)
+
+def set_Run(value):
+ global IS_RUN
+ IS_RUN = value
+
+def get_Run():
+ global IS_RUN
+ return IS_RUN
diff --git a/scripts/swapper.py b/scripts/swapper.py
index 9a3481e..9b0ed3e 100644
--- a/scripts/swapper.py
+++ b/scripts/swapper.py
@@ -77,7 +77,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
if upscale_options.do_restore_first:
if upscale_options.face_restorer is not None:
original_image = result_image.copy()
- logger.info("Restore face with %s", upscale_options.face_restorer.name())
+ 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)
@@ -87,7 +87,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
original_image = result_image.copy()
logger.info(
- "Upscale with %s scale = %s",
+ "Upscaling with %s scale = %s",
upscale_options.upscaler.name,
upscale_options.scale,
)
@@ -102,7 +102,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
original_image = result_image.copy()
logger.info(
- "Upscale with %s scale = %s",
+ "Upscaling with %s scale = %s",
upscale_options.upscaler.name,
upscale_options.scale,
)
@@ -115,7 +115,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
)
if upscale_options.face_restorer is not None:
original_image = result_image.copy()
- logger.info("Restore face with %s", upscale_options.face_restorer.name())
+ 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)
@@ -192,7 +192,7 @@ def swap_face(
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:
+ if upscale_options is not None and target_face is not None:
result_image = upscale_image(result_image, upscale_options)
else:
diff --git a/scripts/version.py b/scripts/version.py
index 4ebc359..5ad1e16 100644
--- a/scripts/version.py
+++ b/scripts/version.py
@@ -1,5 +1,10 @@
-version_flag = "v0.2.4b"
+app_title = "ReActor"
+version_flag = "v0.3.0"
-from scripts.logger import logger
+from scripts.logger import logger, get_Run, set_Run
-logger.info(f"Roop-GE {version_flag}")
+is_run = get_Run()
+
+if not is_run:
+ logger.info(f"Running {version_flag}")
+ set_Run(True)