- 
+ 
- 
+ 
- 
+ 
- 
+ 
+
+
+## What's new in the latest update
+
+### 0.5.1 BETA2
+
+- You can now save face models as "safetensors" files (stored in `
+
## Installation
[Automatic1111](#a1111) | [Vladmandic SD.Next](#sdnext) | [Google Colab SD WebUI](#colab)
@@ -103,6 +114,8 @@
- Ability to **save original images** (made before swapping)
- **Face restoration** of a swapped face
- **Upscaling** of a resulting image
+- Saving ans loading **Safetensors Face Models**
+- **Facial Mask Correction** to avoid any pixelation around face contours
- Ability to set the **Postprocessing order**
- **100% compatibility** with different **SD WebUIs**: Automatic1111, SD.Next, Cagliostro Colab UI
- **Fast performance** even with CPU, ReActor for SD WebUI is absolutely not picky about how powerful your GPU is
diff --git a/README_RU.md b/README_RU.md
index 20dcb41..9ccd906 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -21,7 +21,7 @@
---
- Установка | Возможности | Использование | API | Устранение проблем | Обновление | ComfyUI | Ответственность
+ Что нового | Установка | Возможности | Использование | API | Устранение проблем | Обновление | ComfyUI | Ответственность
@@ -55,6 +55,17 @@
+
+
+## Что нового в последнем обновлении
+
+### 0.5.1 BETA2
+
+- Теперь можно сохранять модели лиц в качестве файлов "safetensors" (находятся в `
+
## Установка
@@ -106,6 +117,8 @@
- Функция **сохранения оригинального изображения** (сгенерированного до замены лица)
- **Восстановление лица** после замены
- **Увеличение размера** полученного изображения
+- Сохранение и загрузка **Моделей Лиц типа Safetensors**
+- **Коррекция Маски Лица** для предотвращения какой-либо пикселизации вокруг контуров лиц
- Возможность задать **порядок постобработки**
- **100% совместимость** с разными **SD WebUI**: Automatic1111, SD.Next, Cagliostro Colab UI
- **Отличная производительность** даже с использованием ЦПУ, ReActor для SD WebUI абсолютно не требователен к мощности вашей видеокарты
From 70479479b314aa84dc37bda01a44988adabdb9b4 Mon Sep 17 00:00:00 2001
From: Gourieff <777@lovemet.ru>
Date: Fri, 24 Nov 2023 23:02:00 +0700
Subject: [PATCH 04/35] HotFIX: Compatibility with "sd-face-editor"
Issue #211
Because Reactor's Mask Correction is based on sd-face-editor masking script - we need another naming of active folders
+VersionUP (0.5.1 beta3)
---
README.md | 2 +-
README_RU.md | 2 +-
modules/reactor_mask.py | 6 +++---
scripts/{entities => reactor_entities}/face.py | 2 +-
scripts/{entities => reactor_entities}/rect.py | 0
.../bisenet_mask_generator.py | 2 +-
.../{inferencers => reactor_inferencers}/mask_generator.py | 0
scripts/reactor_version.py | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
rename scripts/{entities => reactor_entities}/face.py (98%)
rename scripts/{entities => reactor_entities}/rect.py (100%)
rename scripts/{inferencers => reactor_inferencers}/bisenet_mask_generator.py (97%)
rename scripts/{inferencers => reactor_inferencers}/mask_generator.py (100%)
diff --git a/README.md b/README.md
index 06586a0..3515ce2 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
- 
+ 
- 
+ 
- 
+ 
- 
-
-
+
-
-
- - - Support This Project - - - |
- - ReActor is an extension for Stable Diffusion WebUI that allows a very easy and accurate face-replacement (face swap) in images. Based on ReActor-UI. - | -
-
- - - Donate to This Project - - - |
-
## What's new in the latest update
-### 0.5.1 BETA2
+### 0.5.1
- You can now save face models as "safetensors" files (stored in `
- 
+ 
-
+
-
-
- - - Поддержать проект - - - |
- - ReActor это расширение для Stable Diffusion WebUI, которое позволяет делать простую и точную замену лиц на изображениях. Сделано на основе ReActor-UI. - | -
-
- - - Помочь проекту - - - |
-
## Что нового в последнем обновлении
-### 0.5.1 BETA2
+### 0.5.1
- Теперь можно сохранять модели лиц в качестве файлов "safetensors" (находятся в `
- 
+ 
@@ -38,11 +38,20 @@
-## What's new in the latest update
+## What's new in the latest updates
+
+### 0.6.0 ALPHA1
+
+- UI reworked
+- You can now load several source images (with reference faces) or set the path to the folder containing faces images
+
+
+
+
### 0.5.1
-- You can now save face models as "safetensors" files (stored in `
@@ -59,8 +68,8 @@
- OR only **VS C++ Build Tools** (if you don't need the whole Visual Studio) and select "Desktop Development with C++" under "Workloads -> Desktop & Mobile":
https://visualstudio.microsoft.com/visual-cpp-build-tools/
- OR if you don't want to install VS or VS C++ BT - follow [this steps (sec. VIII)](#insightfacebuild)
-2. In web-ui, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab and click "Install"
-3. Please, wait for several minutes until the installation process will be finished
+2. In web-ui, go to the "Extensions" tab, load "Available" extensions and type "ReActor" in the search field or use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab - and click "Install"
+3. Please, wait for several minutes until the installation process will be finished (be patient, don't interrupt the process)
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 or CMD+C) and start it again - or just go to the "Installed" tab, click "Apply and restart UI"
* If you see the message "Done!", just reload the UI
@@ -73,7 +82,7 @@
3. Go to (Windows)`automatic\venv\Scripts` or (MacOS/Linux)`automatic/venv/bin`, run Terminal or Console (cmd) for that folder and type `activate`
4. Run `pip install insightface==0.7.3`
5. Run SD.Next, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab and click "Install"
-6. Please, wait for several minutes until the installation process will be finished
+6. Please, wait for several minutes until the installation process will be finished (be patient, don't interrupt the process)
7. Check the last message in your SD.Next Console:
* If you see the message "--- PLEASE, RESTART the Server! ---" - stop the Server (CTRL+C or CMD+C) or just close your console
8. Go to the `automatic\extensions\sd-webui-reactor` directory - if you see there `models\insightface` folder with the file `inswapper_128.onnx`, just move the file to the `automatic\models\insightface` folder
@@ -81,8 +90,8 @@
If you use [Cagliostro Colab UI](https://github.com/Linaqruf/sd-notebook-collection):
-1. In active WebUI, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab and click "Install"
-2. Please, wait for several minutes until the installation process will be finished
+1. In active WebUI, go to the "Extensions" tab, load "Available" extensions and type "ReActor" in the search field or use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab - and click "Install"
+2. Please, wait for several minutes until the installation process will be finished (be patient, don't interrupt the process)
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"
4. Enjoy!
@@ -99,7 +108,7 @@
- Ability to set the **Postprocessing order**
- **100% compatibility** with different **SD WebUIs**: Automatic1111, SD.Next, Cagliostro Colab UI
- **Fast performance** even with CPU, ReActor for SD WebUI is absolutely not picky about how powerful your GPU is
-- **CUDA** acceleration support from the version 0.5.0
+- **CUDA** acceleration support since version 0.5.0
- **[API](/API.md) support**: both SD WebUI built-in and external (via POST/GET requests)
- **ComfyUI [support](https://github.com/Gourieff/comfyui-reactor-node)**
- **Mac M1/M2 [support](https://github.com/Gourieff/sd-webui-reactor/issues/42)**
@@ -191,7 +200,7 @@ Please, check the path where "inswapper_128.onnx" model is stored. It must be in
7. Then one-by-one:
- `pip install insightface==0.7.3`
- `pip install onnx`
- - `pip install onnxruntime-gpu>=1.16.1`
+ - `pip install "onnxruntime-gpu>=1.16.1"`
- `pip install opencv-python`
- `pip install tqdm`
8. Type `deactivate`, you can close your Terminal or Console and start your SD WebUI, ReActor should start OK - if not, welcome to the Issues section.
@@ -226,7 +235,7 @@ and put it to the `stable-diffusion-webui\models\insightface` replacing existing
4. Then:
- `python -m pip install -U pip`
- `pip uninstall -y onnxruntime onnxruntime-gpu onnxruntime-silicon onnxruntime-extensions`
-- `pip install onnxruntime-gpu>=1.16.1`
+- `pip install "onnxruntime-gpu>=1.16.1"`
If it didn't help - it seems that you have another extension reinstalling `onnxruntime` when SD WebUI checks requirements. Please see your extensions list. Some extensions can causes reinstalling of `onnxruntime-gpu` to `onnxruntime<1.16.1` every time SD WebUI runs.
- 
+ 
@@ -37,7 +37,14 @@
-## Что нового в последнем обновлении
+## Что нового в последних обновлениях
+
+### 0.6.0 ALPHA1
+
+- UI переработан
+- Появилась возможность загружать несколько исходных изображений с лицами или задавать путь к папке, содержащей такие изображения
+
+
### 0.5.1
@@ -60,8 +67,8 @@
- ИЛИ только **VS C++ Build Tools** (если вам не нужен весь пакет Visual Studio), выберите "Desktop Development with C++" в разделе "Workloads -> Desktop & Mobile":
https://visualstudio.microsoft.com/visual-cpp-build-tools/
- ИЛИ если же вы не хотите устанавливать что-либо из вышеуказанного - выполните [следующие шаги (пункт VIII)](#insightfacebuild)
-2. Внутри SD Web-UI перейдите во вкладку "Extensions" и вставьте ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" и нажмите "Install"
-3. Пожалуйста, подождите несколько минут, пока процесс установки полностью не завершится
+2. Внутри SD Web-UI перейдите во вкладку "Extensions", загрузите список доступных расширений (вкладка "Available") и введите "ReActor" в строке поиска или же вставьте ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" - и нажмите "Install"
+3. Пожалуйста, подождите несколько минут, пока процесс установки полностью не завершится (наберитесь терпения, не прерывайте процесс)
4. Проверьте последнее сообщение в консоли SD-WebUI:
* Если вы видите "--- PLEASE, RESTART the Server! ---" - остановите Сервер (CTRL+C или CMD+C) и запустите его заново - ИЛИ же перейдите во вкладку "Installed", нажмите "Apply and restart UI"
* Если вы видите "Done!", просто перезагрузите UI, нажав на "Reload UI"
@@ -74,7 +81,7 @@
3. Перейдите в (Windows)`automatic\venv\Scripts` или (MacOS/Linux)`automatic/venv/bin`, запустите Терминал или Консоль (cmd) для данной папки и выполните `activate`
4. Выполните `pip install insightface==0.7.3`
5. Запустите SD.Next, перейдите во вкладку "Extensions", вставьте эту ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" и нажмите "Install"
-6. Пожалуйста, подождите несколько минут, пока процесс установки полностью не завершится
+6. Пожалуйста, подождите несколько минут, пока процесс установки полностью не завершится (наберитесь терпения, не прерывайте процесс)
7. Проверьте последнее сообщение в консоли SD.Next:
* Если вы видите "--- PLEASE, RESTART the Server! ---" - остановите Сервер (CTRL+C или CMD+C) или просто закройте консоль
8. Перейдите в директорию `automatic\extensions\sd-webui-reactor` - если вы видите там папку `models\insightface` с файлом `inswapper_128.onnx` внутри, переместите его в папку `automatic\models\insightface`
@@ -82,8 +89,8 @@
Если вы используете [Cagliostro Colab UI](https://github.com/Linaqruf/sd-notebook-collection):
-1. В активном WebUI, перейдите во вкладку "Extensions", вставьте ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" и нажмите "Install"
-2. Пожалуйста, подождите некоторое время, пока процесс установки полностью не завершится
+1. В активном WebUI перейдите во вкладку "Extensions", загрузите список доступных расширений (вкладка "Available") и введите "ReActor" в строке поиска или же вставьте ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" - и нажмите "Install"
+2. Пожалуйста, подождите некоторое время, пока процесс установки полностью не завершится (наберитесь терпения, не прерывайте процесс)
3. Когда вы увидите сообщение "--- PLEASE, RESTART the Server! ---" (в секции "Start UI" вашего ноутбука "Start Cagliostro Colab UI") - перейдите во вкладку "Installed" и нажмите "Apply and restart UI"
4. Готово!
@@ -198,7 +205,7 @@ Inpainting также работает, но замена лица происх
7. Далее:
- `pip install insightface==0.7.3`
- `pip install onnx`
- - `pip install onnxruntime-gpu>=1.16.1`
+ - `pip install "onnxruntime-gpu>=1.16.1"`
- `pip install opencv-python`
- `pip install tqdm`
8. Выполните `deactivate`, закройте Терминал или Консоль и запустите SD WebUI, ReActor должен запуститься без к-л проблем - если же нет, добро пожаловать в раздел "Issues".
@@ -233,7 +240,7 @@ Inpainting также работает, но замена лица происх
4. Затем:
- `python -m pip install -U pip`
- `pip uninstall -y onnxruntime onnxruntime-gpu onnxruntime-silicon onnxruntime-extensions`
-- `pip install onnxruntime-gpu>=1.16.1`
+- `pip install "onnxruntime-gpu>=1.16.1"`
Если это не помогло - значит какое-то другое расширение переустанавливает `onnxruntime` всякий раз, когда SD WebUI проверяет требования пакетов. Внимательно посмотрите список активных расширений. Некоторые расширения могут вызывать переустановку `onnxruntime-gpu` на версию `onnxruntime<1.16.1` при каждом запуске SD WebUI.
+

diff --git a/README_RU.md b/README_RU.md
index 78bb651..12a84c1 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -1,6 +1,6 @@
+

From fda111bb3d36592e37c36059796e418a6cc70591 Mon Sep 17 00:00:00 2001
From: Gourieff <777@lovemet.ru>
Date: Wed, 6 Dec 2023 22:44:32 +0700
Subject: [PATCH 10/35] UPDATE: New logo (better or not?)
---
README.md | 2 +-
README_RU.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 6dd109b..8939559 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
+

diff --git a/README_RU.md b/README_RU.md
index 12a84c1..962af74 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -1,6 +1,6 @@
+

From 3b50def4069320d02405e59673d08066e888f961 Mon Sep 17 00:00:00 2001
From: Gourieff <777@lovemet.ru>
Date: Sat, 9 Dec 2023 21:27:08 +0700
Subject: [PATCH 11/35] UPDATE: Save Original On/Off w/Multiple Source
Feature Request #250
+VersionUP (0.6.0 alpha2)
---
README.md | 2 +-
README_RU.md | 4 +++-
reactor_ui/reactor_main_ui.py | 23 ++++++++++++-----------
scripts/reactor_faceswap.py | 5 ++++-
scripts/reactor_version.py | 2 +-
5 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index 8939559..4e06349 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/README_RU.md b/README_RU.md
index 962af74..a1ba1f0 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
@@ -46,6 +46,8 @@
+
+
### 0.5.1
- Теперь можно сохранять модели лиц в качестве файлов "safetensors" (находятся в `
- 
+ 
@@ -257,10 +257,10 @@ If this method doesn't help - there is some other extension that has a wrong ver
### **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:**
1. Close (stop) your SD WebUI Server if it's running
-2. Download and put [prebuilt Insightface package](https://github.com/Gourieff/sd-webui-reactor/raw/main/example/insightface-0.7.3-cp310-cp310-win_amd64.whl) into the stable-diffusion-webui (or SD.Next) root folder (where you have "webui-user.bat" file)
-3. From stable-diffusion-webui (or SD.Next) root folder run CMD and `.\venv\Scripts\activate`
-4. Then update your PIP: `python -m pip install -U pip`
-5. Then install Insightface: `pip install insightface-0.7.3-cp310-cp310-win_amd64.whl`
+2. Download and put [prebuilt Insightface package](https://github.com/Gourieff/sd-webui-reactor/raw/main/example/insightface-0.7.3-cp310-cp310-win_amd64.whl) into the stable-diffusion-webui (or SD.Next) root folder where you have "webui-user.bat" file or (A1111 Portable) "run.bat"
+3. From stable-diffusion-webui (or SD.Next) root folder run CMD and `.\venv\Scripts\activate`
- 
+ 
@@ -264,10 +264,10 @@ Inpainting также работает, но замена лица происх
### **VIII. (Для пользователей Windows) Если вы до сих пор не можете установить пакет Insightface по каким-то причинам или же просто не желаете устанавливать Visual Studio или VS C++ Build Tools - сделайте следующее:**
1. Закройте (остановите) SD WebUI Сервер, если он запущен
-2. Скачайте готовый [пакет Insightface](https://github.com/Gourieff/sd-webui-reactor/raw/main/example/insightface-0.7.3-cp310-cp310-win_amd64.whl) и сохраните его в корневую директорию stable-diffusion-webui (или SD.Next) - туда, где лежит файл "webui-user.bat"
-3. Из корневой директории откройте Консоль (CMD) и выполните `.\venv\Scripts\activate`
-4. Обновите PIP: `python -m pip install -U pip`
-5. Затем установите Insightface: `pip install insightface-0.7.3-cp310-cp310-win_amd64.whl`
+2. Скачайте готовый [пакет Insightface](https://github.com/Gourieff/sd-webui-reactor/raw/main/example/insightface-0.7.3-cp310-cp310-win_amd64.whl) и сохраните его в корневую директорию stable-diffusion-webui (или SD.Next) - туда, где лежит файл "webui-user.bat" или (A1111 Portable) "run.bat"
+3. Из корневой директории откройте Консоль (CMD) и выполните `.\venv\Scripts\activate`
- 
+ 
diff --git a/README_RU.md b/README_RU.md
index 77ed941..294ad57 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/scripts/reactor_faceswap.py b/scripts/reactor_faceswap.py
index 783c68c..1a45fab 100644
--- a/scripts/reactor_faceswap.py
+++ b/scripts/reactor_faceswap.py
@@ -28,6 +28,7 @@ from scripts.console_log_patch import apply_logging_patch
from scripts.reactor_helpers import (
make_grid,
set_Device,
+ get_SDNEXT
)
from scripts.reactor_globals import SWAPPER_MODELS_PATH #, DEVICE, DEVICE_LIST
@@ -50,6 +51,10 @@ class FaceSwapScript(scripts.Script):
# def on_files_clear():
# clear_faces_list()
# return gr.Checkbox.update(value=SAVE_ORIGINAL,visible=True)
+
+ # SD.Next fix
+ if get_SDNEXT():
+ enable = gr.Checkbox(False, label="Enable")
# enable = gr.Checkbox(False, label="Enable", info=f"The Fast and Simple FaceSwap Extension - {version_flag}")
gr.Markdown(f"The Fast and Simple FaceSwap Extension - {version_flag}")
@@ -408,6 +413,10 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
def ui(self):
with ui_components.InputAccordion(False, label=f"{app_title}") as enable:
# with gr.Accordion(f"{app_title}", open=False):
+
+ # SD.Next fix
+ if get_SDNEXT():
+ enable = gr.Checkbox(False, label="Enable")
# enable = gr.Checkbox(False, label="Enable", info=f"The Fast and Simple FaceSwap Extension - {version_flag}")
gr.Markdown(f"The Fast and Simple FaceSwap Extension - {version_flag}")
diff --git a/scripts/reactor_globals.py b/scripts/reactor_globals.py
index 7e8f4dc..81d123d 100644
--- a/scripts/reactor_globals.py
+++ b/scripts/reactor_globals.py
@@ -18,6 +18,8 @@ SWAPPER_MODELS_PATH = os.path.join(MODELS_PATH, "insightface")
REACTOR_MODELS_PATH = os.path.join(MODELS_PATH, "reactor")
FACE_MODELS_PATH = os.path.join(REACTOR_MODELS_PATH, "faces")
+IS_SDNEXT = False
+
if not os.path.exists(REACTOR_MODELS_PATH):
os.makedirs(REACTOR_MODELS_PATH)
if not os.path.exists(FACE_MODELS_PATH):
diff --git a/scripts/reactor_helpers.py b/scripts/reactor_helpers.py
index 2db883d..0290425 100644
--- a/scripts/reactor_helpers.py
+++ b/scripts/reactor_helpers.py
@@ -11,7 +11,7 @@ from insightface.app.common import Face
from modules.images import FilenameGenerator, get_next_sequence_number
from modules import shared, script_callbacks
-from scripts.reactor_globals import DEVICE, BASE_PATH, FACE_MODELS_PATH
+from scripts.reactor_globals import DEVICE, BASE_PATH, FACE_MODELS_PATH, IS_SDNEXT
try:
from modules.paths_internal import models_path
@@ -33,6 +33,14 @@ def get_Device():
global DEVICE
return DEVICE
+def set_SDNEXT():
+ global IS_SDNEXT
+ IS_SDNEXT = True
+
+def get_SDNEXT():
+ global IS_SDNEXT
+ return IS_SDNEXT
+
def make_grid(image_list: List):
# Count the occurrences of each image size in the image_list
diff --git a/scripts/reactor_swapper.py b/scripts/reactor_swapper.py
index 0f70bb2..c92cae4 100644
--- a/scripts/reactor_swapper.py
+++ b/scripts/reactor_swapper.py
@@ -17,7 +17,8 @@ from scripts.reactor_helpers import (
save_face_model,
load_face_model,
get_images_from_folder,
- get_images_from_list
+ get_images_from_list,
+ set_SDNEXT
)
from scripts.console_log_patch import apply_logging_patch
@@ -26,6 +27,7 @@ try: # A1111
from modules import codeformer_model, gfpgan_model
except: # SD.Next
from modules.postprocess import codeformer_model, gfpgan_model
+ set_SDNEXT()
from modules.upscaler import UpscalerData
from modules.shared import state
from scripts.reactor_logger import logger
diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py
index f590633..85adc92 100644
--- a/scripts/reactor_version.py
+++ b/scripts/reactor_version.py
@@ -1,5 +1,5 @@
app_title = "ReActor"
-version_flag = "v0.6.0-a3"
+version_flag = "v0.6.0-a4"
from scripts.reactor_logger import logger, get_Run, set_Run
From be546524af43c2547b9f5fca0df14167d724f907 Mon Sep 17 00:00:00 2001
From: Gourieff <777@lovemet.ru>
Date: Sat, 6 Jan 2024 13:23:48 +0700
Subject: [PATCH 15/35] UPDATE: UI labels, install script less verb
+VersionUP (alpha passed)
---
README.md | 2 +-
README_RU.md | 2 +-
install.py | 4 ++--
reactor_ui/reactor_main_ui.py | 2 +-
reactor_ui/reactor_settings_ui.py | 2 +-
scripts/reactor_version.py | 5 +++--
6 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index cd3f800..aa31ec0 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/README_RU.md b/README_RU.md
index 294ad57..a470c95 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/install.py b/install.py
index 7023b53..fab874b 100644
--- a/install.py
+++ b/install.py
@@ -75,7 +75,7 @@ if not os.path.exists(models_dir):
if not os.path.exists(model_path):
download(model_url, model_path)
-print("ReActor preheating...", end=' ')
+# print("ReActor preheating...", end=' ')
last_device = None
first_run = False
@@ -121,7 +121,7 @@ with open(req_file) as file:
print(e)
print(f"\nERROR: Failed to install {ort} - ReActor won't start")
raise e
- print(f"Device: {last_device}")
+ # print(f"Device: {last_device}")
strict = True
for package in file:
package_version = None
diff --git a/reactor_ui/reactor_main_ui.py b/reactor_ui/reactor_main_ui.py
index 5ed4212..5b2b9a2 100644
--- a/reactor_ui/reactor_main_ui.py
+++ b/reactor_ui/reactor_main_ui.py
@@ -164,7 +164,7 @@ def show(is_img2img: bool, show_br: bool = True, **msgs):
0, 1, 1, step=0.1, label="Restore Face Visibility"
)
codeformer_weight = gr.Slider(
- 0, 1, 0.5, step=0.1, label="CodeFormer Weight", info="0 = maximum effect, 1 = minimum effect"
+ 0, 1, 0.5, step=0.1, label="CodeFormer Weight (Fidelity)", info="0 = far from original (max restoration), 1 = close to original (min restoration)"
)
gr.Markdown("
- 
+ 
@@ -224,7 +224,7 @@ Probably, you need to disable the "SD-CN-Animation" extension (or perhaps some a
This error may occur if there's smth wrong with the model file `inswapper_128.onnx`
-Try to download it manually from [here](https://github.com/facefusion/facefusion-assets/releases/download/models/inswapper_128.onnx)
+Try to download it manually from [here](https://huggingface.co/datasets/Gourieff/ReActor/resolve/main/models/inswapper_128.onnx)
and put it to the `stable-diffusion-webui\models\insightface` replacing existing one
### **VI. "ValueError: This ORT build has ['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'] enabled" OR "ValueError: This ORT build has ['AzureExecutionProvider', 'CPUExecutionProvider'] enabled"**
diff --git a/README_RU.md b/README_RU.md
index a470c95..1ef8a6a 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
@@ -231,7 +231,7 @@ Inpainting также работает, но замена лица происх
Эта ошибка появляется, если что-то не так с файлом модели `inswapper_128.onnx`.
-Скачайте вручную по ссылке [here](https://github.com/facefusion/facefusion-assets/releases/download/models/inswapper_128.onnx)
+Скачайте вручную по ссылке [here](https://huggingface.co/datasets/Gourieff/ReActor/resolve/main/models/inswapper_128.onnx)
и сохраните в директорию `stable-diffusion-webui\models\insightface`, заменив имеющийся файл.
### **VI. "ValueError: This ORT build has ['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'] enabled" ИЛИ "ValueError: This ORT build has ['AzureExecutionProvider', 'CPUExecutionProvider'] enabled"**
diff --git a/install.py b/install.py
index fab874b..444a8f6 100644
--- a/install.py
+++ b/install.py
@@ -35,7 +35,7 @@ models_dir = os.path.join(models_path, "insightface")
# except Exception as e:
# print(f"OSError: {e}")
-model_url = "https://github.com/facefusion/facefusion-assets/releases/download/models/inswapper_128.onnx"
+model_url = "https://huggingface.co/datasets/Gourieff/ReActor/resolve/main/models/inswapper_128.onnx"
model_name = os.path.basename(model_url)
model_path = os.path.join(models_dir, model_name)
diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py
index b46bbde..0e1a852 100644
--- a/scripts/reactor_version.py
+++ b/scripts/reactor_version.py
@@ -1,5 +1,5 @@
app_title = "ReActor"
-version_flag = "v0.6.0-b1"
+version_flag = "v0.6.0"
from scripts.reactor_logger import logger, get_Run, set_Run
from scripts.reactor_globals import DEVICE
From 472c75ee880097209a97168d33ceaba6035eaddc Mon Sep 17 00:00:00 2001
From: Art Gourieff <85128026+Gourieff@users.noreply.github.com>
Date: Tue, 16 Jan 2024 13:50:20 +0700
Subject: [PATCH 17/35] FIX: API base64 decode error if select_source != 0
Issue #266
+VersionUP (0.6.1 beta1)
---
README.md | 2 +-
README_RU.md | 2 +-
scripts/reactor_api.py | 4 ++--
scripts/reactor_version.py | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index d5882b6..424fe4a 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/README_RU.md b/README_RU.md
index 1ef8a6a..a2f4e78 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/scripts/reactor_api.py b/scripts/reactor_api.py
index a982ae1..4d9ce48 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.1 ---
+--- ReActor External API v1.0.2 ---
-----------------------------------
'''
import os, glob
@@ -77,7 +77,7 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
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")
):
- s_image = api.decode_base64_to_image(source_image)
+ s_image = api.decode_base64_to_image(source_image) if select_source == 0 else None
t_image = api.decode_base64_to_image(target_image)
sf_index = source_faces_index
f_index = face_index
diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py
index 0e1a852..b6a089e 100644
--- a/scripts/reactor_version.py
+++ b/scripts/reactor_version.py
@@ -1,5 +1,5 @@
app_title = "ReActor"
-version_flag = "v0.6.0"
+version_flag = "v0.6.1-b1"
from scripts.reactor_logger import logger, get_Run, set_Run
from scripts.reactor_globals import DEVICE
From de43816a3bac3cf07ec91f5d9459b65110611c01 Mon Sep 17 00:00:00 2001
From: Art Gourieff <85128026+Gourieff@users.noreply.github.com>
Date: Fri, 19 Jan 2024 15:38:08 +0700
Subject: [PATCH 18/35] UPDATE: Random Image from Folder; FIX: save_orig
FR: #250 #252
---
README.md | 14 +++++++++--
README_RU.md | 14 +++++++++--
example/api_example.py | 2 ++
example/api_external.curl | 4 +++-
example/api_external.json | 4 +++-
reactor_ui/reactor_main_ui.py | 44 +++++++++++++++++++++--------------
scripts/reactor_api.py | 8 ++++---
scripts/reactor_faceswap.py | 31 ++++++++++++++++++++----
scripts/reactor_helpers.py | 7 +++++-
scripts/reactor_swapper.py | 8 ++++++-
scripts/reactor_version.py | 2 +-
11 files changed, 104 insertions(+), 34 deletions(-)
diff --git a/README.md b/README.md
index 424fe4a..ea68037 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
@@ -40,8 +40,18 @@
## What's new in the latest updates
-### 0.6.0 ALPHA1
+### 0.6.1 BETA2
+- 'Save orignal' option works fine now when you select 'Multiple Images' or 'Source Folder'
+- Random Mode for 'Source Folder'
+
+
+
+### 0.6.0
+
+- New Logo
+- Adaptation to A1111 1.7.0 (appropriate GFPGAN loader)
+- New URL for the main model file
- UI reworked
- You can now load several source images (with reference faces) or set the path to the folder containing faces images
diff --git a/README_RU.md b/README_RU.md
index a2f4e78..3cbe555 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
@@ -39,8 +39,18 @@
## Что нового в последних обновлениях
-### 0.6.0 ALPHA1
+### 0.6.1 BETA2
+- Опция 'Save orignal' теперь работает правильно, когда вы выбираете 'Multiple Images' или 'Source Folder'
+- Добавлен режим выбора случайного изображения для 'Source Folder'
+
+
+
+### 0.6.0
+
+- Новый логотип
+- Адаптация к версии A1111 1.7.0 (правильная загрузка GFPGAN)
+- Новая ссылка для файла основной модели
- UI переработан
- Появилась возможность загружать несколько исходных изображений с лицами или задавать путь к папке, содержащей такие изображения
diff --git a/example/api_example.py b/example/api_example.py
index 9a0caf0..3c9e3c4 100644
--- a/example/api_example.py
+++ b/example/api_example.py
@@ -47,6 +47,8 @@ args=[
1, #22 Select Source, 0 - Image, 1 - Face Model, 2 - Source Folder
"elena.safetensors", #23 Filename of the face model (from "models/reactor/faces"), e.g. elena.safetensors, don't forger to set #22 to 1
"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
]
# The args for ReActor can be found by
diff --git a/example/api_external.curl b/example/api_external.curl
index f324f0e..4033d84 100644
--- a/example/api_external.curl
+++ b/example/api_external.curl
@@ -22,5 +22,7 @@ curl -X POST \
"device": "CUDA",
"mask_face": 1,
"select_source": 1,
- "face_model": "elena.safetensors"
+ "face_model": "elena.safetensors",
+ "source_folder": "C:/faces",
+ "random_image": 1
}'
diff --git a/example/api_external.json b/example/api_external.json
index c4b32a4..542da69 100644
--- a/example/api_external.json
+++ b/example/api_external.json
@@ -18,5 +18,7 @@
"device": "CUDA",
"mask_face": 1,
"select_source": 1,
- "face_model": "elena.safetensors"
+ "face_model": "elena.safetensors",
+ "source_folder": "C:/faces",
+ "random_image": 1
}
\ No newline at end of file
diff --git a/reactor_ui/reactor_main_ui.py b/reactor_ui/reactor_main_ui.py
index 5b2b9a2..bbbd248 100644
--- a/reactor_ui/reactor_main_ui.py
+++ b/reactor_ui/reactor_main_ui.py
@@ -8,7 +8,7 @@ from scripts.reactor_swapper import (
)
from modules import shared
-SAVE_ORIGINAL: bool = False
+# SAVE_ORIGINAL: bool = False
def update_fm_list(selected: str):
return gr.Dropdown.update(
@@ -18,16 +18,17 @@ def update_fm_list(selected: str):
# TAB MAIN
def show(is_img2img: bool, show_br: bool = True, **msgs):
- def on_select_source(selected: bool, evt: gr.SelectData):
- global SAVE_ORIGINAL
+ # def on_select_source(selected: bool, evt: gr.SelectData):
+ def on_select_source(evt: gr.SelectData):
+ # global SAVE_ORIGINAL
if evt.index == 2:
- if SAVE_ORIGINAL != selected:
- SAVE_ORIGINAL = selected
+ # if SAVE_ORIGINAL != selected:
+ # SAVE_ORIGINAL = selected
return {
control_col_1: gr.Column.update(visible=False),
control_col_2: gr.Column.update(visible=False),
control_col_3: gr.Column.update(visible=True),
- save_original: gr.Checkbox.update(value=False,visible=False),
+ # save_original: gr.Checkbox.update(value=False,visible=False),
imgs_hash_clear: gr.Button.update(visible=True)
}
if evt.index == 0:
@@ -35,7 +36,7 @@ def show(is_img2img: bool, show_br: bool = True, **msgs):
control_col_1: gr.Column.update(visible=True),
control_col_2: gr.Column.update(visible=False),
control_col_3: gr.Column.update(visible=False),
- save_original: gr.Checkbox.update(value=SAVE_ORIGINAL,visible=show_br),
+ # save_original: gr.Checkbox.update(value=SAVE_ORIGINAL,visible=show_br),
imgs_hash_clear: gr.Button.update(visible=False)
}
if evt.index == 1:
@@ -43,7 +44,7 @@ def show(is_img2img: bool, show_br: bool = True, **msgs):
control_col_1: gr.Column.update(visible=False),
control_col_2: gr.Column.update(visible=True),
control_col_3: gr.Column.update(visible=False),
- save_original: gr.Checkbox.update(value=SAVE_ORIGINAL,visible=show_br),
+ # save_original: gr.Checkbox.update(value=SAVE_ORIGINAL,visible=show_br),
imgs_hash_clear: gr.Button.update(visible=False)
}
@@ -96,23 +97,31 @@ def show(is_img2img: bool, show_br: bool = True, **msgs):
)
with gr.Column(visible=False) as control_col_3:
gr.Markdown("Clear Hash if you see the previous face was swapped instead of the new one")
- source_folder = gr.Textbox(
- value="",
- placeholder="Paste here the path to the folder containing source faces images",
- label=f"Source Folder{msgs['extra_multiple_source']}",
- )
+ with gr.Row():
+ source_folder = gr.Textbox(
+ value="",
+ placeholder="Paste here the path to the folder containing source faces images",
+ label=f"Source Folder{msgs['extra_multiple_source']}",
+ scale=2,
+ )
+ random_image = gr.Checkbox(
+ False,
+ label="Random Image",
+ info="Randomly select an image from the path",
+ scale=1,
+ )
setattr(face_model, "do_not_save_to_config", True)
if is_img2img:
save_original = gr.Checkbox(
False,
label="Save Original (Swap in generated only)",
- info="Save the original image(s) made before swapping (it always saves Original when you use Multiple Images or Folder)"
+ info="Save the original image(s) made before swapping"
)
else:
save_original = gr.Checkbox(
False,
label="Save Original",
- info="Save the original image(s) made before swapping (it always saves Original when you use Multiple Images or Folder)",
+ info="Save the original image(s) made before swapping",
visible=show_br
)
# imgs.upload(on_files_upload_uncheck_so,[save_original],[save_original],show_progress=False)
@@ -177,6 +186,7 @@ def show(is_img2img: bool, show_br: bool = True, **msgs):
label="Swap in generated image",
visible=is_img2img,
)
- select_source.select(on_select_source,[save_original],[control_col_1,control_col_2,control_col_3,save_original,imgs_hash_clear],show_progress=False)
+ # select_source.select(on_select_source,[save_original],[control_col_1,control_col_2,control_col_3,save_original,imgs_hash_clear],show_progress=False)
+ select_source.select(on_select_source,None,[control_col_1,control_col_2,control_col_3,imgs_hash_clear],show_progress=False)
- return 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
+ return 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
diff --git a/scripts/reactor_api.py b/scripts/reactor_api.py
index 4d9ce48..6e0b69c 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.2 ---
+--- ReActor External API v1.0.3 ---
-----------------------------------
'''
import os, glob
@@ -75,7 +75,8 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
mask_face: int = Body(0,title="Face Mask Correction, 1 - True, 0 - False"),
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")
+ 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")
):
s_image = api.decode_base64_to_image(source_image) if select_source == 0 else None
t_image = api.decode_base64_to_image(target_image)
@@ -85,11 +86,12 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
gender_t = gender_target
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)
use_model = get_full_model(model)
if use_model is None:
Exception("Model not found")
- result = swap_face(s_image, t_image, use_model, sf_index, f_index, up_options, gender_s, gender_t, True, True, device, mask_face, select_source, face_model, source_folder, None)
+ result = swap_face(s_image, t_image, use_model, sf_index, f_index, up_options, gender_s, gender_t, True, True, device, mask_face, select_source, face_model, source_folder, None, random_image)
if save_to_file == 1:
if result_file_path == "":
result_file_path = default_file_path()
diff --git a/scripts/reactor_faceswap.py b/scripts/reactor_faceswap.py
index 1a45fab..61adcf0 100644
--- a/scripts/reactor_faceswap.py
+++ b/scripts/reactor_faceswap.py
@@ -63,7 +63,7 @@ class FaceSwapScript(scripts.Script):
msgs: dict = {
"extra_multiple_source": "",
}
- 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 = ui_main.show(is_img2img=is_img2img, **msgs)
+ 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()
@@ -103,6 +103,7 @@ class FaceSwapScript(scripts.Script):
face_model,
source_folder,
imgs,
+ random_image,
]
@@ -161,6 +162,7 @@ class FaceSwapScript(scripts.Script):
face_model,
source_folder,
imgs,
+ random_image,
):
self.enable = enable
if self.enable:
@@ -195,6 +197,7 @@ class FaceSwapScript(scripts.Script):
self.face_model = face_model
self.source_folder = source_folder
self.source_imgs = imgs
+ self.random_image = random_image
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":
@@ -217,9 +220,14 @@ class FaceSwapScript(scripts.Script):
self.target_hash_check = False
if self.mask_face is None:
self.mask_face = False
+ if self.random_image is None:
+ self.random_image = False
logger.debug("*** Set Device")
set_Device(self.device)
+
+ if (self.save_original is None or not self.save_original) and (self.select_source == 2 or self.source_imgs is not None):
+ p.do_not_save_samples = True
if ((self.source is not None or self.source_imgs is not None) and self.select_source == 0) or ((self.face_model is not None and self.face_model != "None") and self.select_source == 1) or ((self.source_folder is not None and self.source_folder != "") and self.select_source == 2):
logger.debug("*** Log patch")
@@ -247,6 +255,7 @@ class FaceSwapScript(scripts.Script):
face_model = self.face_model,
source_folder = None,
source_imgs = None,
+ random_image = False,
)
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")
@@ -311,17 +320,23 @@ class FaceSwapScript(scripts.Script):
face_model = self.face_model,
source_folder = self.source_folder,
source_imgs = self.source_imgs,
+ random_image = self.random_image,
)
if self.select_source == 2 or (self.select_source == 0 and self.source_imgs is not None and self.source is None):
if len(result) > 0 and swapped > 0:
- result_images.extend(result)
+ # result_images.extend(result)
+ if self.save_original:
+ result_images.extend(result)
+ else:
+ result_images = result
suffix = "-swapped"
for i,x in enumerate(result):
try:
- img_path = save_image(result[i], p.outpath_samples, "", p.all_seeds[0], p.all_prompts[0], "png",info=info, p=p, suffix=suffix)
+ img_path = save_image(result[i], 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)")
+
elif len(result) == 0:
logger.error("Cannot create a result image")
@@ -330,7 +345,7 @@ class FaceSwapScript(scripts.Script):
result_images.append(result)
suffix = "-swapped"
try:
- img_path = 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)")
elif result is None:
@@ -390,6 +405,7 @@ class FaceSwapScript(scripts.Script):
face_model = self.face_model,
source_folder = None,
source_imgs = None,
+ random_image = False,
)
try:
pp = scripts_postprocessing.PostprocessedImage(result)
@@ -425,7 +441,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
msgs: dict = {
"extra_multiple_source": " | Сomparison grid as a result",
}
- 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 = ui_main.show(is_img2img=False, show_br=False, **msgs)
+ 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)
@@ -460,6 +476,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
'face_model': face_model,
'source_folder': source_folder,
'imgs': imgs,
+ 'random_image': random_image,
}
return args
@@ -514,6 +531,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
self.face_model = args['face_model']
self.source_folder = args['source_folder']
self.source_imgs = args['imgs']
+ self.random_image = args['random_image']
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":
@@ -530,6 +548,8 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
self.faces_index = [0]
if self.mask_face is None:
self.mask_face = False
+ if self.random_image is None:
+ self.random_image = False
current_job_number = shared.state.job_no + 1
job_count = shared.state.job_count
@@ -565,6 +585,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
face_model=self.face_model,
source_folder=self.source_folder,
source_imgs=self.source_imgs,
+ random_image=self.random_image,
)
if self.select_source == 2 or (self.select_source == 0 and self.source_imgs is not None and self.source is None):
if len(result) > 0 and swapped > 0:
diff --git a/scripts/reactor_helpers.py b/scripts/reactor_helpers.py
index 0290425..c3384bd 100644
--- a/scripts/reactor_helpers.py
+++ b/scripts/reactor_helpers.py
@@ -1,4 +1,4 @@
-import os, glob
+import os, glob, random
from collections import Counter
from PIL import Image
from math import isqrt, ceil
@@ -213,5 +213,10 @@ def get_images_from_folder(path: str):
images = glob.glob(images_path)
return [Image.open(x) for x in images if x.endswith(('jpg', 'png', 'jpeg', 'webp', 'bmp'))]
+def get_random_image_from_folder(path: str):
+ images = get_images_from_folder(path)
+ random_image_index = random.randint(0, len(images) - 1)
+ return [images[random_image_index]]
+
def get_images_from_list(imgs: List):
return [Image.open(os.path.abspath(x.name)) for x in imgs]
diff --git a/scripts/reactor_swapper.py b/scripts/reactor_swapper.py
index c92cae4..6d771ee 100644
--- a/scripts/reactor_swapper.py
+++ b/scripts/reactor_swapper.py
@@ -17,6 +17,7 @@ from scripts.reactor_helpers import (
save_face_model,
load_face_model,
get_images_from_folder,
+ get_random_image_from_folder,
get_images_from_list,
set_SDNEXT
)
@@ -335,6 +336,7 @@ def swap_face(
face_model: str = "None",
source_folder: str = "",
source_imgs: Union[List, None] = None,
+ random_image: bool = False,
):
global SOURCE_FACES, SOURCE_IMAGE_HASH, TARGET_FACES, TARGET_IMAGE_HASH, PROVIDERS, SOURCE_FACES_LIST, SOURCE_IMAGE_LIST_HASH
@@ -376,7 +378,11 @@ def swap_face(
result = []
- source_images = get_images_from_folder(source_folder) if select_source == 2 else get_images_from_list(source_imgs)
+ if random_image and select_source == 2:
+ source_images = get_random_image_from_folder(source_folder)
+ logger.status("Processing with Random Image from the folder")
+ else:
+ source_images = get_images_from_folder(source_folder) if select_source == 2 else get_images_from_list(source_imgs)
if len(source_images) > 0:
source_img_ff = []
diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py
index b6a089e..e119b0b 100644
--- a/scripts/reactor_version.py
+++ b/scripts/reactor_version.py
@@ -1,5 +1,5 @@
app_title = "ReActor"
-version_flag = "v0.6.1-b1"
+version_flag = "v0.6.1-b2"
from scripts.reactor_logger import logger, get_Run, set_Run
from scripts.reactor_globals import DEVICE
From c5ecf9a1940b3cb693e6423af8a11fa5bff348bd Mon Sep 17 00:00:00 2001
From: Art Gourieff <85128026+Gourieff@users.noreply.github.com>
Date: Fri, 19 Jan 2024 15:39:42 +0700
Subject: [PATCH 19/35] FIX: typo
---
README.md | 2 +-
README_RU.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index ea68037..c9ba481 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@
### 0.6.1 BETA2
-- 'Save orignal' option works fine now when you select 'Multiple Images' or 'Source Folder'
+- 'Save original' option works fine now when you select 'Multiple Images' or 'Source Folder'
- Random Mode for 'Source Folder'
diff --git a/README_RU.md b/README_RU.md
index 3cbe555..6154eb2 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -41,7 +41,7 @@
### 0.6.1 BETA2
-- Опция 'Save orignal' теперь работает правильно, когда вы выбираете 'Multiple Images' или 'Source Folder'
+- Опция 'Save original' теперь работает правильно, когда вы выбираете 'Multiple Images' или 'Source Folder'
- Добавлен режим выбора случайного изображения для 'Source Folder'
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 20/35] 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 @@
- 
+ 
@@ -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 @@
- 
+ 
@@ -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 @@ args=[
"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 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
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 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
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 @@ class FaceSwapScript(scripts.Script):
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 @@ class FaceSwapScript(scripts.Script):
source_folder,
imgs,
random_image,
+ upscale_force
]
@@ -124,13 +125,14 @@ class FaceSwapScript(scripts.Script):
@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 @@ class FaceSwapScript(scripts.Script):
source_folder,
imgs,
random_image,
+ upscale_force,
):
self.enable = enable
if self.enable:
@@ -198,6 +201,7 @@ class FaceSwapScript(scripts.Script):
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 @@ class FaceSwapScript(scripts.Script):
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 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
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 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
'source_folder': source_folder,
'imgs': imgs,
'random_image': random_image,
+ 'upscale_force': upscale_force,
}
return args
@@ -504,6 +511,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
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 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
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 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
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
From a93e04ea132bca2f223a3494e653cc2a7ba436eb Mon Sep 17 00:00:00 2001
From: Art Gourieff <85128026+Gourieff@users.noreply.github.com>
Date: Sat, 3 Feb 2024 01:01:08 +0700
Subject: [PATCH 21/35] UPDATE: Filenames w/ Multiple or Random; FIX: #342
FR #332
Issue #342
---
README.md | 1 +
README_RU.md | 1 +
scripts/reactor_faceswap.py | 29 +++++++++++++++++++++++++++--
scripts/reactor_helpers.py | 25 +++++++++++++++++++------
scripts/reactor_swapper.py | 12 ++++++------
5 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 672e137..0ac86bd 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,7 @@
### 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)
+- ReActor shows filenames of source images in-process when the multiple images mode or the folder mode (random as well) is selected
### 0.6.1 BETA2
diff --git a/README_RU.md b/README_RU.md
index f595cc6..36cef74 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -42,6 +42,7 @@
### 0.6.1 BETA3
- Опция 'Force Upscale' внутри вкладки 'Upscale': апскейл выполнится, даже если не было обнаружено ни одного лица (FR https://github.com/Gourieff/sd-webui-reactor/issues/116)
+- Отображение имён файлов используемых изображений, когда выбрано несколько изображений или папка (а также режим случайного изображения)
### 0.6.1 BETA2
diff --git a/scripts/reactor_faceswap.py b/scripts/reactor_faceswap.py
index cb4b9dd..604884a 100644
--- a/scripts/reactor_faceswap.py
+++ b/scripts/reactor_faceswap.py
@@ -238,7 +238,11 @@ class FaceSwapScript(scripts.Script):
if ((self.source is not None or self.source_imgs is not None) and self.select_source == 0) or ((self.face_model is not None and self.face_model != "None") and self.select_source == 1) or ((self.source_folder is not None and self.source_folder != "") and self.select_source == 2):
logger.debug("*** Log patch")
apply_logging_patch(console_logging_level)
+
if isinstance(p, StableDiffusionProcessingImg2Img) and self.swap_in_source:
+
+ logger.debug("*** Check process")
+
logger.status("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
for i in range(len(p.init_images)):
@@ -279,7 +283,7 @@ class FaceSwapScript(scripts.Script):
def postprocess(self, p: StableDiffusionProcessing, processed: Processed, *args):
if self.enable:
- logger.debug("*** Check postprocess")
+ logger.debug("*** Check postprocess - before IF")
reset_messaged()
if check_process_halt():
@@ -287,6 +291,8 @@ class FaceSwapScript(scripts.Script):
if self.save_original or ((self.select_source == 2 and self.source_folder is not None and self.source_folder != "") or (self.select_source == 0 and self.source_imgs is not None and self.source is None)):
+ logger.debug("*** Check postprocess - after IF")
+
postprocess_run: bool = True
orig_images : List[Image.Image] = processed.images[processed.index_of_first_image:]
@@ -373,6 +379,21 @@ class FaceSwapScript(scripts.Script):
processed.images = result_images
# processed.infotexts = result_info
+
+ elif self.select_source == 0 and self.source is not None and self.source_imgs is not None:
+
+ logger.debug("*** Check postprocess - after ELIF")
+
+ if self.result is not None:
+ orig_infotexts : List[str] = processed.infotexts[processed.index_of_first_image:]
+ processed.images = [self.result]
+ try:
+ img_path = save_image(self.result, p.outpath_samples, "", p.all_seeds[0], p.all_prompts[0], "png", info=orig_infotexts[0], p=p, suffix="")
+ except:
+ logger.error("Cannot save a result image - please, check SD WebUI Settings (Saving and Paths)")
+ else:
+ logger.error("Cannot create a result image")
+
def postprocess_batch(self, p, *args, **kwargs):
if self.enable and not self.save_original:
@@ -392,7 +413,7 @@ class FaceSwapScript(scripts.Script):
return
# if (self.source is not None and self.select_source == 0) or ((self.face_model is not None and self.face_model != "None") and self.select_source == 1):
- logger.status("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
+ logger.status("! Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
image: Image.Image = script_pp.image
result, output, swapped = swap_face(
self.source,
@@ -413,6 +434,7 @@ class FaceSwapScript(scripts.Script):
source_imgs = None,
random_image = False,
)
+ self.result = result
try:
pp = scripts_postprocessing.PostprocessedImage(result)
pp.info = {}
@@ -575,6 +597,9 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
logger.debug("We're here: process() 2")
+ if self.source is not None and self.select_source == 0:
+ self.source_imgs = None
+
apply_logging_patch(self.console_logging_level)
logger.status("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
# if self.select_source != 2:
diff --git a/scripts/reactor_helpers.py b/scripts/reactor_helpers.py
index c3384bd..6c31dfe 100644
--- a/scripts/reactor_helpers.py
+++ b/scripts/reactor_helpers.py
@@ -209,14 +209,27 @@ def get_model_names(get_models):
return names
def get_images_from_folder(path: str):
- images_path = os.path.join(path, "*")
- images = glob.glob(images_path)
- return [Image.open(x) for x in images if x.endswith(('jpg', 'png', 'jpeg', 'webp', 'bmp'))]
+ files_path = os.path.join(path, "*")
+ files = glob.glob(files_path)
+ images = []
+ images_names = []
+ for x in files:
+ if x.endswith(('jpg', 'png', 'jpeg', 'webp', 'bmp')):
+ images.append(Image.open(x))
+ images_names.append(os.path.basename(x))
+ return images,images_names
+ # return [Image.open(x) for x in images if x.endswith(('jpg', 'png', 'jpeg', 'webp', 'bmp'))],[os.path.basename(x) for x in images if x.endswith(('jpg', 'png', 'jpeg', 'webp', 'bmp'))]
def get_random_image_from_folder(path: str):
- images = get_images_from_folder(path)
+ images,names = get_images_from_folder(path)
random_image_index = random.randint(0, len(images) - 1)
- return [images[random_image_index]]
+ return [images[random_image_index]],[names[random_image_index]]
def get_images_from_list(imgs: List):
- return [Image.open(os.path.abspath(x.name)) for x in imgs]
+ images = []
+ images_names = []
+ for x in imgs:
+ images.append(Image.open(os.path.abspath(x.name)))
+ images_names.append(os.path.basename(x.name))
+ return images,images_names
+ # return [Image.open(os.path.abspath(x.name)) for x in imgs],[os.path.basename(x.name) for x in imgs]
diff --git a/scripts/reactor_swapper.py b/scripts/reactor_swapper.py
index 9a9641f..6d34648 100644
--- a/scripts/reactor_swapper.py
+++ b/scripts/reactor_swapper.py
@@ -380,10 +380,10 @@ def swap_face(
result = []
if random_image and select_source == 2:
- source_images = get_random_image_from_folder(source_folder)
- logger.status("Processing with Random Image from the folder")
+ source_images,source_images_names = get_random_image_from_folder(source_folder)
+ logger.status(f"Processing with Random Image from the folder: {source_images_names[0]}")
else:
- source_images = get_images_from_folder(source_folder) if select_source == 2 else get_images_from_list(source_imgs)
+ source_images,source_images_names = get_images_from_folder(source_folder) if select_source == 2 else get_images_from_list(source_imgs)
if len(source_images) > 0:
source_img_ff = []
@@ -412,15 +412,15 @@ def swap_face(
logger.info("(Image %s) Source Image the Same? %s", i, source_image_same)
if len(SOURCE_FACES_LIST) == 0:
- logger.status(f"Analyzing Source Image {i}...")
+ logger.status(f"Analyzing Source Image {i}: {source_images_names[i]}...")
source_faces = analyze_faces(source_image)
SOURCE_FACES_LIST = [source_faces]
elif len(SOURCE_FACES_LIST) == i and not source_image_same:
- logger.status(f"Analyzing Source Image {i}...")
+ logger.status(f"Analyzing Source Image {i}: {source_images_names[i]}...")
source_faces = analyze_faces(source_image)
SOURCE_FACES_LIST.append(source_faces)
elif len(SOURCE_FACES_LIST) != i and not source_image_same:
- logger.status(f"Analyzing Source Image {i}...")
+ logger.status(f"Analyzing Source Image {i}: {source_images_names[i]}...")
source_faces = analyze_faces(source_image)
SOURCE_FACES_LIST[i] = source_faces
elif source_image_same:
From 4a7a367ea1a5ea7a7215269bf1c251ae30e40eb1 Mon Sep 17 00:00:00 2001
From: Art Gourieff <85128026+Gourieff@users.noreply.github.com>
Date: Sat, 3 Feb 2024 15:25:08 +0700
Subject: [PATCH 22/35] VersionUP (0.6.1, beta passed)
---
README.md | 2 +-
README_RU.md | 2 +-
scripts/reactor_version.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 0ac86bd..4f8bdc2 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/README_RU.md b/README_RU.md
index 36cef74..2204dd6 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
diff --git a/scripts/reactor_version.py b/scripts/reactor_version.py
index 0728bcd..ec858c1 100644
--- a/scripts/reactor_version.py
+++ b/scripts/reactor_version.py
@@ -1,5 +1,5 @@
app_title = "ReActor"
-version_flag = "v0.6.1-b3"
+version_flag = "v0.6.1"
from scripts.reactor_logger import logger, get_Run, set_Run
from scripts.reactor_globals import DEVICE
From 96d7a0629196f6c554e0a7803bb5e1e4acce9318 Mon Sep 17 00:00:00 2001
From: Art Gourieff <85128026+Gourieff@users.noreply.github.com>
Date: Sun, 11 Feb 2024 19:52:01 +0700
Subject: [PATCH 23/35] UPDATE: Blended Faces, CU12, Detection Tab
+VersionUP (0.7.0 alpha1)
FR #143 #255 (partly) #280 (partly) #352
Issue #319
---
README.md | 11 +-
README_RU.md | 11 +-
example/api_example.py | 2 +
...nsightface-0.7.3-cp310-cp310-win_amd64.whl | Bin 841704 -> 0 bytes
install.py | 11 +-
reactor_ui/__init__.py | 1 +
reactor_ui/reactor_detection_ui.py | 54 +++++++
reactor_ui/reactor_tools_ui.py | 72 ++++++---
scripts/reactor_api.py | 11 +-
scripts/reactor_faceswap.py | 59 +++++--
scripts/reactor_swapper.py | 147 ++++++++++++++----
scripts/reactor_version.py | 2 +-
12 files changed, 314 insertions(+), 67 deletions(-)
delete mode 100644 example/insightface-0.7.3-cp310-cp310-win_amd64.whl
create mode 100644 reactor_ui/reactor_detection_ui.py
diff --git a/README.md b/README.md
index 4f8bdc2..63ddfef 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
- 
+ 
@@ -40,6 +40,15 @@
## What's new in the latest updates
+### 0.7.0 ALPHA1
+
+- You can now blend faces to build blended face models ("Tools->Face Models->Blend") - due to popular demand
+
+
+
+- CUDA 12 Support in the Installer script for 1.17.0 ORT-GPU library
+- New tab "Detection" with "Threshold" and "Max Faces" parameters
+
### 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)
diff --git a/README_RU.md b/README_RU.md
index 2204dd6..ab50a72 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
- 
+ 
@@ -39,6 +39,15 @@
## Что нового в последних обновлениях
+### 0.7.0 ALPHA1
+
+- По многочисленным просьбам появилась возможность строить смешанные модели лиц ("Tools->Face Models->Blend")
+
+
+
+- Поддержка CUDA 12 в скрипте установщика для библиотеки ORT-GPU версии 1.17.0
+- Новая вкладка "Detection" с параметрами "Threshold" и "Max Faces"
+
### 0.6.1 BETA3
- Опция 'Force Upscale' внутри вкладки 'Upscale': апскейл выполнится, даже если не было обнаружено ни одного лица (FR https://github.com/Gourieff/sd-webui-reactor/issues/116)
diff --git a/example/api_example.py b/example/api_example.py
index f683ee5..d3bc64a 100644
--- a/example/api_example.py
+++ b/example/api_example.py
@@ -50,6 +50,8 @@ args=[
None, #25 skip it for API
True, #26 Randomly select an image from the path
True, #27 Force Upscale even if no face found
+ 0.6, #28 Face Detection Threshold
+ 2, #29 Maximum number of faces to detect (0 is unlimited)
]
# The args for ReActor can be found by
diff --git a/example/insightface-0.7.3-cp310-cp310-win_amd64.whl b/example/insightface-0.7.3-cp310-cp310-win_amd64.whl
deleted file mode 100644
index 4f71ef2ff2ea1ce366b3e3083b510b099882e0b1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 841704
zcmZ_#V~}RSwk?2`%`V%vZQJHow(aV&ZL7<+ZL7<+ZM{DCy|{7rj`MzGtXRJ?a*UBP
zXO1~jQ3ezY6$l6j3Mh&1w>lEB^TEr%zcOGTAdG)sOFL&va|;(UfUzlqfq|u+rHg?9
zy@RJ-T)q4tBT}flz%Ugaj0g!Sgd%Au0-Nt$D?JjG>lYdn4?-R+0d~FD
z_O}iObMPcAJBTSX-CNG3?tvCOowd7qmzHQ^CQpPmd_&93)z|3+bG|H_QuLHi@tzsi
z5t=o#3+3_))97@#)%~Dax6yV9gmcIHS`}~EPRwJOs$;9!k!%}M8`pHK9Iy7Y>2ka~
zzqigxeLb(w0Qq(HxZ_peU$PR885Y3@?^@kjj)MxWDd-MysoW
zFCs3tHcajnKJ6_@fm*K;--4dQQkSp2%Ny!6qg#Wo>Dvde*l@XDRa5qNEpWZN2jTNy
zS33K!F^XG4RNLmpV8020dgd2DYj6fR0sd^R^s-0g*}z~l-?AeH@<~7mvCX=R7+5Xg
zZs}i`(xshRJK{kW?UAjaO8;x{DYZZOuhC|jF(hXAOkL@eyq^|?*n7Q9cRHSy<0;5R
z7RzE$<}nbh=8I@{h~J-g=)n0b?E<{c
xq(1ctLDaua-3C8oKt1<1>YtwGlzXPa=LfHV
zvSxkVbZPL#ejDyLC;}^@&f--yc}A;si|91
BEb_FoTCsZq_l7b;^6W7T
vI<6OD~kl^x#!}s*fG24AA0J6~vfYsRagLe8H9&kA1e{mk;R&Hyy#@}+8ts`dygDtQ$gKOZhF(&8M+d
Ktj{`>ub@uf``U)~Nfy{1aUm9}&9~9ex%qM3lBDw(@r%*kTz)
zZH$v(x+zgiSGK#Bze;H)ipDRXzI1WSK#r!(&u$2rE3$}|9xyOVrauYz5oYT5rO3%k
zfia%~h&QA&DESq0+~i|2!j=rpWKK1lNq@BD$(7G86Ky~6F86_1WzFbc>wJOVyS0Wm
zc(ufyCEjz8HBRGHyZ$WtAa`h0`&dCq@S?b3{bHK>THEY^eFsWfrp}htR`4P_J4$