Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,20 +1,17 @@
|
|
| 1 |
import os
|
| 2 |
-
import cv2
|
| 3 |
-
import glob
|
| 4 |
import time
|
| 5 |
-
import torch
|
| 6 |
import shutil
|
| 7 |
import argparse
|
| 8 |
-
import subprocess
|
| 9 |
-
import onnxruntime
|
| 10 |
-
import numpy as np
|
| 11 |
-
import gradio as gr
|
| 12 |
import concurrent.futures
|
| 13 |
-
from tqdm import tqdm
|
| 14 |
-
from moviepy.editor import VideoFileClip
|
| 15 |
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
| 17 |
import spaces
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
from face_swapper import Inswapper, paste_to_whole
|
| 20 |
from face_analyser import detect_conditions, get_analysed_data, swap_options_list
|
|
@@ -23,25 +20,26 @@ from face_enhancer import get_available_enhancer_names, load_face_enhancer_model
|
|
| 23 |
from utils import trim_video, open_directory, split_list_by_lengths, merge_img_sequence_from_ref, create_image_grid
|
| 24 |
|
| 25 |
parser = argparse.ArgumentParser(description="Free Face Swapper")
|
| 26 |
-
parser.add_argument("--out_dir",
|
| 27 |
-
parser.add_argument("--batch_size",
|
| 28 |
-
parser.add_argument("--cuda", action="store_true",
|
| 29 |
-
parser.add_argument("--colab", action="store_true",
|
| 30 |
-
|
| 31 |
|
| 32 |
-
USE_COLAB =
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
BATCH_SIZE = int(user_args.batch_size)
|
| 36 |
|
| 37 |
WORKSPACE = None
|
| 38 |
OUTPUT_FILE = None
|
| 39 |
PREVIEW = None
|
| 40 |
STREAMER = None
|
|
|
|
| 41 |
DETECT_CONDITION = "best detection"
|
| 42 |
DETECT_SIZE = 640
|
| 43 |
DETECT_THRESH = 0.6
|
| 44 |
NUM_OF_SRC_SPECIFIC = 10
|
|
|
|
| 45 |
MASK_INCLUDE = ["Skin", "R-Eyebrow", "L-Eyebrow", "L-Eye", "R-Eye", "Nose", "Mouth", "L-Lip", "U-Lip"]
|
| 46 |
MASK_SOFT_KERNEL = 17
|
| 47 |
MASK_SOFT_ITERATIONS = 10
|
|
@@ -52,6 +50,7 @@ FACE_SWAPPER = None
|
|
| 52 |
FACE_ANALYSER = None
|
| 53 |
FACE_ENHANCER = None
|
| 54 |
FACE_PARSER = None
|
|
|
|
| 55 |
FACE_ENHANCER_LIST = ["NONE"]
|
| 56 |
FACE_ENHANCER_LIST.extend(get_available_enhancer_names())
|
| 57 |
FACE_ENHANCER_LIST.extend(cv2_interpolations)
|
|
@@ -156,13 +155,10 @@ def process(
|
|
| 156 |
matrs.extend(batch_matr)
|
| 157 |
empty_cache()
|
| 158 |
|
| 159 |
-
generated_len = len(preds)
|
| 160 |
-
|
| 161 |
if face_enhancer_name != "NONE" and FACE_ENHANCER is not None:
|
| 162 |
enhancer_model, enhancer_model_runner = FACE_ENHANCER
|
| 163 |
for idx, pred in enumerate(preds):
|
| 164 |
-
|
| 165 |
-
preds[idx] = cv2.resize(pred, (512, 512))
|
| 166 |
empty_cache()
|
| 167 |
|
| 168 |
if enable_face_parser:
|
|
@@ -179,7 +175,7 @@ def process(
|
|
| 179 |
empty_cache()
|
| 180 |
masks = np.concatenate(masks, axis=0) if len(masks) >= 1 else masks
|
| 181 |
else:
|
| 182 |
-
masks = [None] *
|
| 183 |
|
| 184 |
split_preds = split_list_by_lengths(preds, num_faces_per_frame)
|
| 185 |
split_matrs = split_list_by_lengths(matrs, num_faces_per_frame)
|
|
@@ -265,32 +261,25 @@ with gr.Blocks(css=css) as interface:
|
|
| 265 |
with gr.Column(scale=0.4):
|
| 266 |
swap_option = gr.Dropdown(swap_options_list, value=swap_options_list[0], interactive=True, show_label=False)
|
| 267 |
age = gr.Number(value=25, interactive=True, visible=False)
|
| 268 |
-
|
| 269 |
detect_condition_dropdown = gr.Dropdown(detect_conditions, label="Condition", value=DETECT_CONDITION)
|
| 270 |
detection_size = gr.Number(label="Detection Size", value=DETECT_SIZE)
|
| 271 |
detection_threshold = gr.Number(label="Detection Threshold", value=DETECT_THRESH)
|
| 272 |
-
|
| 273 |
output_directory = gr.Text(label="Output Directory", value=DEF_OUTPUT_PATH)
|
| 274 |
output_name = gr.Text(label="Output Name", value="Result")
|
| 275 |
keep_output_sequence = gr.Checkbox(label="Keep output sequence", value=False)
|
| 276 |
-
|
| 277 |
face_scale = gr.Slider(label="Face Scale", minimum=0, maximum=2, value=1)
|
| 278 |
face_enhancer_name = gr.Dropdown(FACE_ENHANCER_LIST, label="Face Enhancer", value="NONE")
|
| 279 |
-
|
| 280 |
enable_face_parser_mask = gr.Checkbox(label="Enable Face Parsing", value=False)
|
| 281 |
mask_include = gr.Dropdown(mask_regions.keys(), value=MASK_INCLUDE, multiselect=True, label="Include")
|
| 282 |
mask_soft_kernel = gr.Number(label="Soft Erode Kernel", value=MASK_SOFT_KERNEL, visible=False)
|
| 283 |
mask_soft_iterations = gr.Number(label="Soft Erode Iterations", value=MASK_SOFT_ITERATIONS)
|
| 284 |
-
|
| 285 |
crop_top = gr.Slider(label="Top", minimum=0, maximum=511, value=0, step=1)
|
| 286 |
crop_bott = gr.Slider(label="Bottom", minimum=0, maximum=511, value=511, step=1)
|
| 287 |
crop_left = gr.Slider(label="Left", minimum=0, maximum=511, value=0, step=1)
|
| 288 |
crop_right = gr.Slider(label="Right", minimum=0, maximum=511, value=511, step=1)
|
| 289 |
-
|
| 290 |
erode_amount = gr.Slider(label="Mask Erode", minimum=0, maximum=1, value=MASK_ERODE_AMOUNT, step=0.05)
|
| 291 |
blur_amount = gr.Slider(label="Mask Blur", minimum=0, maximum=1, value=MASK_BLUR_AMOUNT, step=0.05)
|
| 292 |
enable_laplacian_blend = gr.Checkbox(label="Laplacian Blending", value=True)
|
| 293 |
-
|
| 294 |
source_image_input = gr.Image(label="Source face", type="filepath", interactive=True)
|
| 295 |
input_type = gr.Radio(["Image", "Video"], label="Target Type", value="Image")
|
| 296 |
image_input = gr.Image(label="Target Image", interactive=True, type="filepath")
|
|
@@ -309,40 +298,18 @@ with gr.Blocks(css=css) as interface:
|
|
| 309 |
for i in range(NUM_OF_SRC_SPECIFIC):
|
| 310 |
exec(f"src{i+1} = gr.Image(interactive=True, type='numpy', label='Source Face {i+1}')")
|
| 311 |
exec(f"trg{i+1} = gr.Image(interactive=True, type='numpy', label='Specific Face {i+1}')")
|
| 312 |
-
|
| 313 |
-
gen_variable_txt = ",".join([f"src{i+1}" for i in range(NUM_OF_SRC_SPECIFIC)] + [f"trg{i+1}" for i in range(NUM_OF_SRC_SPECIFIC)])
|
| 314 |
-
exec(f"src_specific_inputs = ({gen_variable_txt})")
|
| 315 |
|
| 316 |
swap_inputs = [
|
| 317 |
-
input_type,
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
output_directory,
|
| 323 |
-
output_name,
|
| 324 |
-
keep_output_sequence,
|
| 325 |
-
swap_option,
|
| 326 |
-
age,
|
| 327 |
-
gr.Number(value=0.6),
|
| 328 |
-
face_enhancer_name,
|
| 329 |
-
enable_face_parser_mask,
|
| 330 |
-
mask_include,
|
| 331 |
-
mask_soft_kernel,
|
| 332 |
-
mask_soft_iterations,
|
| 333 |
-
blur_amount,
|
| 334 |
-
erode_amount,
|
| 335 |
-
face_scale,
|
| 336 |
-
enable_laplacian_blend,
|
| 337 |
-
crop_top,
|
| 338 |
-
crop_bott,
|
| 339 |
-
crop_left,
|
| 340 |
-
crop_right,
|
| 341 |
-
*src_specific_inputs,
|
| 342 |
]
|
| 343 |
|
| 344 |
swap_button.click(fn=process, inputs=swap_inputs, outputs=[info, preview_image, output_directory_button, output_video_button, preview_video], show_progress=True)
|
| 345 |
cancel_button.click(fn=stop_running, inputs=None, outputs=[info])
|
| 346 |
|
| 347 |
if __name__ == "__main__":
|
| 348 |
-
interface.queue(
|
|
|
|
| 1 |
import os
|
|
|
|
|
|
|
| 2 |
import time
|
|
|
|
| 3 |
import shutil
|
| 4 |
import argparse
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
import concurrent.futures
|
|
|
|
|
|
|
| 6 |
|
| 7 |
+
import cv2
|
| 8 |
+
import numpy as np
|
| 9 |
+
import torch
|
| 10 |
+
import gradio as gr
|
| 11 |
import spaces
|
| 12 |
+
import onnxruntime
|
| 13 |
+
from moviepy.editor import VideoFileClip
|
| 14 |
+
from tqdm import tqdm
|
| 15 |
|
| 16 |
from face_swapper import Inswapper, paste_to_whole
|
| 17 |
from face_analyser import detect_conditions, get_analysed_data, swap_options_list
|
|
|
|
| 20 |
from utils import trim_video, open_directory, split_list_by_lengths, merge_img_sequence_from_ref, create_image_grid
|
| 21 |
|
| 22 |
parser = argparse.ArgumentParser(description="Free Face Swapper")
|
| 23 |
+
parser.add_argument("--out_dir", default=os.getcwd())
|
| 24 |
+
parser.add_argument("--batch_size", default=32)
|
| 25 |
+
parser.add_argument("--cuda", action="store_true", default=False)
|
| 26 |
+
parser.add_argument("--colab", action="store_true", default=False)
|
| 27 |
+
args, _ = parser.parse_known_args()
|
| 28 |
|
| 29 |
+
USE_COLAB = args.colab
|
| 30 |
+
DEF_OUTPUT_PATH = args.out_dir
|
| 31 |
+
BATCH_SIZE = int(args.batch_size)
|
|
|
|
| 32 |
|
| 33 |
WORKSPACE = None
|
| 34 |
OUTPUT_FILE = None
|
| 35 |
PREVIEW = None
|
| 36 |
STREAMER = None
|
| 37 |
+
|
| 38 |
DETECT_CONDITION = "best detection"
|
| 39 |
DETECT_SIZE = 640
|
| 40 |
DETECT_THRESH = 0.6
|
| 41 |
NUM_OF_SRC_SPECIFIC = 10
|
| 42 |
+
|
| 43 |
MASK_INCLUDE = ["Skin", "R-Eyebrow", "L-Eyebrow", "L-Eye", "R-Eye", "Nose", "Mouth", "L-Lip", "U-Lip"]
|
| 44 |
MASK_SOFT_KERNEL = 17
|
| 45 |
MASK_SOFT_ITERATIONS = 10
|
|
|
|
| 50 |
FACE_ANALYSER = None
|
| 51 |
FACE_ENHANCER = None
|
| 52 |
FACE_PARSER = None
|
| 53 |
+
|
| 54 |
FACE_ENHANCER_LIST = ["NONE"]
|
| 55 |
FACE_ENHANCER_LIST.extend(get_available_enhancer_names())
|
| 56 |
FACE_ENHANCER_LIST.extend(cv2_interpolations)
|
|
|
|
| 155 |
matrs.extend(batch_matr)
|
| 156 |
empty_cache()
|
| 157 |
|
|
|
|
|
|
|
| 158 |
if face_enhancer_name != "NONE" and FACE_ENHANCER is not None:
|
| 159 |
enhancer_model, enhancer_model_runner = FACE_ENHANCER
|
| 160 |
for idx, pred in enumerate(preds):
|
| 161 |
+
preds[idx] = cv2.resize(enhancer_model_runner(pred, enhancer_model), (512, 512))
|
|
|
|
| 162 |
empty_cache()
|
| 163 |
|
| 164 |
if enable_face_parser:
|
|
|
|
| 175 |
empty_cache()
|
| 176 |
masks = np.concatenate(masks, axis=0) if len(masks) >= 1 else masks
|
| 177 |
else:
|
| 178 |
+
masks = [None] * len(preds)
|
| 179 |
|
| 180 |
split_preds = split_list_by_lengths(preds, num_faces_per_frame)
|
| 181 |
split_matrs = split_list_by_lengths(matrs, num_faces_per_frame)
|
|
|
|
| 261 |
with gr.Column(scale=0.4):
|
| 262 |
swap_option = gr.Dropdown(swap_options_list, value=swap_options_list[0], interactive=True, show_label=False)
|
| 263 |
age = gr.Number(value=25, interactive=True, visible=False)
|
|
|
|
| 264 |
detect_condition_dropdown = gr.Dropdown(detect_conditions, label="Condition", value=DETECT_CONDITION)
|
| 265 |
detection_size = gr.Number(label="Detection Size", value=DETECT_SIZE)
|
| 266 |
detection_threshold = gr.Number(label="Detection Threshold", value=DETECT_THRESH)
|
|
|
|
| 267 |
output_directory = gr.Text(label="Output Directory", value=DEF_OUTPUT_PATH)
|
| 268 |
output_name = gr.Text(label="Output Name", value="Result")
|
| 269 |
keep_output_sequence = gr.Checkbox(label="Keep output sequence", value=False)
|
|
|
|
| 270 |
face_scale = gr.Slider(label="Face Scale", minimum=0, maximum=2, value=1)
|
| 271 |
face_enhancer_name = gr.Dropdown(FACE_ENHANCER_LIST, label="Face Enhancer", value="NONE")
|
|
|
|
| 272 |
enable_face_parser_mask = gr.Checkbox(label="Enable Face Parsing", value=False)
|
| 273 |
mask_include = gr.Dropdown(mask_regions.keys(), value=MASK_INCLUDE, multiselect=True, label="Include")
|
| 274 |
mask_soft_kernel = gr.Number(label="Soft Erode Kernel", value=MASK_SOFT_KERNEL, visible=False)
|
| 275 |
mask_soft_iterations = gr.Number(label="Soft Erode Iterations", value=MASK_SOFT_ITERATIONS)
|
|
|
|
| 276 |
crop_top = gr.Slider(label="Top", minimum=0, maximum=511, value=0, step=1)
|
| 277 |
crop_bott = gr.Slider(label="Bottom", minimum=0, maximum=511, value=511, step=1)
|
| 278 |
crop_left = gr.Slider(label="Left", minimum=0, maximum=511, value=0, step=1)
|
| 279 |
crop_right = gr.Slider(label="Right", minimum=0, maximum=511, value=511, step=1)
|
|
|
|
| 280 |
erode_amount = gr.Slider(label="Mask Erode", minimum=0, maximum=1, value=MASK_ERODE_AMOUNT, step=0.05)
|
| 281 |
blur_amount = gr.Slider(label="Mask Blur", minimum=0, maximum=1, value=MASK_BLUR_AMOUNT, step=0.05)
|
| 282 |
enable_laplacian_blend = gr.Checkbox(label="Laplacian Blending", value=True)
|
|
|
|
| 283 |
source_image_input = gr.Image(label="Source face", type="filepath", interactive=True)
|
| 284 |
input_type = gr.Radio(["Image", "Video"], label="Target Type", value="Image")
|
| 285 |
image_input = gr.Image(label="Target Image", interactive=True, type="filepath")
|
|
|
|
| 298 |
for i in range(NUM_OF_SRC_SPECIFIC):
|
| 299 |
exec(f"src{i+1} = gr.Image(interactive=True, type='numpy', label='Source Face {i+1}')")
|
| 300 |
exec(f"trg{i+1} = gr.Image(interactive=True, type='numpy', label='Specific Face {i+1}')")
|
| 301 |
+
exec("src_specific_inputs = (" + ",".join([f"src{i+1}" for i in range(NUM_OF_SRC_SPECIFIC)] + [f\"trg{i+1}\" for i in range(NUM_OF_SRC_SPECIFIC)]) + ")")
|
|
|
|
|
|
|
| 302 |
|
| 303 |
swap_inputs = [
|
| 304 |
+
input_type, image_input, video_input, gr.Text(), source_image_input, output_directory, output_name,
|
| 305 |
+
keep_output_sequence, swap_option, age, gr.Number(value=0.6), face_enhancer_name,
|
| 306 |
+
enable_face_parser_mask, mask_include, mask_soft_kernel, mask_soft_iterations,
|
| 307 |
+
blur_amount, erode_amount, face_scale, enable_laplacian_blend,
|
| 308 |
+
crop_top, crop_bott, crop_left, crop_right, *src_specific_inputs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
]
|
| 310 |
|
| 311 |
swap_button.click(fn=process, inputs=swap_inputs, outputs=[info, preview_image, output_directory_button, output_video_button, preview_video], show_progress=True)
|
| 312 |
cancel_button.click(fn=stop_running, inputs=None, outputs=[info])
|
| 313 |
|
| 314 |
if __name__ == "__main__":
|
| 315 |
+
interface.queue().launch(server_name="0.0.0.0", share=False)
|