Upload 44 files
Browse files- uis/components/about.py +41 -0
- uis/components/age_modifier_options.py +64 -0
- uis/components/background_remover_options.py +165 -0
- uis/components/benchmark.py +51 -0
- uis/components/benchmark_options.py +54 -0
- uis/components/deep_swapper_options.py +64 -0
- uis/components/download.py +48 -0
- uis/components/execution.py +48 -0
- uis/components/execution_thread_count.py +29 -0
- uis/components/expression_restorer_options.py +80 -0
- uis/components/face_debugger_options.py +40 -0
- uis/components/face_detector.py +103 -0
- uis/components/face_editor_options.py +272 -0
- uis/components/face_enhancer_options.py +81 -0
- uis/components/face_landmarker.py +50 -0
- uis/components/face_masker.py +181 -0
- uis/components/face_selector.py +236 -0
- uis/components/face_swapper_options.py +84 -0
- uis/components/face_tracker.py +32 -0
- uis/components/frame_colorizer_options.py +81 -0
- uis/components/frame_enhancer_options.py +64 -0
- uis/components/instant_runner.py +110 -0
- uis/components/job_list.py +50 -0
- uis/components/job_list_options.py +35 -0
- uis/components/job_manager.py +194 -0
- uis/components/job_runner.py +142 -0
- uis/components/lip_syncer_options.py +64 -0
- uis/components/memory.py +27 -0
- uis/components/output.py +48 -0
- uis/components/output_options.py +184 -0
- uis/components/preview.py +306 -0
- uis/components/preview_options.py +62 -0
- uis/components/processors.py +49 -0
- uis/components/source.py +61 -0
- uis/components/target.py +65 -0
- uis/components/temp_frame.py +42 -0
- uis/components/terminal.py +80 -0
- uis/components/trim_frame.py +62 -0
- uis/components/ui_workflow.py +21 -0
- uis/components/voice_extractor.py +56 -0
- uis/components/webcam.py +116 -0
- uis/components/webcam_options.py +49 -0
- uis/components/workflow.py +27 -0
uis/components/about.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
from typing import Optional
|
| 3 |
+
|
| 4 |
+
import gradio
|
| 5 |
+
|
| 6 |
+
from facefusion import metadata, translator
|
| 7 |
+
|
| 8 |
+
METADATA_BUTTON : Optional[gradio.Button] = None
|
| 9 |
+
ACTION_BUTTON : Optional[gradio.Button] = None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def render() -> None:
|
| 13 |
+
global METADATA_BUTTON
|
| 14 |
+
global ACTION_BUTTON
|
| 15 |
+
|
| 16 |
+
action = random.choice(
|
| 17 |
+
[
|
| 18 |
+
{
|
| 19 |
+
'translator': translator.get('about.fund'),
|
| 20 |
+
'url': 'https://fund.facefusion.io'
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
'translator': translator.get('about.subscribe'),
|
| 24 |
+
'url': 'https://subscribe.facefusion.io'
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
'translator': translator.get('about.join'),
|
| 28 |
+
'url': 'https://join.facefusion.io'
|
| 29 |
+
}
|
| 30 |
+
])
|
| 31 |
+
|
| 32 |
+
METADATA_BUTTON = gradio.Button(
|
| 33 |
+
value = metadata.get('name') + ' ' + metadata.get('version'),
|
| 34 |
+
variant = 'primary',
|
| 35 |
+
link = metadata.get('url')
|
| 36 |
+
)
|
| 37 |
+
ACTION_BUTTON = gradio.Button(
|
| 38 |
+
value = action.get('translator'),
|
| 39 |
+
link = action.get('url'),
|
| 40 |
+
size = 'sm'
|
| 41 |
+
)
|
uis/components/age_modifier_options.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_float_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.age_modifier import choices as age_modifier_choices
|
| 9 |
+
from facefusion.processors.modules.age_modifier.types import AgeModifierModel
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
AGE_MODIFIER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
AGE_MODIFIER_DIRECTION_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global AGE_MODIFIER_MODEL_DROPDOWN
|
| 18 |
+
global AGE_MODIFIER_DIRECTION_SLIDER
|
| 19 |
+
|
| 20 |
+
has_age_modifier = 'age_modifier' in state_manager.get_item('processors')
|
| 21 |
+
AGE_MODIFIER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 22 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.age_modifier'),
|
| 23 |
+
choices = age_modifier_choices.age_modifier_models,
|
| 24 |
+
value = state_manager.get_item('age_modifier_model'),
|
| 25 |
+
visible = has_age_modifier
|
| 26 |
+
)
|
| 27 |
+
AGE_MODIFIER_DIRECTION_SLIDER = gradio.Slider(
|
| 28 |
+
label = translator.get('uis.direction_slider', 'facefusion.processors.modules.age_modifier'),
|
| 29 |
+
value = state_manager.get_item('age_modifier_direction'),
|
| 30 |
+
step = calculate_float_step(age_modifier_choices.age_modifier_direction_range),
|
| 31 |
+
minimum = age_modifier_choices.age_modifier_direction_range[0],
|
| 32 |
+
maximum = age_modifier_choices.age_modifier_direction_range[-1],
|
| 33 |
+
visible = has_age_modifier
|
| 34 |
+
)
|
| 35 |
+
register_ui_component('age_modifier_model_dropdown', AGE_MODIFIER_MODEL_DROPDOWN)
|
| 36 |
+
register_ui_component('age_modifier_direction_slider', AGE_MODIFIER_DIRECTION_SLIDER)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def listen() -> None:
|
| 40 |
+
AGE_MODIFIER_MODEL_DROPDOWN.change(update_age_modifier_model, inputs = AGE_MODIFIER_MODEL_DROPDOWN, outputs = AGE_MODIFIER_MODEL_DROPDOWN)
|
| 41 |
+
AGE_MODIFIER_DIRECTION_SLIDER.release(update_age_modifier_direction, inputs = AGE_MODIFIER_DIRECTION_SLIDER)
|
| 42 |
+
|
| 43 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 44 |
+
if processors_checkbox_group:
|
| 45 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ AGE_MODIFIER_MODEL_DROPDOWN, AGE_MODIFIER_DIRECTION_SLIDER ])
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
|
| 49 |
+
has_age_modifier = 'age_modifier' in processors
|
| 50 |
+
return gradio.Dropdown(visible = has_age_modifier), gradio.Slider(visible = has_age_modifier)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def update_age_modifier_model(age_modifier_model : AgeModifierModel) -> gradio.Dropdown:
|
| 54 |
+
age_modifier_module = load_processor_module('age_modifier')
|
| 55 |
+
age_modifier_module.clear_inference_pool()
|
| 56 |
+
state_manager.set_item('age_modifier_model', age_modifier_model)
|
| 57 |
+
|
| 58 |
+
if age_modifier_module.pre_check():
|
| 59 |
+
return gradio.Dropdown(value = state_manager.get_item('age_modifier_model'))
|
| 60 |
+
return gradio.Dropdown()
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_age_modifier_direction(age_modifier_direction : float) -> None:
|
| 64 |
+
state_manager.set_item('age_modifier_direction', int(age_modifier_direction))
|
uis/components/background_remover_options.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_int_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.background_remover import choices as background_remover_choices
|
| 9 |
+
from facefusion.processors.modules.background_remover.types import BackgroundRemoverModel
|
| 10 |
+
from facefusion.sanitizer import sanitize_int_range
|
| 11 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 12 |
+
|
| 13 |
+
BACKGROUND_REMOVER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 14 |
+
BACKGROUND_REMOVER_FILL_COLOR_WRAPPER : Optional[gradio.Group] = None
|
| 15 |
+
BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER : Optional[gradio.Number] = None
|
| 16 |
+
BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER : Optional[gradio.Number] = None
|
| 17 |
+
BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER : Optional[gradio.Number] = None
|
| 18 |
+
BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER : Optional[gradio.Number] = None
|
| 19 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER : Optional[gradio.Group] = None
|
| 20 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER : Optional[gradio.Number] = None
|
| 21 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER : Optional[gradio.Number] = None
|
| 22 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER : Optional[gradio.Number] = None
|
| 23 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER : Optional[gradio.Number] = None
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def render() -> None:
|
| 27 |
+
global BACKGROUND_REMOVER_MODEL_DROPDOWN
|
| 28 |
+
global BACKGROUND_REMOVER_FILL_COLOR_WRAPPER
|
| 29 |
+
global BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER
|
| 30 |
+
global BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER
|
| 31 |
+
global BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER
|
| 32 |
+
global BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER
|
| 33 |
+
global BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER
|
| 34 |
+
global BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER
|
| 35 |
+
global BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER
|
| 36 |
+
global BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER
|
| 37 |
+
global BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER
|
| 38 |
+
|
| 39 |
+
has_background_remover = 'background_remover' in state_manager.get_item('processors')
|
| 40 |
+
background_remover_fill_color = state_manager.get_item('background_remover_fill_color')
|
| 41 |
+
background_remover_despill_color = state_manager.get_item('background_remover_despill_color')
|
| 42 |
+
BACKGROUND_REMOVER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 43 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.background_remover'),
|
| 44 |
+
choices = background_remover_choices.background_remover_models,
|
| 45 |
+
value = state_manager.get_item('background_remover_model'),
|
| 46 |
+
visible = has_background_remover
|
| 47 |
+
)
|
| 48 |
+
with gradio.Group(visible = has_background_remover) as BACKGROUND_REMOVER_FILL_COLOR_WRAPPER:
|
| 49 |
+
with gradio.Row():
|
| 50 |
+
BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER = gradio.Number(
|
| 51 |
+
label = translator.get('uis.fill_color_red_number', 'facefusion.processors.modules.background_remover'),
|
| 52 |
+
value = background_remover_fill_color[0],
|
| 53 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 54 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 55 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 56 |
+
)
|
| 57 |
+
BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER = gradio.Number(
|
| 58 |
+
label = translator.get('uis.fill_color_green_number', 'facefusion.processors.modules.background_remover'),
|
| 59 |
+
value = background_remover_fill_color[1],
|
| 60 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 61 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 62 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 63 |
+
)
|
| 64 |
+
with gradio.Row():
|
| 65 |
+
BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER = gradio.Number(
|
| 66 |
+
label = translator.get('uis.fill_color_blue_number', 'facefusion.processors.modules.background_remover'),
|
| 67 |
+
value = background_remover_fill_color[2],
|
| 68 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 69 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 70 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 71 |
+
)
|
| 72 |
+
BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER = gradio.Number(
|
| 73 |
+
label = translator.get('uis.fill_color_alpha_number', 'facefusion.processors.modules.background_remover'),
|
| 74 |
+
value = background_remover_fill_color[3],
|
| 75 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 76 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 77 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 78 |
+
)
|
| 79 |
+
with gradio.Group(visible = has_background_remover) as BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER:
|
| 80 |
+
with gradio.Row():
|
| 81 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER = gradio.Number(
|
| 82 |
+
label = translator.get('uis.despill_color_red_number', 'facefusion.processors.modules.background_remover'),
|
| 83 |
+
value = background_remover_despill_color[0],
|
| 84 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 85 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 86 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 87 |
+
)
|
| 88 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER = gradio.Number(
|
| 89 |
+
label = translator.get('uis.despill_color_green_number', 'facefusion.processors.modules.background_remover'),
|
| 90 |
+
value = background_remover_despill_color[1],
|
| 91 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 92 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 93 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 94 |
+
)
|
| 95 |
+
with gradio.Row():
|
| 96 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER = gradio.Number(
|
| 97 |
+
label = translator.get('uis.despill_color_blue_number', 'facefusion.processors.modules.background_remover'),
|
| 98 |
+
value = background_remover_despill_color[2],
|
| 99 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 100 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 101 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 102 |
+
)
|
| 103 |
+
BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER = gradio.Number(
|
| 104 |
+
label = translator.get('uis.despill_color_alpha_number', 'facefusion.processors.modules.background_remover'),
|
| 105 |
+
value = background_remover_despill_color[3],
|
| 106 |
+
minimum = background_remover_choices.background_remover_color_range[0],
|
| 107 |
+
maximum = background_remover_choices.background_remover_color_range[-1],
|
| 108 |
+
step = calculate_int_step(background_remover_choices.background_remover_color_range)
|
| 109 |
+
)
|
| 110 |
+
register_ui_component('background_remover_model_dropdown', BACKGROUND_REMOVER_MODEL_DROPDOWN)
|
| 111 |
+
register_ui_component('background_remover_fill_color_red_number', BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER)
|
| 112 |
+
register_ui_component('background_remover_fill_color_green_number', BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER)
|
| 113 |
+
register_ui_component('background_remover_fill_color_blue_number', BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER)
|
| 114 |
+
register_ui_component('background_remover_fill_color_alpha_number', BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER)
|
| 115 |
+
register_ui_component('background_remover_despill_color_red_number', BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER)
|
| 116 |
+
register_ui_component('background_remover_despill_color_green_number', BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER)
|
| 117 |
+
register_ui_component('background_remover_despill_color_blue_number', BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER)
|
| 118 |
+
register_ui_component('background_remover_despill_color_alpha_number', BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER)
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def listen() -> None:
|
| 122 |
+
BACKGROUND_REMOVER_MODEL_DROPDOWN.change(update_background_remover_model, inputs = BACKGROUND_REMOVER_MODEL_DROPDOWN, outputs = BACKGROUND_REMOVER_MODEL_DROPDOWN)
|
| 123 |
+
background_remover_fill_color_inputs = [ BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER, BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER, BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER, BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER ]
|
| 124 |
+
background_remover_despill_color_inputs = [ BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER, BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER, BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER, BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER ]
|
| 125 |
+
|
| 126 |
+
for background_remover_fill_color_input in background_remover_fill_color_inputs:
|
| 127 |
+
background_remover_fill_color_input.change(update_background_remover_fill_color, inputs = background_remover_fill_color_inputs)
|
| 128 |
+
|
| 129 |
+
for background_remover_despill_color_input in background_remover_despill_color_inputs:
|
| 130 |
+
background_remover_despill_color_input.change(update_background_remover_despill_color, inputs = background_remover_despill_color_inputs)
|
| 131 |
+
|
| 132 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 133 |
+
if processors_checkbox_group:
|
| 134 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ BACKGROUND_REMOVER_MODEL_DROPDOWN, BACKGROUND_REMOVER_FILL_COLOR_WRAPPER, BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER ])
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Group, gradio.Group]:
|
| 138 |
+
has_background_remover = 'background_remover' in processors
|
| 139 |
+
return gradio.Dropdown(visible = has_background_remover), gradio.Group(visible = has_background_remover), gradio.Group(visible = has_background_remover)
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def update_background_remover_model(background_remover_model : BackgroundRemoverModel) -> gradio.Dropdown:
|
| 143 |
+
background_remover_module = load_processor_module('background_remover')
|
| 144 |
+
background_remover_module.clear_inference_pool()
|
| 145 |
+
state_manager.set_item('background_remover_model', background_remover_model)
|
| 146 |
+
|
| 147 |
+
if background_remover_module.pre_check():
|
| 148 |
+
return gradio.Dropdown(value = state_manager.get_item('background_remover_model'))
|
| 149 |
+
return gradio.Dropdown()
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def update_background_remover_fill_color(red : int, green : int, blue : int, alpha : int) -> None:
|
| 153 |
+
red = sanitize_int_range(red, background_remover_choices.background_remover_color_range)
|
| 154 |
+
green = sanitize_int_range(green, background_remover_choices.background_remover_color_range)
|
| 155 |
+
blue = sanitize_int_range(blue, background_remover_choices.background_remover_color_range)
|
| 156 |
+
alpha = sanitize_int_range(alpha, background_remover_choices.background_remover_color_range)
|
| 157 |
+
state_manager.set_item('background_remover_fill_color', (red, green, blue, alpha))
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def update_background_remover_despill_color(red : int, green : int, blue : int, alpha : int) -> None:
|
| 161 |
+
red = sanitize_int_range(red, background_remover_choices.background_remover_color_range)
|
| 162 |
+
green = sanitize_int_range(green, background_remover_choices.background_remover_color_range)
|
| 163 |
+
blue = sanitize_int_range(blue, background_remover_choices.background_remover_color_range)
|
| 164 |
+
alpha = sanitize_int_range(alpha, background_remover_choices.background_remover_color_range)
|
| 165 |
+
state_manager.set_item('background_remover_despill_color', (red, green, blue, alpha))
|
uis/components/benchmark.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any, Iterator, List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import benchmarker, state_manager, translator
|
| 6 |
+
|
| 7 |
+
BENCHMARK_BENCHMARKS_DATAFRAME : Optional[gradio.Dataframe] = None
|
| 8 |
+
BENCHMARK_START_BUTTON : Optional[gradio.Button] = None
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def render() -> None:
|
| 12 |
+
global BENCHMARK_BENCHMARKS_DATAFRAME
|
| 13 |
+
global BENCHMARK_START_BUTTON
|
| 14 |
+
|
| 15 |
+
BENCHMARK_BENCHMARKS_DATAFRAME = gradio.Dataframe(
|
| 16 |
+
headers =
|
| 17 |
+
[
|
| 18 |
+
'target_path',
|
| 19 |
+
'cycle_count',
|
| 20 |
+
'average_run',
|
| 21 |
+
'fastest_run',
|
| 22 |
+
'slowest_run',
|
| 23 |
+
'relative_fps'
|
| 24 |
+
],
|
| 25 |
+
datatype =
|
| 26 |
+
[
|
| 27 |
+
'str',
|
| 28 |
+
'number',
|
| 29 |
+
'number',
|
| 30 |
+
'number',
|
| 31 |
+
'number',
|
| 32 |
+
'number'
|
| 33 |
+
],
|
| 34 |
+
show_label = False
|
| 35 |
+
)
|
| 36 |
+
BENCHMARK_START_BUTTON = gradio.Button(
|
| 37 |
+
value = translator.get('uis.start_button'),
|
| 38 |
+
variant = 'primary',
|
| 39 |
+
size = 'sm'
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def listen() -> None:
|
| 44 |
+
BENCHMARK_START_BUTTON.click(start, outputs = BENCHMARK_BENCHMARKS_DATAFRAME)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def start() -> Iterator[List[Any]]:
|
| 48 |
+
state_manager.sync_state()
|
| 49 |
+
|
| 50 |
+
for benchmark in benchmarker.run():
|
| 51 |
+
yield [ list(benchmark_set.values()) for benchmark_set in benchmark ]
|
uis/components/benchmark_options.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_int_step
|
| 8 |
+
from facefusion.types import BenchmarkMode, BenchmarkResolution
|
| 9 |
+
|
| 10 |
+
BENCHMARK_MODE_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 11 |
+
BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 12 |
+
BENCHMARK_CYCLE_COUNT_SLIDER : Optional[gradio.Button] = None
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def render() -> None:
|
| 16 |
+
global BENCHMARK_MODE_DROPDOWN
|
| 17 |
+
global BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP
|
| 18 |
+
global BENCHMARK_CYCLE_COUNT_SLIDER
|
| 19 |
+
|
| 20 |
+
BENCHMARK_MODE_DROPDOWN = gradio.Dropdown(
|
| 21 |
+
label = translator.get('uis.benchmark_mode_dropdown'),
|
| 22 |
+
choices = facefusion.choices.benchmark_modes,
|
| 23 |
+
value = state_manager.get_item('benchmark_mode')
|
| 24 |
+
)
|
| 25 |
+
BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 26 |
+
label = translator.get('uis.benchmark_resolutions_checkbox_group'),
|
| 27 |
+
choices = facefusion.choices.benchmark_resolutions,
|
| 28 |
+
value = state_manager.get_item('benchmark_resolutions')
|
| 29 |
+
)
|
| 30 |
+
BENCHMARK_CYCLE_COUNT_SLIDER = gradio.Slider(
|
| 31 |
+
label = translator.get('uis.benchmark_cycle_count_slider'),
|
| 32 |
+
value = state_manager.get_item('benchmark_cycle_count'),
|
| 33 |
+
step = calculate_int_step(facefusion.choices.benchmark_cycle_count_range),
|
| 34 |
+
minimum = facefusion.choices.benchmark_cycle_count_range[0],
|
| 35 |
+
maximum = facefusion.choices.benchmark_cycle_count_range[-1]
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def listen() -> None:
|
| 40 |
+
BENCHMARK_MODE_DROPDOWN.change(update_benchmark_mode, inputs = BENCHMARK_MODE_DROPDOWN)
|
| 41 |
+
BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP.change(update_benchmark_resolutions, inputs = BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP)
|
| 42 |
+
BENCHMARK_CYCLE_COUNT_SLIDER.release(update_benchmark_cycle_count, inputs = BENCHMARK_CYCLE_COUNT_SLIDER)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def update_benchmark_mode(benchmark_mode : BenchmarkMode) -> None:
|
| 46 |
+
state_manager.set_item('benchmark_mode', benchmark_mode)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def update_benchmark_resolutions(benchmark_resolutions : List[BenchmarkResolution]) -> None:
|
| 50 |
+
state_manager.set_item('benchmark_resolutions', benchmark_resolutions)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def update_benchmark_cycle_count(benchmark_cycle_count : int) -> None:
|
| 54 |
+
state_manager.set_item('benchmark_cycle_count', benchmark_cycle_count)
|
uis/components/deep_swapper_options.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_int_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.deep_swapper import choices as deep_swapper_choices
|
| 9 |
+
from facefusion.processors.modules.deep_swapper.types import DeepSwapperModel
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
DEEP_SWAPPER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
DEEP_SWAPPER_MORPH_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global DEEP_SWAPPER_MODEL_DROPDOWN
|
| 18 |
+
global DEEP_SWAPPER_MORPH_SLIDER
|
| 19 |
+
|
| 20 |
+
has_deep_swapper = 'deep_swapper' in state_manager.get_item('processors')
|
| 21 |
+
DEEP_SWAPPER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 22 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.deep_swapper'),
|
| 23 |
+
choices = deep_swapper_choices.deep_swapper_models,
|
| 24 |
+
value = state_manager.get_item('deep_swapper_model'),
|
| 25 |
+
visible = has_deep_swapper
|
| 26 |
+
)
|
| 27 |
+
DEEP_SWAPPER_MORPH_SLIDER = gradio.Slider(
|
| 28 |
+
label = translator.get('uis.morph_slider', 'facefusion.processors.modules.deep_swapper'),
|
| 29 |
+
value = state_manager.get_item('deep_swapper_morph'),
|
| 30 |
+
step = calculate_int_step(deep_swapper_choices.deep_swapper_morph_range),
|
| 31 |
+
minimum = deep_swapper_choices.deep_swapper_morph_range[0],
|
| 32 |
+
maximum = deep_swapper_choices.deep_swapper_morph_range[-1],
|
| 33 |
+
visible = has_deep_swapper and load_processor_module('deep_swapper').get_inference_pool() and load_processor_module('deep_swapper').has_morph_input()
|
| 34 |
+
)
|
| 35 |
+
register_ui_component('deep_swapper_model_dropdown', DEEP_SWAPPER_MODEL_DROPDOWN)
|
| 36 |
+
register_ui_component('deep_swapper_morph_slider', DEEP_SWAPPER_MORPH_SLIDER)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def listen() -> None:
|
| 40 |
+
DEEP_SWAPPER_MODEL_DROPDOWN.change(update_deep_swapper_model, inputs = DEEP_SWAPPER_MODEL_DROPDOWN, outputs = [ DEEP_SWAPPER_MODEL_DROPDOWN, DEEP_SWAPPER_MORPH_SLIDER ])
|
| 41 |
+
DEEP_SWAPPER_MORPH_SLIDER.release(update_deep_swapper_morph, inputs = DEEP_SWAPPER_MORPH_SLIDER)
|
| 42 |
+
|
| 43 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 44 |
+
if processors_checkbox_group:
|
| 45 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ DEEP_SWAPPER_MODEL_DROPDOWN, DEEP_SWAPPER_MORPH_SLIDER ])
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
|
| 49 |
+
has_deep_swapper = 'deep_swapper' in processors
|
| 50 |
+
return gradio.Dropdown(visible = has_deep_swapper), gradio.Slider(visible = has_deep_swapper and load_processor_module('deep_swapper').get_inference_pool() and load_processor_module('deep_swapper').has_morph_input())
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def update_deep_swapper_model(deep_swapper_model : DeepSwapperModel) -> Tuple[gradio.Dropdown, gradio.Slider]:
|
| 54 |
+
deep_swapper_module = load_processor_module('deep_swapper')
|
| 55 |
+
deep_swapper_module.clear_inference_pool()
|
| 56 |
+
state_manager.set_item('deep_swapper_model', deep_swapper_model)
|
| 57 |
+
|
| 58 |
+
if deep_swapper_module.pre_check():
|
| 59 |
+
return gradio.Dropdown(value = state_manager.get_item('deep_swapper_model')), gradio.Slider(visible = deep_swapper_module.has_morph_input())
|
| 60 |
+
return gradio.Dropdown(), gradio.Slider()
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_deep_swapper_morph(deep_swapper_morph : int) -> None:
|
| 64 |
+
state_manager.set_item('deep_swapper_morph', deep_swapper_morph)
|
uis/components/download.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, state_manager, translator, voice_extractor
|
| 7 |
+
from facefusion.filesystem import get_file_name, resolve_file_paths
|
| 8 |
+
from facefusion.processors.core import get_processors_modules
|
| 9 |
+
from facefusion.types import DownloadProvider
|
| 10 |
+
|
| 11 |
+
DOWNLOAD_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def render() -> None:
|
| 15 |
+
global DOWNLOAD_PROVIDERS_CHECKBOX_GROUP
|
| 16 |
+
|
| 17 |
+
DOWNLOAD_PROVIDERS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 18 |
+
label = translator.get('uis.download_providers_checkbox_group'),
|
| 19 |
+
choices = facefusion.choices.download_providers,
|
| 20 |
+
value = state_manager.get_item('download_providers')
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def listen() -> None:
|
| 25 |
+
DOWNLOAD_PROVIDERS_CHECKBOX_GROUP.change(update_download_providers, inputs = DOWNLOAD_PROVIDERS_CHECKBOX_GROUP, outputs = DOWNLOAD_PROVIDERS_CHECKBOX_GROUP)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def update_download_providers(download_providers : List[DownloadProvider]) -> gradio.CheckboxGroup:
|
| 29 |
+
common_modules =\
|
| 30 |
+
[
|
| 31 |
+
content_analyser,
|
| 32 |
+
face_classifier,
|
| 33 |
+
face_detector,
|
| 34 |
+
face_landmarker,
|
| 35 |
+
face_recognizer,
|
| 36 |
+
face_masker,
|
| 37 |
+
voice_extractor
|
| 38 |
+
]
|
| 39 |
+
available_processors = [ get_file_name(file_path) for file_path in resolve_file_paths('facefusion/processors/modules') ]
|
| 40 |
+
processor_modules = get_processors_modules(available_processors)
|
| 41 |
+
|
| 42 |
+
for module in common_modules + processor_modules:
|
| 43 |
+
if hasattr(module, 'create_static_model_set'):
|
| 44 |
+
module.create_static_model_set.cache_clear()
|
| 45 |
+
|
| 46 |
+
download_providers = download_providers or facefusion.choices.download_providers
|
| 47 |
+
state_manager.set_item('download_providers', download_providers)
|
| 48 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('download_providers'))
|
uis/components/execution.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, state_manager, translator, voice_extractor
|
| 6 |
+
from facefusion.execution import get_available_execution_providers
|
| 7 |
+
from facefusion.filesystem import get_file_name, resolve_file_paths
|
| 8 |
+
from facefusion.processors.core import get_processors_modules
|
| 9 |
+
from facefusion.types import ExecutionProvider
|
| 10 |
+
|
| 11 |
+
EXECUTION_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def render() -> None:
|
| 15 |
+
global EXECUTION_PROVIDERS_CHECKBOX_GROUP
|
| 16 |
+
|
| 17 |
+
EXECUTION_PROVIDERS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 18 |
+
label = translator.get('uis.execution_providers_checkbox_group'),
|
| 19 |
+
choices = get_available_execution_providers(),
|
| 20 |
+
value = state_manager.get_item('execution_providers')
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def listen() -> None:
|
| 25 |
+
EXECUTION_PROVIDERS_CHECKBOX_GROUP.change(update_execution_providers, inputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP, outputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def update_execution_providers(execution_providers : List[ExecutionProvider]) -> gradio.CheckboxGroup:
|
| 29 |
+
common_modules =\
|
| 30 |
+
[
|
| 31 |
+
content_analyser,
|
| 32 |
+
face_classifier,
|
| 33 |
+
face_detector,
|
| 34 |
+
face_landmarker,
|
| 35 |
+
face_masker,
|
| 36 |
+
face_recognizer,
|
| 37 |
+
voice_extractor
|
| 38 |
+
]
|
| 39 |
+
available_processors = [ get_file_name(file_path) for file_path in resolve_file_paths('facefusion/processors/modules') ]
|
| 40 |
+
processor_modules = get_processors_modules(available_processors)
|
| 41 |
+
|
| 42 |
+
for module in common_modules + processor_modules:
|
| 43 |
+
if hasattr(module, 'clear_inference_pool'):
|
| 44 |
+
module.clear_inference_pool()
|
| 45 |
+
|
| 46 |
+
execution_providers = execution_providers or get_available_execution_providers()
|
| 47 |
+
state_manager.set_item('execution_providers', execution_providers)
|
| 48 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('execution_providers'))
|
uis/components/execution_thread_count.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_int_step
|
| 8 |
+
|
| 9 |
+
EXECUTION_THREAD_COUNT_SLIDER : Optional[gradio.Slider] = None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def render() -> None:
|
| 13 |
+
global EXECUTION_THREAD_COUNT_SLIDER
|
| 14 |
+
|
| 15 |
+
EXECUTION_THREAD_COUNT_SLIDER = gradio.Slider(
|
| 16 |
+
label = translator.get('uis.execution_thread_count_slider'),
|
| 17 |
+
value = state_manager.get_item('execution_thread_count'),
|
| 18 |
+
step = calculate_int_step(facefusion.choices.execution_thread_count_range),
|
| 19 |
+
minimum = facefusion.choices.execution_thread_count_range[0],
|
| 20 |
+
maximum = facefusion.choices.execution_thread_count_range[-1]
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def listen() -> None:
|
| 25 |
+
EXECUTION_THREAD_COUNT_SLIDER.release(update_execution_thread_count, inputs = EXECUTION_THREAD_COUNT_SLIDER)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def update_execution_thread_count(execution_thread_count : float) -> None:
|
| 29 |
+
state_manager.set_item('execution_thread_count', int(execution_thread_count))
|
uis/components/expression_restorer_options.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_float_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.expression_restorer import choices as expression_restorer_choices
|
| 9 |
+
from facefusion.processors.modules.expression_restorer.types import ExpressionRestorerArea, ExpressionRestorerModel
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
EXPRESSION_RESTORER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
EXPRESSION_RESTORER_FACTOR_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def render() -> None:
|
| 18 |
+
global EXPRESSION_RESTORER_MODEL_DROPDOWN
|
| 19 |
+
global EXPRESSION_RESTORER_FACTOR_SLIDER
|
| 20 |
+
global EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP
|
| 21 |
+
|
| 22 |
+
has_expression_restorer = 'expression_restorer' in state_manager.get_item('processors')
|
| 23 |
+
EXPRESSION_RESTORER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 24 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.expression_restorer'),
|
| 25 |
+
choices = expression_restorer_choices.expression_restorer_models,
|
| 26 |
+
value = state_manager.get_item('expression_restorer_model'),
|
| 27 |
+
visible = has_expression_restorer
|
| 28 |
+
)
|
| 29 |
+
EXPRESSION_RESTORER_FACTOR_SLIDER = gradio.Slider(
|
| 30 |
+
label = translator.get('uis.factor_slider', 'facefusion.processors.modules.expression_restorer'),
|
| 31 |
+
value = state_manager.get_item('expression_restorer_factor'),
|
| 32 |
+
step = calculate_float_step(expression_restorer_choices.expression_restorer_factor_range),
|
| 33 |
+
minimum = expression_restorer_choices.expression_restorer_factor_range[0],
|
| 34 |
+
maximum = expression_restorer_choices.expression_restorer_factor_range[-1],
|
| 35 |
+
visible = has_expression_restorer
|
| 36 |
+
)
|
| 37 |
+
EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 38 |
+
label = translator.get('uis.areas_checkbox_group', 'facefusion.processors.modules.expression_restorer'),
|
| 39 |
+
choices = expression_restorer_choices.expression_restorer_areas,
|
| 40 |
+
value = state_manager.get_item('expression_restorer_areas'),
|
| 41 |
+
visible = has_expression_restorer
|
| 42 |
+
)
|
| 43 |
+
register_ui_component('expression_restorer_model_dropdown', EXPRESSION_RESTORER_MODEL_DROPDOWN)
|
| 44 |
+
register_ui_component('expression_restorer_factor_slider', EXPRESSION_RESTORER_FACTOR_SLIDER)
|
| 45 |
+
register_ui_component('expression_restorer_areas_checkbox_group', EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def listen() -> None:
|
| 49 |
+
EXPRESSION_RESTORER_MODEL_DROPDOWN.change(update_expression_restorer_model, inputs = EXPRESSION_RESTORER_MODEL_DROPDOWN, outputs = EXPRESSION_RESTORER_MODEL_DROPDOWN)
|
| 50 |
+
EXPRESSION_RESTORER_FACTOR_SLIDER.release(update_expression_restorer_factor, inputs = EXPRESSION_RESTORER_FACTOR_SLIDER)
|
| 51 |
+
EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP.change(update_expression_restorer_areas, inputs = EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP, outputs = EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP)
|
| 52 |
+
|
| 53 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 54 |
+
if processors_checkbox_group:
|
| 55 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ EXPRESSION_RESTORER_MODEL_DROPDOWN, EXPRESSION_RESTORER_FACTOR_SLIDER, EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP ])
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.CheckboxGroup]:
|
| 59 |
+
has_expression_restorer = 'expression_restorer' in processors
|
| 60 |
+
return gradio.Dropdown(visible = has_expression_restorer), gradio.Slider(visible = has_expression_restorer), gradio.CheckboxGroup(visible = has_expression_restorer)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_expression_restorer_model(expression_restorer_model : ExpressionRestorerModel) -> gradio.Dropdown:
|
| 64 |
+
expression_restorer_module = load_processor_module('expression_restorer')
|
| 65 |
+
expression_restorer_module.clear_inference_pool()
|
| 66 |
+
state_manager.set_item('expression_restorer_model', expression_restorer_model)
|
| 67 |
+
|
| 68 |
+
if expression_restorer_module.pre_check():
|
| 69 |
+
return gradio.Dropdown(value = state_manager.get_item('expression_restorer_model'))
|
| 70 |
+
return gradio.Dropdown()
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def update_expression_restorer_factor(expression_restorer_factor : float) -> None:
|
| 74 |
+
state_manager.set_item('expression_restorer_factor', int(expression_restorer_factor))
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def update_expression_restorer_areas(expression_restorer_areas : List[ExpressionRestorerArea]) -> gradio.CheckboxGroup:
|
| 78 |
+
expression_restorer_areas = expression_restorer_areas or expression_restorer_choices.expression_restorer_areas
|
| 79 |
+
state_manager.set_item('expression_restorer_areas', expression_restorer_areas)
|
| 80 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('expression_restorer_areas'))
|
uis/components/face_debugger_options.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.processors.modules.face_debugger import choices as face_debugger_choices
|
| 7 |
+
from facefusion.processors.modules.face_debugger.types import FaceDebuggerItem
|
| 8 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 9 |
+
|
| 10 |
+
FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def render() -> None:
|
| 14 |
+
global FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP
|
| 15 |
+
|
| 16 |
+
has_face_debugger = 'face_debugger' in state_manager.get_item('processors')
|
| 17 |
+
FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 18 |
+
label = translator.get('uis.items_checkbox_group', 'facefusion.processors.modules.face_debugger'),
|
| 19 |
+
choices = face_debugger_choices.face_debugger_items,
|
| 20 |
+
value = state_manager.get_item('face_debugger_items'),
|
| 21 |
+
visible = has_face_debugger
|
| 22 |
+
)
|
| 23 |
+
register_ui_component('face_debugger_items_checkbox_group', FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def listen() -> None:
|
| 27 |
+
FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP.change(update_face_debugger_items, inputs = FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP)
|
| 28 |
+
|
| 29 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 30 |
+
if processors_checkbox_group:
|
| 31 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def remote_update(processors : List[str]) -> gradio.CheckboxGroup:
|
| 35 |
+
has_face_debugger = 'face_debugger' in processors
|
| 36 |
+
return gradio.CheckboxGroup(visible = has_face_debugger)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def update_face_debugger_items(face_debugger_items : List[FaceDebuggerItem]) -> None:
|
| 40 |
+
state_manager.set_item('face_debugger_items', face_debugger_items)
|
uis/components/face_detector.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional, Sequence, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import face_detector, state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_float_step, get_last
|
| 8 |
+
from facefusion.sanitizer import sanitize_int_range
|
| 9 |
+
from facefusion.types import Angle, FaceDetectorModel, Score
|
| 10 |
+
from facefusion.uis.core import register_ui_component
|
| 11 |
+
from facefusion.uis.types import ComponentOptions
|
| 12 |
+
|
| 13 |
+
FACE_DETECTOR_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 14 |
+
FACE_DETECTOR_SIZE_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 15 |
+
FACE_DETECTOR_MARGIN_SLIDER : Optional[gradio.Slider] = None
|
| 16 |
+
FACE_DETECTOR_ANGLES_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 17 |
+
FACE_DETECTOR_SCORE_SLIDER : Optional[gradio.Slider] = None
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def render() -> None:
|
| 21 |
+
global FACE_DETECTOR_MODEL_DROPDOWN
|
| 22 |
+
global FACE_DETECTOR_SIZE_DROPDOWN
|
| 23 |
+
global FACE_DETECTOR_MARGIN_SLIDER
|
| 24 |
+
global FACE_DETECTOR_ANGLES_CHECKBOX_GROUP
|
| 25 |
+
global FACE_DETECTOR_SCORE_SLIDER
|
| 26 |
+
|
| 27 |
+
face_detector_size_dropdown_options : ComponentOptions =\
|
| 28 |
+
{
|
| 29 |
+
'label': translator.get('uis.face_detector_size_dropdown'),
|
| 30 |
+
'value': state_manager.get_item('face_detector_size')
|
| 31 |
+
}
|
| 32 |
+
if state_manager.get_item('face_detector_size') in facefusion.choices.face_detector_set[state_manager.get_item('face_detector_model')]:
|
| 33 |
+
face_detector_size_dropdown_options['choices'] = facefusion.choices.face_detector_set[state_manager.get_item('face_detector_model')]
|
| 34 |
+
with gradio.Row():
|
| 35 |
+
FACE_DETECTOR_MODEL_DROPDOWN = gradio.Dropdown(
|
| 36 |
+
label = translator.get('uis.face_detector_model_dropdown'),
|
| 37 |
+
choices = facefusion.choices.face_detector_models,
|
| 38 |
+
value = state_manager.get_item('face_detector_model')
|
| 39 |
+
)
|
| 40 |
+
FACE_DETECTOR_SIZE_DROPDOWN = gradio.Dropdown(**face_detector_size_dropdown_options)
|
| 41 |
+
FACE_DETECTOR_MARGIN_SLIDER = gradio.Slider(
|
| 42 |
+
label = translator.get('uis.face_detector_margin_slider'),
|
| 43 |
+
value = state_manager.get_item('face_detector_margin')[0],
|
| 44 |
+
step = calculate_float_step(facefusion.choices.face_detector_margin_range),
|
| 45 |
+
minimum = facefusion.choices.face_detector_margin_range[0],
|
| 46 |
+
maximum = facefusion.choices.face_detector_margin_range[-1]
|
| 47 |
+
)
|
| 48 |
+
FACE_DETECTOR_ANGLES_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 49 |
+
label = translator.get('uis.face_detector_angles_checkbox_group'),
|
| 50 |
+
choices = facefusion.choices.face_detector_angles,
|
| 51 |
+
value = state_manager.get_item('face_detector_angles')
|
| 52 |
+
)
|
| 53 |
+
FACE_DETECTOR_SCORE_SLIDER = gradio.Slider(
|
| 54 |
+
label = translator.get('uis.face_detector_score_slider'),
|
| 55 |
+
value = state_manager.get_item('face_detector_score'),
|
| 56 |
+
step = calculate_float_step(facefusion.choices.face_detector_score_range),
|
| 57 |
+
minimum = facefusion.choices.face_detector_score_range[0],
|
| 58 |
+
maximum = facefusion.choices.face_detector_score_range[-1]
|
| 59 |
+
)
|
| 60 |
+
register_ui_component('face_detector_model_dropdown', FACE_DETECTOR_MODEL_DROPDOWN)
|
| 61 |
+
register_ui_component('face_detector_size_dropdown', FACE_DETECTOR_SIZE_DROPDOWN)
|
| 62 |
+
register_ui_component('face_detector_margin_slider', FACE_DETECTOR_MARGIN_SLIDER)
|
| 63 |
+
register_ui_component('face_detector_angles_checkbox_group', FACE_DETECTOR_ANGLES_CHECKBOX_GROUP)
|
| 64 |
+
register_ui_component('face_detector_score_slider', FACE_DETECTOR_SCORE_SLIDER)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def listen() -> None:
|
| 68 |
+
FACE_DETECTOR_MODEL_DROPDOWN.change(update_face_detector_model, inputs = FACE_DETECTOR_MODEL_DROPDOWN, outputs = [ FACE_DETECTOR_MODEL_DROPDOWN, FACE_DETECTOR_SIZE_DROPDOWN ])
|
| 69 |
+
FACE_DETECTOR_SIZE_DROPDOWN.change(update_face_detector_size, inputs = FACE_DETECTOR_SIZE_DROPDOWN)
|
| 70 |
+
FACE_DETECTOR_MARGIN_SLIDER.release(update_face_detector_margin, inputs=FACE_DETECTOR_MARGIN_SLIDER)
|
| 71 |
+
FACE_DETECTOR_ANGLES_CHECKBOX_GROUP.change(update_face_detector_angles, inputs = FACE_DETECTOR_ANGLES_CHECKBOX_GROUP, outputs = FACE_DETECTOR_ANGLES_CHECKBOX_GROUP)
|
| 72 |
+
FACE_DETECTOR_SCORE_SLIDER.release(update_face_detector_score, inputs = FACE_DETECTOR_SCORE_SLIDER)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def update_face_detector_model(face_detector_model : FaceDetectorModel) -> Tuple[gradio.Dropdown, gradio.Dropdown]:
|
| 76 |
+
face_detector.clear_inference_pool()
|
| 77 |
+
state_manager.set_item('face_detector_model', face_detector_model)
|
| 78 |
+
|
| 79 |
+
if face_detector.pre_check():
|
| 80 |
+
face_detector_size_choices = facefusion.choices.face_detector_set.get(state_manager.get_item('face_detector_model'))
|
| 81 |
+
state_manager.set_item('face_detector_size', get_last(face_detector_size_choices))
|
| 82 |
+
return gradio.Dropdown(value = state_manager.get_item('face_detector_model')), gradio.Dropdown(value = state_manager.get_item('face_detector_size'), choices = face_detector_size_choices)
|
| 83 |
+
return gradio.Dropdown(), gradio.Dropdown()
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def update_face_detector_size(face_detector_size : str) -> None:
|
| 87 |
+
state_manager.set_item('face_detector_size', face_detector_size)
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def update_face_detector_margin(face_detector_margin : int) -> None:
|
| 91 |
+
face_detector_margin = sanitize_int_range(face_detector_margin, facefusion.choices.face_detector_margin_range)
|
| 92 |
+
state_manager.set_item('face_detector_margin', (face_detector_margin, face_detector_margin, face_detector_margin, face_detector_margin))
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def update_face_detector_angles(face_detector_angles : Sequence[Angle]) -> gradio.CheckboxGroup:
|
| 96 |
+
face_detector_angles = face_detector_angles or facefusion.choices.face_detector_angles
|
| 97 |
+
|
| 98 |
+
state_manager.set_item('face_detector_angles', face_detector_angles)
|
| 99 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('face_detector_angles'))
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def update_face_detector_score(face_detector_score : Score) -> None:
|
| 103 |
+
state_manager.set_item('face_detector_score', face_detector_score)
|
uis/components/face_editor_options.py
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_float_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.face_editor import choices as face_editor_choices
|
| 9 |
+
from facefusion.processors.modules.face_editor.types import FaceEditorModel
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
FACE_EDITOR_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
FACE_EDITOR_EYEBROW_DIRECTION_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER : Optional[gradio.Slider] = None
|
| 15 |
+
FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER : Optional[gradio.Slider] = None
|
| 16 |
+
FACE_EDITOR_EYE_OPEN_RATIO_SLIDER : Optional[gradio.Slider] = None
|
| 17 |
+
FACE_EDITOR_LIP_OPEN_RATIO_SLIDER : Optional[gradio.Slider] = None
|
| 18 |
+
FACE_EDITOR_MOUTH_GRIM_SLIDER : Optional[gradio.Slider] = None
|
| 19 |
+
FACE_EDITOR_MOUTH_POUT_SLIDER : Optional[gradio.Slider] = None
|
| 20 |
+
FACE_EDITOR_MOUTH_PURSE_SLIDER : Optional[gradio.Slider] = None
|
| 21 |
+
FACE_EDITOR_MOUTH_SMILE_SLIDER : Optional[gradio.Slider] = None
|
| 22 |
+
FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER : Optional[gradio.Slider] = None
|
| 23 |
+
FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER : Optional[gradio.Slider] = None
|
| 24 |
+
FACE_EDITOR_HEAD_PITCH_SLIDER : Optional[gradio.Slider] = None
|
| 25 |
+
FACE_EDITOR_HEAD_YAW_SLIDER : Optional[gradio.Slider] = None
|
| 26 |
+
FACE_EDITOR_HEAD_ROLL_SLIDER : Optional[gradio.Slider] = None
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def render() -> None:
|
| 30 |
+
global FACE_EDITOR_MODEL_DROPDOWN
|
| 31 |
+
global FACE_EDITOR_EYEBROW_DIRECTION_SLIDER
|
| 32 |
+
global FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER
|
| 33 |
+
global FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER
|
| 34 |
+
global FACE_EDITOR_EYE_OPEN_RATIO_SLIDER
|
| 35 |
+
global FACE_EDITOR_LIP_OPEN_RATIO_SLIDER
|
| 36 |
+
global FACE_EDITOR_MOUTH_GRIM_SLIDER
|
| 37 |
+
global FACE_EDITOR_MOUTH_POUT_SLIDER
|
| 38 |
+
global FACE_EDITOR_MOUTH_PURSE_SLIDER
|
| 39 |
+
global FACE_EDITOR_MOUTH_SMILE_SLIDER
|
| 40 |
+
global FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER
|
| 41 |
+
global FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER
|
| 42 |
+
global FACE_EDITOR_HEAD_PITCH_SLIDER
|
| 43 |
+
global FACE_EDITOR_HEAD_YAW_SLIDER
|
| 44 |
+
global FACE_EDITOR_HEAD_ROLL_SLIDER
|
| 45 |
+
|
| 46 |
+
has_face_editor = 'face_editor' in state_manager.get_item('processors')
|
| 47 |
+
FACE_EDITOR_MODEL_DROPDOWN = gradio.Dropdown(
|
| 48 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.face_editor'),
|
| 49 |
+
choices = face_editor_choices.face_editor_models,
|
| 50 |
+
value = state_manager.get_item('face_editor_model'),
|
| 51 |
+
visible = has_face_editor
|
| 52 |
+
)
|
| 53 |
+
FACE_EDITOR_EYEBROW_DIRECTION_SLIDER = gradio.Slider(
|
| 54 |
+
label = translator.get('uis.eyebrow_direction_slider', 'facefusion.processors.modules.face_editor'),
|
| 55 |
+
value = state_manager.get_item('face_editor_eyebrow_direction'),
|
| 56 |
+
step = calculate_float_step(face_editor_choices.face_editor_eyebrow_direction_range),
|
| 57 |
+
minimum = face_editor_choices.face_editor_eyebrow_direction_range[0],
|
| 58 |
+
maximum = face_editor_choices.face_editor_eyebrow_direction_range[-1],
|
| 59 |
+
visible = has_face_editor
|
| 60 |
+
)
|
| 61 |
+
FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER = gradio.Slider(
|
| 62 |
+
label = translator.get('uis.eye_gaze_horizontal_slider', 'facefusion.processors.modules.face_editor'),
|
| 63 |
+
value = state_manager.get_item('face_editor_eye_gaze_horizontal'),
|
| 64 |
+
step = calculate_float_step(face_editor_choices.face_editor_eye_gaze_horizontal_range),
|
| 65 |
+
minimum = face_editor_choices.face_editor_eye_gaze_horizontal_range[0],
|
| 66 |
+
maximum = face_editor_choices.face_editor_eye_gaze_horizontal_range[-1],
|
| 67 |
+
visible = has_face_editor
|
| 68 |
+
)
|
| 69 |
+
FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER = gradio.Slider(
|
| 70 |
+
label = translator.get('uis.eye_gaze_vertical_slider', 'facefusion.processors.modules.face_editor'),
|
| 71 |
+
value = state_manager.get_item('face_editor_eye_gaze_vertical'),
|
| 72 |
+
step = calculate_float_step(face_editor_choices.face_editor_eye_gaze_vertical_range),
|
| 73 |
+
minimum = face_editor_choices.face_editor_eye_gaze_vertical_range[0],
|
| 74 |
+
maximum = face_editor_choices.face_editor_eye_gaze_vertical_range[-1],
|
| 75 |
+
visible = has_face_editor
|
| 76 |
+
)
|
| 77 |
+
FACE_EDITOR_EYE_OPEN_RATIO_SLIDER = gradio.Slider(
|
| 78 |
+
label = translator.get('uis.eye_open_ratio_slider', 'facefusion.processors.modules.face_editor'),
|
| 79 |
+
value = state_manager.get_item('face_editor_eye_open_ratio'),
|
| 80 |
+
step = calculate_float_step(face_editor_choices.face_editor_eye_open_ratio_range),
|
| 81 |
+
minimum = face_editor_choices.face_editor_eye_open_ratio_range[0],
|
| 82 |
+
maximum = face_editor_choices.face_editor_eye_open_ratio_range[-1],
|
| 83 |
+
visible = has_face_editor
|
| 84 |
+
)
|
| 85 |
+
FACE_EDITOR_LIP_OPEN_RATIO_SLIDER = gradio.Slider(
|
| 86 |
+
label = translator.get('uis.lip_open_ratio_slider', 'facefusion.processors.modules.face_editor'),
|
| 87 |
+
value = state_manager.get_item('face_editor_lip_open_ratio'),
|
| 88 |
+
step = calculate_float_step(face_editor_choices.face_editor_lip_open_ratio_range),
|
| 89 |
+
minimum = face_editor_choices.face_editor_lip_open_ratio_range[0],
|
| 90 |
+
maximum = face_editor_choices.face_editor_lip_open_ratio_range[-1],
|
| 91 |
+
visible = has_face_editor
|
| 92 |
+
)
|
| 93 |
+
FACE_EDITOR_MOUTH_GRIM_SLIDER = gradio.Slider(
|
| 94 |
+
label = translator.get('uis.mouth_grim_slider', 'facefusion.processors.modules.face_editor'),
|
| 95 |
+
value = state_manager.get_item('face_editor_mouth_grim'),
|
| 96 |
+
step = calculate_float_step(face_editor_choices.face_editor_mouth_grim_range),
|
| 97 |
+
minimum = face_editor_choices.face_editor_mouth_grim_range[0],
|
| 98 |
+
maximum = face_editor_choices.face_editor_mouth_grim_range[-1],
|
| 99 |
+
visible = has_face_editor
|
| 100 |
+
)
|
| 101 |
+
FACE_EDITOR_MOUTH_POUT_SLIDER = gradio.Slider(
|
| 102 |
+
label = translator.get('uis.mouth_pout_slider', 'facefusion.processors.modules.face_editor'),
|
| 103 |
+
value = state_manager.get_item('face_editor_mouth_pout'),
|
| 104 |
+
step = calculate_float_step(face_editor_choices.face_editor_mouth_pout_range),
|
| 105 |
+
minimum = face_editor_choices.face_editor_mouth_pout_range[0],
|
| 106 |
+
maximum = face_editor_choices.face_editor_mouth_pout_range[-1],
|
| 107 |
+
visible = has_face_editor
|
| 108 |
+
)
|
| 109 |
+
FACE_EDITOR_MOUTH_PURSE_SLIDER = gradio.Slider(
|
| 110 |
+
label = translator.get('uis.mouth_purse_slider', 'facefusion.processors.modules.face_editor'),
|
| 111 |
+
value = state_manager.get_item('face_editor_mouth_purse'),
|
| 112 |
+
step = calculate_float_step(face_editor_choices.face_editor_mouth_purse_range),
|
| 113 |
+
minimum = face_editor_choices.face_editor_mouth_purse_range[0],
|
| 114 |
+
maximum = face_editor_choices.face_editor_mouth_purse_range[-1],
|
| 115 |
+
visible = has_face_editor
|
| 116 |
+
)
|
| 117 |
+
FACE_EDITOR_MOUTH_SMILE_SLIDER = gradio.Slider(
|
| 118 |
+
label = translator.get('uis.mouth_smile_slider', 'facefusion.processors.modules.face_editor'),
|
| 119 |
+
value = state_manager.get_item('face_editor_mouth_smile'),
|
| 120 |
+
step = calculate_float_step(face_editor_choices.face_editor_mouth_smile_range),
|
| 121 |
+
minimum = face_editor_choices.face_editor_mouth_smile_range[0],
|
| 122 |
+
maximum = face_editor_choices.face_editor_mouth_smile_range[-1],
|
| 123 |
+
visible = has_face_editor
|
| 124 |
+
)
|
| 125 |
+
FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER = gradio.Slider(
|
| 126 |
+
label = translator.get('uis.mouth_position_horizontal_slider', 'facefusion.processors.modules.face_editor'),
|
| 127 |
+
value = state_manager.get_item('face_editor_mouth_position_horizontal'),
|
| 128 |
+
step = calculate_float_step(face_editor_choices.face_editor_mouth_position_horizontal_range),
|
| 129 |
+
minimum = face_editor_choices.face_editor_mouth_position_horizontal_range[0],
|
| 130 |
+
maximum = face_editor_choices.face_editor_mouth_position_horizontal_range[-1],
|
| 131 |
+
visible = has_face_editor
|
| 132 |
+
)
|
| 133 |
+
FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER = gradio.Slider(
|
| 134 |
+
label = translator.get('uis.mouth_position_vertical_slider', 'facefusion.processors.modules.face_editor'),
|
| 135 |
+
value = state_manager.get_item('face_editor_mouth_position_vertical'),
|
| 136 |
+
step = calculate_float_step(face_editor_choices.face_editor_mouth_position_vertical_range),
|
| 137 |
+
minimum = face_editor_choices.face_editor_mouth_position_vertical_range[0],
|
| 138 |
+
maximum = face_editor_choices.face_editor_mouth_position_vertical_range[-1],
|
| 139 |
+
visible = has_face_editor
|
| 140 |
+
)
|
| 141 |
+
FACE_EDITOR_HEAD_PITCH_SLIDER = gradio.Slider(
|
| 142 |
+
label = translator.get('uis.head_pitch_slider', 'facefusion.processors.modules.face_editor'),
|
| 143 |
+
value = state_manager.get_item('face_editor_head_pitch'),
|
| 144 |
+
step = calculate_float_step(face_editor_choices.face_editor_head_pitch_range),
|
| 145 |
+
minimum = face_editor_choices.face_editor_head_pitch_range[0],
|
| 146 |
+
maximum = face_editor_choices.face_editor_head_pitch_range[-1],
|
| 147 |
+
visible = has_face_editor
|
| 148 |
+
)
|
| 149 |
+
FACE_EDITOR_HEAD_YAW_SLIDER = gradio.Slider(
|
| 150 |
+
label = translator.get('uis.head_yaw_slider', 'facefusion.processors.modules.face_editor'),
|
| 151 |
+
value = state_manager.get_item('face_editor_head_yaw'),
|
| 152 |
+
step = calculate_float_step(face_editor_choices.face_editor_head_yaw_range),
|
| 153 |
+
minimum = face_editor_choices.face_editor_head_yaw_range[0],
|
| 154 |
+
maximum = face_editor_choices.face_editor_head_yaw_range[-1],
|
| 155 |
+
visible = has_face_editor
|
| 156 |
+
)
|
| 157 |
+
FACE_EDITOR_HEAD_ROLL_SLIDER = gradio.Slider(
|
| 158 |
+
label = translator.get('uis.head_roll_slider', 'facefusion.processors.modules.face_editor'),
|
| 159 |
+
value = state_manager.get_item('face_editor_head_roll'),
|
| 160 |
+
step = calculate_float_step(face_editor_choices.face_editor_head_roll_range),
|
| 161 |
+
minimum = face_editor_choices.face_editor_head_roll_range[0],
|
| 162 |
+
maximum = face_editor_choices.face_editor_head_roll_range[-1],
|
| 163 |
+
visible = has_face_editor
|
| 164 |
+
)
|
| 165 |
+
register_ui_component('face_editor_model_dropdown', FACE_EDITOR_MODEL_DROPDOWN)
|
| 166 |
+
register_ui_component('face_editor_eyebrow_direction_slider', FACE_EDITOR_EYEBROW_DIRECTION_SLIDER)
|
| 167 |
+
register_ui_component('face_editor_eye_gaze_horizontal_slider', FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER)
|
| 168 |
+
register_ui_component('face_editor_eye_gaze_vertical_slider', FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER)
|
| 169 |
+
register_ui_component('face_editor_eye_open_ratio_slider', FACE_EDITOR_EYE_OPEN_RATIO_SLIDER)
|
| 170 |
+
register_ui_component('face_editor_lip_open_ratio_slider', FACE_EDITOR_LIP_OPEN_RATIO_SLIDER)
|
| 171 |
+
register_ui_component('face_editor_mouth_grim_slider', FACE_EDITOR_MOUTH_GRIM_SLIDER)
|
| 172 |
+
register_ui_component('face_editor_mouth_pout_slider', FACE_EDITOR_MOUTH_POUT_SLIDER)
|
| 173 |
+
register_ui_component('face_editor_mouth_purse_slider', FACE_EDITOR_MOUTH_PURSE_SLIDER)
|
| 174 |
+
register_ui_component('face_editor_mouth_smile_slider', FACE_EDITOR_MOUTH_SMILE_SLIDER)
|
| 175 |
+
register_ui_component('face_editor_mouth_position_horizontal_slider', FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER)
|
| 176 |
+
register_ui_component('face_editor_mouth_position_vertical_slider', FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER)
|
| 177 |
+
register_ui_component('face_editor_head_pitch_slider', FACE_EDITOR_HEAD_PITCH_SLIDER)
|
| 178 |
+
register_ui_component('face_editor_head_yaw_slider', FACE_EDITOR_HEAD_YAW_SLIDER)
|
| 179 |
+
register_ui_component('face_editor_head_roll_slider', FACE_EDITOR_HEAD_ROLL_SLIDER)
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
def listen() -> None:
|
| 183 |
+
FACE_EDITOR_MODEL_DROPDOWN.change(update_face_editor_model, inputs = FACE_EDITOR_MODEL_DROPDOWN, outputs = FACE_EDITOR_MODEL_DROPDOWN)
|
| 184 |
+
FACE_EDITOR_EYEBROW_DIRECTION_SLIDER.release(update_face_editor_eyebrow_direction, inputs = FACE_EDITOR_EYEBROW_DIRECTION_SLIDER)
|
| 185 |
+
FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER.release(update_face_editor_eye_gaze_horizontal, inputs = FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER)
|
| 186 |
+
FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER.release(update_face_editor_eye_gaze_vertical, inputs = FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER)
|
| 187 |
+
FACE_EDITOR_EYE_OPEN_RATIO_SLIDER.release(update_face_editor_eye_open_ratio, inputs = FACE_EDITOR_EYE_OPEN_RATIO_SLIDER)
|
| 188 |
+
FACE_EDITOR_LIP_OPEN_RATIO_SLIDER.release(update_face_editor_lip_open_ratio, inputs = FACE_EDITOR_LIP_OPEN_RATIO_SLIDER)
|
| 189 |
+
FACE_EDITOR_MOUTH_GRIM_SLIDER.release(update_face_editor_mouth_grim, inputs = FACE_EDITOR_MOUTH_GRIM_SLIDER)
|
| 190 |
+
FACE_EDITOR_MOUTH_POUT_SLIDER.release(update_face_editor_mouth_pout, inputs = FACE_EDITOR_MOUTH_POUT_SLIDER)
|
| 191 |
+
FACE_EDITOR_MOUTH_PURSE_SLIDER.release(update_face_editor_mouth_purse, inputs = FACE_EDITOR_MOUTH_PURSE_SLIDER)
|
| 192 |
+
FACE_EDITOR_MOUTH_SMILE_SLIDER.release(update_face_editor_mouth_smile, inputs = FACE_EDITOR_MOUTH_SMILE_SLIDER)
|
| 193 |
+
FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER.release(update_face_editor_mouth_position_horizontal, inputs = FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER)
|
| 194 |
+
FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER.release(update_face_editor_mouth_position_vertical, inputs = FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER)
|
| 195 |
+
FACE_EDITOR_HEAD_PITCH_SLIDER.release(update_face_editor_head_pitch, inputs = FACE_EDITOR_HEAD_PITCH_SLIDER)
|
| 196 |
+
FACE_EDITOR_HEAD_YAW_SLIDER.release(update_face_editor_head_yaw, inputs = FACE_EDITOR_HEAD_YAW_SLIDER)
|
| 197 |
+
FACE_EDITOR_HEAD_ROLL_SLIDER.release(update_face_editor_head_roll, inputs = FACE_EDITOR_HEAD_ROLL_SLIDER)
|
| 198 |
+
|
| 199 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 200 |
+
if processors_checkbox_group:
|
| 201 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FACE_EDITOR_MODEL_DROPDOWN, FACE_EDITOR_EYEBROW_DIRECTION_SLIDER, FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER, FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER, FACE_EDITOR_EYE_OPEN_RATIO_SLIDER, FACE_EDITOR_LIP_OPEN_RATIO_SLIDER, FACE_EDITOR_MOUTH_GRIM_SLIDER, FACE_EDITOR_MOUTH_POUT_SLIDER, FACE_EDITOR_MOUTH_PURSE_SLIDER, FACE_EDITOR_MOUTH_SMILE_SLIDER, FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER, FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER, FACE_EDITOR_HEAD_PITCH_SLIDER, FACE_EDITOR_HEAD_YAW_SLIDER, FACE_EDITOR_HEAD_ROLL_SLIDER ])
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider]:
|
| 205 |
+
has_face_editor = 'face_editor' in processors
|
| 206 |
+
return gradio.Dropdown(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor)
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
def update_face_editor_model(face_editor_model : FaceEditorModel) -> gradio.Dropdown:
|
| 210 |
+
face_editor_module = load_processor_module('face_editor')
|
| 211 |
+
face_editor_module.clear_inference_pool()
|
| 212 |
+
state_manager.set_item('face_editor_model', face_editor_model)
|
| 213 |
+
|
| 214 |
+
if face_editor_module.pre_check():
|
| 215 |
+
return gradio.Dropdown(value = state_manager.get_item('face_editor_model'))
|
| 216 |
+
return gradio.Dropdown()
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
def update_face_editor_eyebrow_direction(face_editor_eyebrow_direction : float) -> None:
|
| 220 |
+
state_manager.set_item('face_editor_eyebrow_direction', face_editor_eyebrow_direction)
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
def update_face_editor_eye_gaze_horizontal(face_editor_eye_gaze_horizontal : float) -> None:
|
| 224 |
+
state_manager.set_item('face_editor_eye_gaze_horizontal', face_editor_eye_gaze_horizontal)
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
def update_face_editor_eye_gaze_vertical(face_editor_eye_gaze_vertical : float) -> None:
|
| 228 |
+
state_manager.set_item('face_editor_eye_gaze_vertical', face_editor_eye_gaze_vertical)
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
def update_face_editor_eye_open_ratio(face_editor_eye_open_ratio : float) -> None:
|
| 232 |
+
state_manager.set_item('face_editor_eye_open_ratio', face_editor_eye_open_ratio)
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
def update_face_editor_lip_open_ratio(face_editor_lip_open_ratio : float) -> None:
|
| 236 |
+
state_manager.set_item('face_editor_lip_open_ratio', face_editor_lip_open_ratio)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
def update_face_editor_mouth_grim(face_editor_mouth_grim : float) -> None:
|
| 240 |
+
state_manager.set_item('face_editor_mouth_grim', face_editor_mouth_grim)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
def update_face_editor_mouth_pout(face_editor_mouth_pout : float) -> None:
|
| 244 |
+
state_manager.set_item('face_editor_mouth_pout', face_editor_mouth_pout)
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
def update_face_editor_mouth_purse(face_editor_mouth_purse : float) -> None:
|
| 248 |
+
state_manager.set_item('face_editor_mouth_purse', face_editor_mouth_purse)
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
def update_face_editor_mouth_smile(face_editor_mouth_smile : float) -> None:
|
| 252 |
+
state_manager.set_item('face_editor_mouth_smile', face_editor_mouth_smile)
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
def update_face_editor_mouth_position_horizontal(face_editor_mouth_position_horizontal : float) -> None:
|
| 256 |
+
state_manager.set_item('face_editor_mouth_position_horizontal', face_editor_mouth_position_horizontal)
|
| 257 |
+
|
| 258 |
+
|
| 259 |
+
def update_face_editor_mouth_position_vertical(face_editor_mouth_position_vertical : float) -> None:
|
| 260 |
+
state_manager.set_item('face_editor_mouth_position_vertical', face_editor_mouth_position_vertical)
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
def update_face_editor_head_pitch(face_editor_head_pitch : float) -> None:
|
| 264 |
+
state_manager.set_item('face_editor_head_pitch', face_editor_head_pitch)
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
def update_face_editor_head_yaw(face_editor_head_yaw : float) -> None:
|
| 268 |
+
state_manager.set_item('face_editor_head_yaw', face_editor_head_yaw)
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
def update_face_editor_head_roll(face_editor_head_roll : float) -> None:
|
| 272 |
+
state_manager.set_item('face_editor_head_roll', face_editor_head_roll)
|
uis/components/face_enhancer_options.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_float_step, calculate_int_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.face_enhancer import choices as face_enhancer_choices
|
| 9 |
+
from facefusion.processors.modules.face_enhancer.types import FaceEnhancerModel, FaceEnhancerWeight
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
FACE_ENHANCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
FACE_ENHANCER_BLEND_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
FACE_ENHANCER_WEIGHT_SLIDER : Optional[gradio.Slider] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def render() -> None:
|
| 18 |
+
global FACE_ENHANCER_MODEL_DROPDOWN
|
| 19 |
+
global FACE_ENHANCER_BLEND_SLIDER
|
| 20 |
+
global FACE_ENHANCER_WEIGHT_SLIDER
|
| 21 |
+
|
| 22 |
+
has_face_enhancer = 'face_enhancer' in state_manager.get_item('processors')
|
| 23 |
+
FACE_ENHANCER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 24 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.face_enhancer'),
|
| 25 |
+
choices = face_enhancer_choices.face_enhancer_models,
|
| 26 |
+
value = state_manager.get_item('face_enhancer_model'),
|
| 27 |
+
visible = has_face_enhancer
|
| 28 |
+
)
|
| 29 |
+
FACE_ENHANCER_BLEND_SLIDER = gradio.Slider(
|
| 30 |
+
label = translator.get('uis.blend_slider', 'facefusion.processors.modules.face_enhancer'),
|
| 31 |
+
value = state_manager.get_item('face_enhancer_blend'),
|
| 32 |
+
step = calculate_int_step(face_enhancer_choices.face_enhancer_blend_range),
|
| 33 |
+
minimum = face_enhancer_choices.face_enhancer_blend_range[0],
|
| 34 |
+
maximum = face_enhancer_choices.face_enhancer_blend_range[-1],
|
| 35 |
+
visible = has_face_enhancer
|
| 36 |
+
)
|
| 37 |
+
FACE_ENHANCER_WEIGHT_SLIDER = gradio.Slider(
|
| 38 |
+
label = translator.get('uis.weight_slider', 'facefusion.processors.modules.face_enhancer'),
|
| 39 |
+
value = state_manager.get_item('face_enhancer_weight'),
|
| 40 |
+
step = calculate_float_step(face_enhancer_choices.face_enhancer_weight_range),
|
| 41 |
+
minimum = face_enhancer_choices.face_enhancer_weight_range[0],
|
| 42 |
+
maximum = face_enhancer_choices.face_enhancer_weight_range[-1],
|
| 43 |
+
visible = has_face_enhancer and load_processor_module('face_enhancer').get_inference_pool() and load_processor_module('face_enhancer').has_weight_input()
|
| 44 |
+
)
|
| 45 |
+
register_ui_component('face_enhancer_model_dropdown', FACE_ENHANCER_MODEL_DROPDOWN)
|
| 46 |
+
register_ui_component('face_enhancer_blend_slider', FACE_ENHANCER_BLEND_SLIDER)
|
| 47 |
+
register_ui_component('face_enhancer_weight_slider', FACE_ENHANCER_WEIGHT_SLIDER)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def listen() -> None:
|
| 51 |
+
FACE_ENHANCER_MODEL_DROPDOWN.change(update_face_enhancer_model, inputs = FACE_ENHANCER_MODEL_DROPDOWN, outputs = [ FACE_ENHANCER_MODEL_DROPDOWN, FACE_ENHANCER_WEIGHT_SLIDER ])
|
| 52 |
+
FACE_ENHANCER_BLEND_SLIDER.release(update_face_enhancer_blend, inputs = FACE_ENHANCER_BLEND_SLIDER)
|
| 53 |
+
FACE_ENHANCER_WEIGHT_SLIDER.release(update_face_enhancer_weight, inputs = FACE_ENHANCER_WEIGHT_SLIDER)
|
| 54 |
+
|
| 55 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 56 |
+
if processors_checkbox_group:
|
| 57 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FACE_ENHANCER_MODEL_DROPDOWN, FACE_ENHANCER_BLEND_SLIDER, FACE_ENHANCER_WEIGHT_SLIDER ])
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.Slider]:
|
| 61 |
+
has_face_enhancer = 'face_enhancer' in processors
|
| 62 |
+
return gradio.Dropdown(visible = has_face_enhancer), gradio.Slider(visible = has_face_enhancer), gradio.Slider(visible = has_face_enhancer and load_processor_module('face_enhancer').get_inference_pool() and load_processor_module('face_enhancer').has_weight_input())
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def update_face_enhancer_model(face_enhancer_model : FaceEnhancerModel) -> Tuple[gradio.Dropdown, gradio.Slider]:
|
| 66 |
+
face_enhancer_module = load_processor_module('face_enhancer')
|
| 67 |
+
face_enhancer_module.clear_inference_pool()
|
| 68 |
+
state_manager.set_item('face_enhancer_model', face_enhancer_model)
|
| 69 |
+
|
| 70 |
+
if face_enhancer_module.pre_check():
|
| 71 |
+
return gradio.Dropdown(value = state_manager.get_item('face_enhancer_model')), gradio.Slider(visible = face_enhancer_module.has_weight_input())
|
| 72 |
+
return gradio.Dropdown(), gradio.Slider()
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def update_face_enhancer_blend(face_enhancer_blend : float) -> None:
|
| 76 |
+
state_manager.set_item('face_enhancer_blend', int(face_enhancer_blend))
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def update_face_enhancer_weight(face_enhancer_weight : FaceEnhancerWeight) -> None:
|
| 80 |
+
state_manager.set_item('face_enhancer_weight', face_enhancer_weight)
|
| 81 |
+
|
uis/components/face_landmarker.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import face_landmarker, state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_float_step
|
| 8 |
+
from facefusion.types import FaceLandmarkerModel, Score
|
| 9 |
+
from facefusion.uis.core import register_ui_component
|
| 10 |
+
|
| 11 |
+
FACE_LANDMARKER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 12 |
+
FACE_LANDMARKER_SCORE_SLIDER : Optional[gradio.Slider] = None
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def render() -> None:
|
| 16 |
+
global FACE_LANDMARKER_MODEL_DROPDOWN
|
| 17 |
+
global FACE_LANDMARKER_SCORE_SLIDER
|
| 18 |
+
|
| 19 |
+
FACE_LANDMARKER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 20 |
+
label = translator.get('uis.face_landmarker_model_dropdown'),
|
| 21 |
+
choices = facefusion.choices.face_landmarker_models,
|
| 22 |
+
value = state_manager.get_item('face_landmarker_model')
|
| 23 |
+
)
|
| 24 |
+
FACE_LANDMARKER_SCORE_SLIDER = gradio.Slider(
|
| 25 |
+
label = translator.get('uis.face_landmarker_score_slider'),
|
| 26 |
+
value = state_manager.get_item('face_landmarker_score'),
|
| 27 |
+
step = calculate_float_step(facefusion.choices.face_landmarker_score_range),
|
| 28 |
+
minimum = facefusion.choices.face_landmarker_score_range[0],
|
| 29 |
+
maximum = facefusion.choices.face_landmarker_score_range[-1]
|
| 30 |
+
)
|
| 31 |
+
register_ui_component('face_landmarker_model_dropdown', FACE_LANDMARKER_MODEL_DROPDOWN)
|
| 32 |
+
register_ui_component('face_landmarker_score_slider', FACE_LANDMARKER_SCORE_SLIDER)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def listen() -> None:
|
| 36 |
+
FACE_LANDMARKER_MODEL_DROPDOWN.change(update_face_landmarker_model, inputs = FACE_LANDMARKER_MODEL_DROPDOWN, outputs = FACE_LANDMARKER_MODEL_DROPDOWN)
|
| 37 |
+
FACE_LANDMARKER_SCORE_SLIDER.release(update_face_landmarker_score, inputs = FACE_LANDMARKER_SCORE_SLIDER)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def update_face_landmarker_model(face_landmarker_model : FaceLandmarkerModel) -> gradio.Dropdown:
|
| 41 |
+
face_landmarker.clear_inference_pool()
|
| 42 |
+
state_manager.set_item('face_landmarker_model', face_landmarker_model)
|
| 43 |
+
|
| 44 |
+
if face_landmarker.pre_check():
|
| 45 |
+
gradio.Dropdown(value = state_manager.get_item('face_landmarker_model'))
|
| 46 |
+
return gradio.Dropdown()
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def update_face_landmarker_score(face_landmarker_score : Score) -> None:
|
| 50 |
+
state_manager.set_item('face_landmarker_score', face_landmarker_score)
|
uis/components/face_masker.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import face_masker, state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_float_step, calculate_int_step
|
| 8 |
+
from facefusion.sanitizer import sanitize_int_range
|
| 9 |
+
from facefusion.types import FaceMaskArea, FaceMaskRegion, FaceMaskType, FaceOccluderModel, FaceParserModel
|
| 10 |
+
from facefusion.uis.core import register_ui_component
|
| 11 |
+
|
| 12 |
+
FACE_OCCLUDER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
FACE_PARSER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 14 |
+
FACE_MASK_TYPES_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 15 |
+
FACE_MASK_AREAS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 16 |
+
FACE_MASK_REGIONS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 17 |
+
FACE_MASK_BOX_WRAPPER : Optional[gradio.Group] = None
|
| 18 |
+
FACE_MASK_BLUR_SLIDER : Optional[gradio.Slider] = None
|
| 19 |
+
FACE_MASK_PADDING_TOP_SLIDER : Optional[gradio.Slider] = None
|
| 20 |
+
FACE_MASK_PADDING_RIGHT_SLIDER : Optional[gradio.Slider] = None
|
| 21 |
+
FACE_MASK_PADDING_BOTTOM_SLIDER : Optional[gradio.Slider] = None
|
| 22 |
+
FACE_MASK_PADDING_LEFT_SLIDER : Optional[gradio.Slider] = None
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def render() -> None:
|
| 26 |
+
global FACE_OCCLUDER_MODEL_DROPDOWN
|
| 27 |
+
global FACE_PARSER_MODEL_DROPDOWN
|
| 28 |
+
global FACE_MASK_TYPES_CHECKBOX_GROUP
|
| 29 |
+
global FACE_MASK_AREAS_CHECKBOX_GROUP
|
| 30 |
+
global FACE_MASK_REGIONS_CHECKBOX_GROUP
|
| 31 |
+
global FACE_MASK_BOX_WRAPPER
|
| 32 |
+
global FACE_MASK_BLUR_SLIDER
|
| 33 |
+
global FACE_MASK_PADDING_TOP_SLIDER
|
| 34 |
+
global FACE_MASK_PADDING_RIGHT_SLIDER
|
| 35 |
+
global FACE_MASK_PADDING_BOTTOM_SLIDER
|
| 36 |
+
global FACE_MASK_PADDING_LEFT_SLIDER
|
| 37 |
+
|
| 38 |
+
has_box_mask = 'box' in state_manager.get_item('face_mask_types')
|
| 39 |
+
has_region_mask = 'region' in state_manager.get_item('face_mask_types')
|
| 40 |
+
has_area_mask = 'area' in state_manager.get_item('face_mask_types')
|
| 41 |
+
with gradio.Row():
|
| 42 |
+
FACE_OCCLUDER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 43 |
+
label = translator.get('uis.face_occluder_model_dropdown'),
|
| 44 |
+
choices = facefusion.choices.face_occluder_models,
|
| 45 |
+
value = state_manager.get_item('face_occluder_model')
|
| 46 |
+
)
|
| 47 |
+
FACE_PARSER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 48 |
+
label = translator.get('uis.face_parser_model_dropdown'),
|
| 49 |
+
choices = facefusion.choices.face_parser_models,
|
| 50 |
+
value = state_manager.get_item('face_parser_model')
|
| 51 |
+
)
|
| 52 |
+
FACE_MASK_TYPES_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 53 |
+
label = translator.get('uis.face_mask_types_checkbox_group'),
|
| 54 |
+
choices = facefusion.choices.face_mask_types,
|
| 55 |
+
value = state_manager.get_item('face_mask_types')
|
| 56 |
+
)
|
| 57 |
+
FACE_MASK_AREAS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 58 |
+
label = translator.get('uis.face_mask_areas_checkbox_group'),
|
| 59 |
+
choices = facefusion.choices.face_mask_areas,
|
| 60 |
+
value = state_manager.get_item('face_mask_areas'),
|
| 61 |
+
visible = has_area_mask
|
| 62 |
+
)
|
| 63 |
+
FACE_MASK_REGIONS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 64 |
+
label = translator.get('uis.face_mask_regions_checkbox_group'),
|
| 65 |
+
choices = facefusion.choices.face_mask_regions,
|
| 66 |
+
value = state_manager.get_item('face_mask_regions'),
|
| 67 |
+
visible = has_region_mask
|
| 68 |
+
)
|
| 69 |
+
FACE_MASK_BLUR_SLIDER = gradio.Slider(
|
| 70 |
+
label = translator.get('uis.face_mask_blur_slider'),
|
| 71 |
+
step = calculate_float_step(facefusion.choices.face_mask_blur_range),
|
| 72 |
+
minimum = facefusion.choices.face_mask_blur_range[0],
|
| 73 |
+
maximum = facefusion.choices.face_mask_blur_range[-1],
|
| 74 |
+
value = state_manager.get_item('face_mask_blur'),
|
| 75 |
+
visible = has_box_mask
|
| 76 |
+
)
|
| 77 |
+
with gradio.Group(visible = has_box_mask) as FACE_MASK_BOX_WRAPPER:
|
| 78 |
+
with gradio.Row():
|
| 79 |
+
FACE_MASK_PADDING_TOP_SLIDER = gradio.Slider(
|
| 80 |
+
label = translator.get('uis.face_mask_padding_top_slider'),
|
| 81 |
+
step = calculate_int_step(facefusion.choices.face_mask_padding_range),
|
| 82 |
+
minimum = facefusion.choices.face_mask_padding_range[0],
|
| 83 |
+
maximum = facefusion.choices.face_mask_padding_range[-1],
|
| 84 |
+
value = state_manager.get_item('face_mask_padding')[0]
|
| 85 |
+
)
|
| 86 |
+
FACE_MASK_PADDING_RIGHT_SLIDER = gradio.Slider(
|
| 87 |
+
label = translator.get('uis.face_mask_padding_right_slider'),
|
| 88 |
+
step = calculate_int_step(facefusion.choices.face_mask_padding_range),
|
| 89 |
+
minimum = facefusion.choices.face_mask_padding_range[0],
|
| 90 |
+
maximum = facefusion.choices.face_mask_padding_range[-1],
|
| 91 |
+
value = state_manager.get_item('face_mask_padding')[1]
|
| 92 |
+
)
|
| 93 |
+
with gradio.Row():
|
| 94 |
+
FACE_MASK_PADDING_BOTTOM_SLIDER = gradio.Slider(
|
| 95 |
+
label = translator.get('uis.face_mask_padding_bottom_slider'),
|
| 96 |
+
step = calculate_int_step(facefusion.choices.face_mask_padding_range),
|
| 97 |
+
minimum = facefusion.choices.face_mask_padding_range[0],
|
| 98 |
+
maximum = facefusion.choices.face_mask_padding_range[-1],
|
| 99 |
+
value = state_manager.get_item('face_mask_padding')[2]
|
| 100 |
+
)
|
| 101 |
+
FACE_MASK_PADDING_LEFT_SLIDER = gradio.Slider(
|
| 102 |
+
label = translator.get('uis.face_mask_padding_left_slider'),
|
| 103 |
+
step = calculate_int_step(facefusion.choices.face_mask_padding_range),
|
| 104 |
+
minimum = facefusion.choices.face_mask_padding_range[0],
|
| 105 |
+
maximum = facefusion.choices.face_mask_padding_range[-1],
|
| 106 |
+
value = state_manager.get_item('face_mask_padding')[3]
|
| 107 |
+
)
|
| 108 |
+
register_ui_component('face_occluder_model_dropdown', FACE_OCCLUDER_MODEL_DROPDOWN)
|
| 109 |
+
register_ui_component('face_parser_model_dropdown', FACE_PARSER_MODEL_DROPDOWN)
|
| 110 |
+
register_ui_component('face_mask_types_checkbox_group', FACE_MASK_TYPES_CHECKBOX_GROUP)
|
| 111 |
+
register_ui_component('face_mask_areas_checkbox_group', FACE_MASK_AREAS_CHECKBOX_GROUP)
|
| 112 |
+
register_ui_component('face_mask_regions_checkbox_group', FACE_MASK_REGIONS_CHECKBOX_GROUP)
|
| 113 |
+
register_ui_component('face_mask_blur_slider', FACE_MASK_BLUR_SLIDER)
|
| 114 |
+
register_ui_component('face_mask_padding_top_slider', FACE_MASK_PADDING_TOP_SLIDER)
|
| 115 |
+
register_ui_component('face_mask_padding_right_slider', FACE_MASK_PADDING_RIGHT_SLIDER)
|
| 116 |
+
register_ui_component('face_mask_padding_bottom_slider', FACE_MASK_PADDING_BOTTOM_SLIDER)
|
| 117 |
+
register_ui_component('face_mask_padding_left_slider', FACE_MASK_PADDING_LEFT_SLIDER)
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def listen() -> None:
|
| 121 |
+
FACE_OCCLUDER_MODEL_DROPDOWN.change(update_face_occluder_model, inputs = FACE_OCCLUDER_MODEL_DROPDOWN)
|
| 122 |
+
FACE_PARSER_MODEL_DROPDOWN.change(update_face_parser_model, inputs = FACE_PARSER_MODEL_DROPDOWN)
|
| 123 |
+
FACE_MASK_TYPES_CHECKBOX_GROUP.change(update_face_mask_types, inputs = FACE_MASK_TYPES_CHECKBOX_GROUP, outputs = [ FACE_MASK_TYPES_CHECKBOX_GROUP, FACE_MASK_AREAS_CHECKBOX_GROUP, FACE_MASK_REGIONS_CHECKBOX_GROUP, FACE_MASK_BLUR_SLIDER, FACE_MASK_BOX_WRAPPER ])
|
| 124 |
+
FACE_MASK_AREAS_CHECKBOX_GROUP.change(update_face_mask_areas, inputs = FACE_MASK_AREAS_CHECKBOX_GROUP, outputs = FACE_MASK_AREAS_CHECKBOX_GROUP)
|
| 125 |
+
FACE_MASK_REGIONS_CHECKBOX_GROUP.change(update_face_mask_regions, inputs = FACE_MASK_REGIONS_CHECKBOX_GROUP, outputs = FACE_MASK_REGIONS_CHECKBOX_GROUP)
|
| 126 |
+
FACE_MASK_BLUR_SLIDER.release(update_face_mask_blur, inputs = FACE_MASK_BLUR_SLIDER)
|
| 127 |
+
|
| 128 |
+
face_mask_padding_sliders = [ FACE_MASK_PADDING_TOP_SLIDER, FACE_MASK_PADDING_RIGHT_SLIDER, FACE_MASK_PADDING_BOTTOM_SLIDER, FACE_MASK_PADDING_LEFT_SLIDER ]
|
| 129 |
+
for face_mask_padding_slider in face_mask_padding_sliders:
|
| 130 |
+
face_mask_padding_slider.release(update_face_mask_padding, inputs = face_mask_padding_sliders)
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
def update_face_occluder_model(face_occluder_model : FaceOccluderModel) -> gradio.Dropdown:
|
| 134 |
+
face_masker.clear_inference_pool()
|
| 135 |
+
state_manager.set_item('face_occluder_model', face_occluder_model)
|
| 136 |
+
|
| 137 |
+
if face_masker.pre_check():
|
| 138 |
+
return gradio.Dropdown(value = state_manager.get_item('face_occluder_model'))
|
| 139 |
+
return gradio.Dropdown()
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def update_face_parser_model(face_parser_model : FaceParserModel) -> gradio.Dropdown:
|
| 143 |
+
face_masker.clear_inference_pool()
|
| 144 |
+
state_manager.set_item('face_parser_model', face_parser_model)
|
| 145 |
+
|
| 146 |
+
if face_masker.pre_check():
|
| 147 |
+
return gradio.Dropdown(value = state_manager.get_item('face_parser_model'))
|
| 148 |
+
return gradio.Dropdown()
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def update_face_mask_types(face_mask_types : List[FaceMaskType]) -> Tuple[gradio.CheckboxGroup, gradio.CheckboxGroup, gradio.CheckboxGroup, gradio.Slider, gradio.Group]:
|
| 152 |
+
face_mask_types = face_mask_types or facefusion.choices.face_mask_types
|
| 153 |
+
state_manager.set_item('face_mask_types', face_mask_types)
|
| 154 |
+
has_box_mask = 'box' in face_mask_types
|
| 155 |
+
has_area_mask = 'area' in face_mask_types
|
| 156 |
+
has_region_mask = 'region' in face_mask_types
|
| 157 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('face_mask_types')), gradio.CheckboxGroup(visible = has_area_mask), gradio.CheckboxGroup(visible = has_region_mask), gradio.Slider(visible = has_box_mask), gradio.Group(visible = has_box_mask)
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def update_face_mask_areas(face_mask_areas : List[FaceMaskArea]) -> gradio.CheckboxGroup:
|
| 161 |
+
face_mask_areas = face_mask_areas or facefusion.choices.face_mask_areas
|
| 162 |
+
state_manager.set_item('face_mask_areas', face_mask_areas)
|
| 163 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('face_mask_areas'))
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def update_face_mask_regions(face_mask_regions : List[FaceMaskRegion]) -> gradio.CheckboxGroup:
|
| 167 |
+
face_mask_regions = face_mask_regions or facefusion.choices.face_mask_regions
|
| 168 |
+
state_manager.set_item('face_mask_regions', face_mask_regions)
|
| 169 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('face_mask_regions'))
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def update_face_mask_blur(face_mask_blur : float) -> None:
|
| 173 |
+
state_manager.set_item('face_mask_blur', face_mask_blur)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def update_face_mask_padding(face_mask_padding_top : float, face_mask_padding_right : float, face_mask_padding_bottom : float, face_mask_padding_left : float) -> None:
|
| 177 |
+
face_mask_padding_top = sanitize_int_range(int(face_mask_padding_top), facefusion.choices.face_mask_padding_range)
|
| 178 |
+
face_mask_padding_right = sanitize_int_range(int(face_mask_padding_right), facefusion.choices.face_mask_padding_range)
|
| 179 |
+
face_mask_padding_bottom = sanitize_int_range(int(face_mask_padding_bottom), facefusion.choices.face_mask_padding_range)
|
| 180 |
+
face_mask_padding_left = sanitize_int_range(int(face_mask_padding_left), facefusion.choices.face_mask_padding_range)
|
| 181 |
+
state_manager.set_item('face_mask_padding', (face_mask_padding_top, face_mask_padding_right, face_mask_padding_bottom, face_mask_padding_left))
|
uis/components/face_selector.py
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import cv2
|
| 4 |
+
import gradio
|
| 5 |
+
from gradio_rangeslider import RangeSlider
|
| 6 |
+
|
| 7 |
+
import facefusion.choices
|
| 8 |
+
from facefusion import state_manager, translator
|
| 9 |
+
from facefusion.common_helper import calculate_float_step, calculate_int_step
|
| 10 |
+
from facefusion.face_creator import get_many_faces
|
| 11 |
+
from facefusion.face_selector import sort_and_filter_faces
|
| 12 |
+
from facefusion.face_store import clear_faces
|
| 13 |
+
from facefusion.filesystem import filter_image_paths, is_image, is_video
|
| 14 |
+
from facefusion.types import FaceSelectorGender, FaceSelectorMode, FaceSelectorOrder, FaceSelectorRace, VisionFrame
|
| 15 |
+
from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
|
| 16 |
+
from facefusion.uis.types import ComponentOptions
|
| 17 |
+
from facefusion.uis.ui_helper import convert_str_none
|
| 18 |
+
from facefusion.vision import fit_cover_frame, read_static_image, read_static_images, read_video_frame
|
| 19 |
+
|
| 20 |
+
FACE_SELECTOR_MODE_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 21 |
+
FACE_SELECTOR_ORDER_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 22 |
+
FACE_SELECTOR_GENDER_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 23 |
+
FACE_SELECTOR_RACE_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 24 |
+
FACE_SELECTOR_AGE_RANGE_SLIDER : Optional[RangeSlider] = None
|
| 25 |
+
REFERENCE_FACE_POSITION_GALLERY : Optional[gradio.Gallery] = None
|
| 26 |
+
REFERENCE_FACE_DISTANCE_SLIDER : Optional[gradio.Slider] = None
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def render() -> None:
|
| 30 |
+
global FACE_SELECTOR_MODE_DROPDOWN
|
| 31 |
+
global FACE_SELECTOR_ORDER_DROPDOWN
|
| 32 |
+
global FACE_SELECTOR_GENDER_DROPDOWN
|
| 33 |
+
global FACE_SELECTOR_RACE_DROPDOWN
|
| 34 |
+
global FACE_SELECTOR_AGE_RANGE_SLIDER
|
| 35 |
+
global REFERENCE_FACE_POSITION_GALLERY
|
| 36 |
+
global REFERENCE_FACE_DISTANCE_SLIDER
|
| 37 |
+
|
| 38 |
+
reference_face_gallery_options : ComponentOptions =\
|
| 39 |
+
{
|
| 40 |
+
'label': translator.get('uis.reference_face_gallery'),
|
| 41 |
+
'object_fit': 'cover',
|
| 42 |
+
'allow_preview': False,
|
| 43 |
+
'elem_classes': 'box-face-selector',
|
| 44 |
+
'visible': 'reference' in state_manager.get_item('face_selector_mode')
|
| 45 |
+
}
|
| 46 |
+
source_vision_frames = read_static_images(filter_image_paths(state_manager.get_item('source_paths')))
|
| 47 |
+
|
| 48 |
+
if is_image(state_manager.get_item('target_path')):
|
| 49 |
+
target_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
| 50 |
+
reference_face_gallery_options['value'] = extract_gallery_frames(source_vision_frames, target_vision_frame)
|
| 51 |
+
if is_video(state_manager.get_item('target_path')):
|
| 52 |
+
target_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
| 53 |
+
reference_face_gallery_options['value'] = extract_gallery_frames(source_vision_frames, target_vision_frame)
|
| 54 |
+
FACE_SELECTOR_MODE_DROPDOWN = gradio.Dropdown(
|
| 55 |
+
label = translator.get('uis.face_selector_mode_dropdown'),
|
| 56 |
+
choices = facefusion.choices.face_selector_modes,
|
| 57 |
+
value = state_manager.get_item('face_selector_mode')
|
| 58 |
+
)
|
| 59 |
+
REFERENCE_FACE_POSITION_GALLERY = gradio.Gallery(**reference_face_gallery_options)
|
| 60 |
+
with gradio.Group():
|
| 61 |
+
with gradio.Row():
|
| 62 |
+
FACE_SELECTOR_ORDER_DROPDOWN = gradio.Dropdown(
|
| 63 |
+
label = translator.get('uis.face_selector_order_dropdown'),
|
| 64 |
+
choices = facefusion.choices.face_selector_orders,
|
| 65 |
+
value = state_manager.get_item('face_selector_order')
|
| 66 |
+
)
|
| 67 |
+
FACE_SELECTOR_GENDER_DROPDOWN = gradio.Dropdown(
|
| 68 |
+
label = translator.get('uis.face_selector_gender_dropdown'),
|
| 69 |
+
choices = [ 'none' ] + facefusion.choices.face_selector_genders,
|
| 70 |
+
value = state_manager.get_item('face_selector_gender') or 'none'
|
| 71 |
+
)
|
| 72 |
+
FACE_SELECTOR_RACE_DROPDOWN = gradio.Dropdown(
|
| 73 |
+
label = translator.get('uis.face_selector_race_dropdown'),
|
| 74 |
+
choices = [ 'none' ] + facefusion.choices.face_selector_races,
|
| 75 |
+
value = state_manager.get_item('face_selector_race') or 'none'
|
| 76 |
+
)
|
| 77 |
+
with gradio.Row():
|
| 78 |
+
face_selector_age_start = state_manager.get_item('face_selector_age_start') or facefusion.choices.face_selector_age_range[0]
|
| 79 |
+
face_selector_age_end = state_manager.get_item('face_selector_age_end') or facefusion.choices.face_selector_age_range[-1]
|
| 80 |
+
FACE_SELECTOR_AGE_RANGE_SLIDER = RangeSlider(
|
| 81 |
+
label = translator.get('uis.face_selector_age_range_slider'),
|
| 82 |
+
minimum = facefusion.choices.face_selector_age_range[0],
|
| 83 |
+
maximum = facefusion.choices.face_selector_age_range[-1],
|
| 84 |
+
value = (face_selector_age_start, face_selector_age_end),
|
| 85 |
+
step = calculate_int_step(facefusion.choices.face_selector_age_range)
|
| 86 |
+
)
|
| 87 |
+
REFERENCE_FACE_DISTANCE_SLIDER = gradio.Slider(
|
| 88 |
+
label = translator.get('uis.reference_face_distance_slider'),
|
| 89 |
+
value = state_manager.get_item('reference_face_distance'),
|
| 90 |
+
step = calculate_float_step(facefusion.choices.reference_face_distance_range),
|
| 91 |
+
minimum = facefusion.choices.reference_face_distance_range[0],
|
| 92 |
+
maximum = facefusion.choices.reference_face_distance_range[-1],
|
| 93 |
+
visible = 'reference' in state_manager.get_item('face_selector_mode')
|
| 94 |
+
)
|
| 95 |
+
register_ui_component('face_selector_mode_dropdown', FACE_SELECTOR_MODE_DROPDOWN)
|
| 96 |
+
register_ui_component('face_selector_order_dropdown', FACE_SELECTOR_ORDER_DROPDOWN)
|
| 97 |
+
register_ui_component('face_selector_gender_dropdown', FACE_SELECTOR_GENDER_DROPDOWN)
|
| 98 |
+
register_ui_component('face_selector_race_dropdown', FACE_SELECTOR_RACE_DROPDOWN)
|
| 99 |
+
register_ui_component('face_selector_age_range_slider', FACE_SELECTOR_AGE_RANGE_SLIDER)
|
| 100 |
+
register_ui_component('reference_face_position_gallery', REFERENCE_FACE_POSITION_GALLERY)
|
| 101 |
+
register_ui_component('reference_face_distance_slider', REFERENCE_FACE_DISTANCE_SLIDER)
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def listen() -> None:
|
| 105 |
+
FACE_SELECTOR_MODE_DROPDOWN.change(update_face_selector_mode, inputs = FACE_SELECTOR_MODE_DROPDOWN, outputs = [ REFERENCE_FACE_POSITION_GALLERY, REFERENCE_FACE_DISTANCE_SLIDER ])
|
| 106 |
+
FACE_SELECTOR_ORDER_DROPDOWN.change(update_face_selector_order, inputs = FACE_SELECTOR_ORDER_DROPDOWN, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 107 |
+
FACE_SELECTOR_GENDER_DROPDOWN.change(update_face_selector_gender, inputs = FACE_SELECTOR_GENDER_DROPDOWN, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 108 |
+
FACE_SELECTOR_RACE_DROPDOWN.change(update_face_selector_race, inputs = FACE_SELECTOR_RACE_DROPDOWN, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 109 |
+
FACE_SELECTOR_AGE_RANGE_SLIDER.release(update_face_selector_age_range, inputs = FACE_SELECTOR_AGE_RANGE_SLIDER, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 110 |
+
REFERENCE_FACE_DISTANCE_SLIDER.release(update_reference_face_distance, inputs = REFERENCE_FACE_DISTANCE_SLIDER)
|
| 111 |
+
|
| 112 |
+
preview_frame_slider = get_ui_component('preview_frame_slider')
|
| 113 |
+
if preview_frame_slider:
|
| 114 |
+
REFERENCE_FACE_POSITION_GALLERY.select(update_reference_frame_number, inputs = preview_frame_slider)
|
| 115 |
+
REFERENCE_FACE_POSITION_GALLERY.select(update_reference_face_position)
|
| 116 |
+
|
| 117 |
+
for ui_component in get_ui_components(
|
| 118 |
+
[
|
| 119 |
+
'target_image',
|
| 120 |
+
'target_video'
|
| 121 |
+
]):
|
| 122 |
+
for method in [ 'change', 'clear' ]:
|
| 123 |
+
getattr(ui_component, method)(clear_reference_frame_number)
|
| 124 |
+
getattr(ui_component, method)(clear_reference_face_position)
|
| 125 |
+
getattr(ui_component, method)(update_reference_position_gallery, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 126 |
+
|
| 127 |
+
for ui_component in get_ui_components(
|
| 128 |
+
[
|
| 129 |
+
'face_detector_model_dropdown',
|
| 130 |
+
'face_detector_size_dropdown',
|
| 131 |
+
'face_detector_angles_checkbox_group'
|
| 132 |
+
]):
|
| 133 |
+
ui_component.change(clear_and_update_reference_position_gallery, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 134 |
+
|
| 135 |
+
face_detector_score_slider = get_ui_component('face_detector_score_slider')
|
| 136 |
+
if face_detector_score_slider:
|
| 137 |
+
face_detector_score_slider.release(update_reference_position_gallery, outputs = REFERENCE_FACE_POSITION_GALLERY)
|
| 138 |
+
|
| 139 |
+
preview_frame_slider = get_ui_component('preview_frame_slider')
|
| 140 |
+
if preview_frame_slider:
|
| 141 |
+
for method in [ 'change', 'release' ]:
|
| 142 |
+
getattr(preview_frame_slider, method)(update_reference_position_gallery, inputs = preview_frame_slider, outputs = REFERENCE_FACE_POSITION_GALLERY, show_progress = 'hidden')
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
def update_face_selector_mode(face_selector_mode : FaceSelectorMode) -> Tuple[gradio.Gallery, gradio.Slider]:
|
| 146 |
+
state_manager.set_item('face_selector_mode', face_selector_mode)
|
| 147 |
+
if face_selector_mode == 'many':
|
| 148 |
+
return gradio.Gallery(visible = False), gradio.Slider(visible = False)
|
| 149 |
+
if face_selector_mode == 'one':
|
| 150 |
+
return gradio.Gallery(visible = False), gradio.Slider(visible = False)
|
| 151 |
+
if face_selector_mode == 'reference':
|
| 152 |
+
return gradio.Gallery(visible = True), gradio.Slider(visible = True)
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
def update_face_selector_order(face_analyser_order : FaceSelectorOrder) -> gradio.Gallery:
|
| 156 |
+
state_manager.set_item('face_selector_order', convert_str_none(face_analyser_order))
|
| 157 |
+
return update_reference_position_gallery()
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def update_face_selector_gender(face_selector_gender : FaceSelectorGender) -> gradio.Gallery:
|
| 161 |
+
state_manager.set_item('face_selector_gender', convert_str_none(face_selector_gender))
|
| 162 |
+
return update_reference_position_gallery()
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
def update_face_selector_race(face_selector_race : FaceSelectorRace) -> gradio.Gallery:
|
| 166 |
+
state_manager.set_item('face_selector_race', convert_str_none(face_selector_race))
|
| 167 |
+
return update_reference_position_gallery()
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
def update_face_selector_age_range(face_selector_age_range : Tuple[float, float]) -> gradio.Gallery:
|
| 171 |
+
face_selector_age_start, face_selector_age_end = face_selector_age_range
|
| 172 |
+
state_manager.set_item('face_selector_age_start', int(face_selector_age_start))
|
| 173 |
+
state_manager.set_item('face_selector_age_end', int(face_selector_age_end))
|
| 174 |
+
return update_reference_position_gallery()
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
def update_reference_face_position(event : gradio.SelectData) -> None:
|
| 178 |
+
state_manager.set_item('reference_face_position', event.index)
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
def clear_reference_face_position() -> None:
|
| 182 |
+
state_manager.set_item('reference_face_position', 0)
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
def update_reference_face_distance(reference_face_distance : float) -> None:
|
| 186 |
+
state_manager.set_item('reference_face_distance', reference_face_distance)
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
def update_reference_frame_number(reference_frame_number : int = 0) -> None:
|
| 190 |
+
state_manager.set_item('reference_frame_number', reference_frame_number)
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def clear_reference_frame_number() -> None:
|
| 194 |
+
state_manager.set_item('reference_frame_number', 0)
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
def clear_and_update_reference_position_gallery() -> gradio.Gallery:
|
| 198 |
+
clear_faces()
|
| 199 |
+
return update_reference_position_gallery()
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
def update_reference_position_gallery(frame_number : int = 0) -> gradio.Gallery:
|
| 203 |
+
gallery_vision_frames = []
|
| 204 |
+
source_vision_frames = read_static_images(filter_image_paths(state_manager.get_item('source_paths')))
|
| 205 |
+
|
| 206 |
+
if is_image(state_manager.get_item('target_path')):
|
| 207 |
+
target_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
| 208 |
+
gallery_vision_frames = extract_gallery_frames(source_vision_frames, target_vision_frame)
|
| 209 |
+
if is_video(state_manager.get_item('target_path')):
|
| 210 |
+
target_vision_frame = read_video_frame(state_manager.get_item('target_path'), frame_number)
|
| 211 |
+
gallery_vision_frames = extract_gallery_frames(source_vision_frames, target_vision_frame)
|
| 212 |
+
if gallery_vision_frames:
|
| 213 |
+
return gradio.Gallery(value = gallery_vision_frames)
|
| 214 |
+
return gradio.Gallery(value = None)
|
| 215 |
+
|
| 216 |
+
|
| 217 |
+
def extract_gallery_frames(source_vision_frames : List[VisionFrame], target_vision_frame : VisionFrame) -> List[VisionFrame]:
|
| 218 |
+
gallery_vision_frames = []
|
| 219 |
+
source_faces = get_many_faces(source_vision_frames)
|
| 220 |
+
target_faces = get_many_faces([ target_vision_frame ])
|
| 221 |
+
target_faces = sort_and_filter_faces(source_faces, target_faces)
|
| 222 |
+
|
| 223 |
+
for target_face in target_faces:
|
| 224 |
+
start_x, start_y, end_x, end_y = map(int, target_face.bounding_box)
|
| 225 |
+
padding_x = int((end_x - start_x) * 0.25)
|
| 226 |
+
padding_y = int((end_y - start_y) * 0.25)
|
| 227 |
+
start_x = max(0, start_x - padding_x)
|
| 228 |
+
start_y = max(0, start_y - padding_y)
|
| 229 |
+
end_x = max(0, end_x + padding_x)
|
| 230 |
+
end_y = max(0, end_y + padding_y)
|
| 231 |
+
crop_vision_frame = target_vision_frame[start_y:end_y, start_x:end_x]
|
| 232 |
+
crop_vision_frame = fit_cover_frame(crop_vision_frame, (128, 128))
|
| 233 |
+
crop_vision_frame = cv2.cvtColor(crop_vision_frame, cv2.COLOR_BGR2RGB)
|
| 234 |
+
gallery_vision_frames.append(crop_vision_frame)
|
| 235 |
+
|
| 236 |
+
return gallery_vision_frames
|
uis/components/face_swapper_options.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_float_step, get_first
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.face_swapper import choices as face_swapper_choices
|
| 9 |
+
from facefusion.processors.modules.face_swapper.types import FaceSwapperModel, FaceSwapperWeight
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
FACE_SWAPPER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
FACE_SWAPPER_PIXEL_BOOST_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 14 |
+
FACE_SWAPPER_WEIGHT_SLIDER : Optional[gradio.Slider] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def render() -> None:
|
| 18 |
+
global FACE_SWAPPER_MODEL_DROPDOWN
|
| 19 |
+
global FACE_SWAPPER_PIXEL_BOOST_DROPDOWN
|
| 20 |
+
global FACE_SWAPPER_WEIGHT_SLIDER
|
| 21 |
+
|
| 22 |
+
has_face_swapper = 'face_swapper' in state_manager.get_item('processors')
|
| 23 |
+
FACE_SWAPPER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 24 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.face_swapper'),
|
| 25 |
+
choices = face_swapper_choices.face_swapper_models,
|
| 26 |
+
value = state_manager.get_item('face_swapper_model'),
|
| 27 |
+
visible = has_face_swapper
|
| 28 |
+
)
|
| 29 |
+
FACE_SWAPPER_PIXEL_BOOST_DROPDOWN = gradio.Dropdown(
|
| 30 |
+
label = translator.get('uis.pixel_boost_dropdown', 'facefusion.processors.modules.face_swapper'),
|
| 31 |
+
choices = face_swapper_choices.face_swapper_set.get(state_manager.get_item('face_swapper_model')),
|
| 32 |
+
value = state_manager.get_item('face_swapper_pixel_boost'),
|
| 33 |
+
visible = has_face_swapper
|
| 34 |
+
)
|
| 35 |
+
FACE_SWAPPER_WEIGHT_SLIDER = gradio.Slider(
|
| 36 |
+
label = translator.get('uis.weight_slider', 'facefusion.processors.modules.face_swapper'),
|
| 37 |
+
value = state_manager.get_item('face_swapper_weight'),
|
| 38 |
+
minimum = face_swapper_choices.face_swapper_weight_range[0],
|
| 39 |
+
maximum = face_swapper_choices.face_swapper_weight_range[-1],
|
| 40 |
+
step = calculate_float_step(face_swapper_choices.face_swapper_weight_range),
|
| 41 |
+
visible = has_face_swapper and has_face_swapper_weight()
|
| 42 |
+
)
|
| 43 |
+
register_ui_component('face_swapper_model_dropdown', FACE_SWAPPER_MODEL_DROPDOWN)
|
| 44 |
+
register_ui_component('face_swapper_pixel_boost_dropdown', FACE_SWAPPER_PIXEL_BOOST_DROPDOWN)
|
| 45 |
+
register_ui_component('face_swapper_weight_slider', FACE_SWAPPER_WEIGHT_SLIDER)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def listen() -> None:
|
| 49 |
+
FACE_SWAPPER_MODEL_DROPDOWN.change(update_face_swapper_model, inputs = FACE_SWAPPER_MODEL_DROPDOWN, outputs = [ FACE_SWAPPER_MODEL_DROPDOWN, FACE_SWAPPER_PIXEL_BOOST_DROPDOWN, FACE_SWAPPER_WEIGHT_SLIDER ])
|
| 50 |
+
FACE_SWAPPER_PIXEL_BOOST_DROPDOWN.change(update_face_swapper_pixel_boost, inputs = FACE_SWAPPER_PIXEL_BOOST_DROPDOWN)
|
| 51 |
+
FACE_SWAPPER_WEIGHT_SLIDER.change(update_face_swapper_weight, inputs = FACE_SWAPPER_WEIGHT_SLIDER)
|
| 52 |
+
|
| 53 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 54 |
+
if processors_checkbox_group:
|
| 55 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FACE_SWAPPER_MODEL_DROPDOWN, FACE_SWAPPER_PIXEL_BOOST_DROPDOWN, FACE_SWAPPER_WEIGHT_SLIDER ])
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Dropdown, gradio.Slider]:
|
| 59 |
+
has_face_swapper = 'face_swapper' in processors
|
| 60 |
+
return gradio.Dropdown(visible = has_face_swapper), gradio.Dropdown(visible = has_face_swapper), gradio.Slider(visible = has_face_swapper)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_face_swapper_model(face_swapper_model : FaceSwapperModel) -> Tuple[gradio.Dropdown, gradio.Dropdown, gradio.Slider]:
|
| 64 |
+
face_swapper_module = load_processor_module('face_swapper')
|
| 65 |
+
face_swapper_module.clear_inference_pool()
|
| 66 |
+
state_manager.set_item('face_swapper_model', face_swapper_model)
|
| 67 |
+
|
| 68 |
+
if face_swapper_module.pre_check():
|
| 69 |
+
face_swapper_pixel_boost_dropdown_choices = face_swapper_choices.face_swapper_set.get(state_manager.get_item('face_swapper_model'))
|
| 70 |
+
state_manager.set_item('face_swapper_pixel_boost', get_first(face_swapper_pixel_boost_dropdown_choices))
|
| 71 |
+
return gradio.Dropdown(value = state_manager.get_item('face_swapper_model')), gradio.Dropdown(value = state_manager.get_item('face_swapper_pixel_boost'), choices = face_swapper_pixel_boost_dropdown_choices), gradio.Slider(visible = has_face_swapper_weight())
|
| 72 |
+
return gradio.Dropdown(), gradio.Dropdown(), gradio.Slider()
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def update_face_swapper_pixel_boost(face_swapper_pixel_boost : str) -> None:
|
| 76 |
+
state_manager.set_item('face_swapper_pixel_boost', face_swapper_pixel_boost)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def update_face_swapper_weight(face_swapper_weight : FaceSwapperWeight) -> None:
|
| 80 |
+
state_manager.set_item('face_swapper_weight', face_swapper_weight)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def has_face_swapper_weight() -> bool:
|
| 84 |
+
return state_manager.get_item('face_swapper_model') in [ 'ghost_1_256', 'ghost_2_256', 'ghost_3_256', 'hififace_unofficial_256', 'hyperswap_1a_256', 'hyperswap_1b_256', 'hyperswap_1c_256', 'inswapper_128', 'inswapper_128_fp16', 'simswap_256', 'simswap_unofficial_512' ]
|
uis/components/face_tracker.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_float_step
|
| 8 |
+
from facefusion.types import Score
|
| 9 |
+
from facefusion.uis.core import register_ui_component
|
| 10 |
+
|
| 11 |
+
FACE_TRACKER_SCORE_SLIDER : Optional[gradio.Slider] = None
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def render() -> None:
|
| 15 |
+
global FACE_TRACKER_SCORE_SLIDER
|
| 16 |
+
|
| 17 |
+
FACE_TRACKER_SCORE_SLIDER = gradio.Slider(
|
| 18 |
+
label = translator.get('uis.face_tracker_score_slider'),
|
| 19 |
+
value = state_manager.get_item('face_tracker_score'),
|
| 20 |
+
step = calculate_float_step(facefusion.choices.face_tracker_score_range),
|
| 21 |
+
minimum = facefusion.choices.face_tracker_score_range[0],
|
| 22 |
+
maximum = facefusion.choices.face_tracker_score_range[-1]
|
| 23 |
+
)
|
| 24 |
+
register_ui_component('face_tracker_score_slider', FACE_TRACKER_SCORE_SLIDER)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def listen() -> None:
|
| 28 |
+
FACE_TRACKER_SCORE_SLIDER.release(update_face_tracker_score, inputs = FACE_TRACKER_SCORE_SLIDER)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def update_face_tracker_score(face_tracker_score : Score) -> None:
|
| 32 |
+
state_manager.set_item('face_tracker_score', face_tracker_score)
|
uis/components/frame_colorizer_options.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_int_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.frame_colorizer import choices as frame_colorizer_choices
|
| 9 |
+
from facefusion.processors.modules.frame_colorizer.types import FrameColorizerModel
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
FRAME_COLORIZER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
FRAME_COLORIZER_SIZE_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 14 |
+
FRAME_COLORIZER_BLEND_SLIDER : Optional[gradio.Slider] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def render() -> None:
|
| 18 |
+
global FRAME_COLORIZER_MODEL_DROPDOWN
|
| 19 |
+
global FRAME_COLORIZER_SIZE_DROPDOWN
|
| 20 |
+
global FRAME_COLORIZER_BLEND_SLIDER
|
| 21 |
+
|
| 22 |
+
has_frame_colorizer = 'frame_colorizer' in state_manager.get_item('processors')
|
| 23 |
+
FRAME_COLORIZER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 24 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.frame_colorizer'),
|
| 25 |
+
choices = frame_colorizer_choices.frame_colorizer_models,
|
| 26 |
+
value = state_manager.get_item('frame_colorizer_model'),
|
| 27 |
+
visible = has_frame_colorizer
|
| 28 |
+
)
|
| 29 |
+
FRAME_COLORIZER_SIZE_DROPDOWN = gradio.Dropdown(
|
| 30 |
+
label = translator.get('uis.size_dropdown', 'facefusion.processors.modules.frame_colorizer'),
|
| 31 |
+
choices = frame_colorizer_choices.frame_colorizer_sizes,
|
| 32 |
+
value = state_manager.get_item('frame_colorizer_size'),
|
| 33 |
+
visible = has_frame_colorizer
|
| 34 |
+
)
|
| 35 |
+
FRAME_COLORIZER_BLEND_SLIDER = gradio.Slider(
|
| 36 |
+
label = translator.get('uis.blend_slider', 'facefusion.processors.modules.frame_colorizer'),
|
| 37 |
+
value = state_manager.get_item('frame_colorizer_blend'),
|
| 38 |
+
step = calculate_int_step(frame_colorizer_choices.frame_colorizer_blend_range),
|
| 39 |
+
minimum = frame_colorizer_choices.frame_colorizer_blend_range[0],
|
| 40 |
+
maximum = frame_colorizer_choices.frame_colorizer_blend_range[-1],
|
| 41 |
+
visible = has_frame_colorizer
|
| 42 |
+
)
|
| 43 |
+
register_ui_component('frame_colorizer_model_dropdown', FRAME_COLORIZER_MODEL_DROPDOWN)
|
| 44 |
+
register_ui_component('frame_colorizer_size_dropdown', FRAME_COLORIZER_SIZE_DROPDOWN)
|
| 45 |
+
register_ui_component('frame_colorizer_blend_slider', FRAME_COLORIZER_BLEND_SLIDER)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def listen() -> None:
|
| 49 |
+
FRAME_COLORIZER_MODEL_DROPDOWN.change(update_frame_colorizer_model, inputs = FRAME_COLORIZER_MODEL_DROPDOWN, outputs = FRAME_COLORIZER_MODEL_DROPDOWN)
|
| 50 |
+
FRAME_COLORIZER_SIZE_DROPDOWN.change(update_frame_colorizer_size, inputs = FRAME_COLORIZER_SIZE_DROPDOWN)
|
| 51 |
+
FRAME_COLORIZER_BLEND_SLIDER.release(update_frame_colorizer_blend, inputs = FRAME_COLORIZER_BLEND_SLIDER)
|
| 52 |
+
|
| 53 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 54 |
+
if processors_checkbox_group:
|
| 55 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FRAME_COLORIZER_MODEL_DROPDOWN, FRAME_COLORIZER_BLEND_SLIDER, FRAME_COLORIZER_SIZE_DROPDOWN ])
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.Dropdown]:
|
| 59 |
+
has_frame_colorizer = 'frame_colorizer' in processors
|
| 60 |
+
return gradio.Dropdown(visible = has_frame_colorizer), gradio.Slider(visible = has_frame_colorizer), gradio.Dropdown(visible = has_frame_colorizer)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_frame_colorizer_model(frame_colorizer_model : FrameColorizerModel) -> gradio.Dropdown:
|
| 64 |
+
frame_colorizer_module = load_processor_module('frame_colorizer')
|
| 65 |
+
frame_colorizer_module.clear_inference_pool()
|
| 66 |
+
state_manager.set_item('frame_colorizer_model', frame_colorizer_model)
|
| 67 |
+
|
| 68 |
+
if frame_colorizer_module.pre_check():
|
| 69 |
+
return gradio.Dropdown(value = state_manager.get_item('frame_colorizer_model'))
|
| 70 |
+
return gradio.Dropdown()
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def update_frame_colorizer_size(frame_colorizer_size : str) -> None:
|
| 74 |
+
state_manager.set_item('frame_colorizer_size', frame_colorizer_size)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def update_frame_colorizer_blend(frame_colorizer_blend : float) -> None:
|
| 78 |
+
state_manager.set_item('frame_colorizer_blend', int(frame_colorizer_blend))
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
|
uis/components/frame_enhancer_options.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_int_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.frame_enhancer import choices as frame_enhancer_choices
|
| 9 |
+
from facefusion.processors.modules.frame_enhancer.types import FrameEnhancerModel
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
FRAME_ENHANCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
FRAME_ENHANCER_BLEND_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global FRAME_ENHANCER_MODEL_DROPDOWN
|
| 18 |
+
global FRAME_ENHANCER_BLEND_SLIDER
|
| 19 |
+
|
| 20 |
+
has_frame_enhancer = 'frame_enhancer' in state_manager.get_item('processors')
|
| 21 |
+
FRAME_ENHANCER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 22 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.frame_enhancer'),
|
| 23 |
+
choices = frame_enhancer_choices.frame_enhancer_models,
|
| 24 |
+
value = state_manager.get_item('frame_enhancer_model'),
|
| 25 |
+
visible = has_frame_enhancer
|
| 26 |
+
)
|
| 27 |
+
FRAME_ENHANCER_BLEND_SLIDER = gradio.Slider(
|
| 28 |
+
label = translator.get('uis.blend_slider', 'facefusion.processors.modules.frame_enhancer'),
|
| 29 |
+
value = state_manager.get_item('frame_enhancer_blend'),
|
| 30 |
+
step = calculate_int_step(frame_enhancer_choices.frame_enhancer_blend_range),
|
| 31 |
+
minimum = frame_enhancer_choices.frame_enhancer_blend_range[0],
|
| 32 |
+
maximum = frame_enhancer_choices.frame_enhancer_blend_range[-1],
|
| 33 |
+
visible = has_frame_enhancer
|
| 34 |
+
)
|
| 35 |
+
register_ui_component('frame_enhancer_model_dropdown', FRAME_ENHANCER_MODEL_DROPDOWN)
|
| 36 |
+
register_ui_component('frame_enhancer_blend_slider', FRAME_ENHANCER_BLEND_SLIDER)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def listen() -> None:
|
| 40 |
+
FRAME_ENHANCER_MODEL_DROPDOWN.change(update_frame_enhancer_model, inputs = FRAME_ENHANCER_MODEL_DROPDOWN, outputs = FRAME_ENHANCER_MODEL_DROPDOWN)
|
| 41 |
+
FRAME_ENHANCER_BLEND_SLIDER.release(update_frame_enhancer_blend, inputs = FRAME_ENHANCER_BLEND_SLIDER)
|
| 42 |
+
|
| 43 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 44 |
+
if processors_checkbox_group:
|
| 45 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FRAME_ENHANCER_MODEL_DROPDOWN, FRAME_ENHANCER_BLEND_SLIDER ])
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
|
| 49 |
+
has_frame_enhancer = 'frame_enhancer' in processors
|
| 50 |
+
return gradio.Dropdown(visible = has_frame_enhancer), gradio.Slider(visible = has_frame_enhancer)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def update_frame_enhancer_model(frame_enhancer_model : FrameEnhancerModel) -> gradio.Dropdown:
|
| 54 |
+
frame_enhancer_module = load_processor_module('frame_enhancer')
|
| 55 |
+
frame_enhancer_module.clear_inference_pool()
|
| 56 |
+
state_manager.set_item('frame_enhancer_model', frame_enhancer_model)
|
| 57 |
+
|
| 58 |
+
if frame_enhancer_module.pre_check():
|
| 59 |
+
return gradio.Dropdown(value = state_manager.get_item('frame_enhancer_model'))
|
| 60 |
+
return gradio.Dropdown()
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_frame_enhancer_blend(frame_enhancer_blend : float) -> None:
|
| 64 |
+
state_manager.set_item('frame_enhancer_blend', int(frame_enhancer_blend))
|
uis/components/instant_runner.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from time import sleep
|
| 2 |
+
from typing import Optional, Tuple
|
| 3 |
+
|
| 4 |
+
import gradio
|
| 5 |
+
|
| 6 |
+
from facefusion import process_manager, state_manager, translator
|
| 7 |
+
from facefusion.args import collect_step_args
|
| 8 |
+
from facefusion.core import process_step
|
| 9 |
+
from facefusion.filesystem import is_directory, is_image, is_video
|
| 10 |
+
from facefusion.jobs import job_helper, job_manager, job_runner, job_store
|
| 11 |
+
from facefusion.temp_helper import clear_temp_directory
|
| 12 |
+
from facefusion.types import Args, UiWorkflow
|
| 13 |
+
from facefusion.uis.core import get_ui_component
|
| 14 |
+
from facefusion.uis.ui_helper import suggest_output_path
|
| 15 |
+
|
| 16 |
+
INSTANT_RUNNER_WRAPPER : Optional[gradio.Row] = None
|
| 17 |
+
INSTANT_RUNNER_START_BUTTON : Optional[gradio.Button] = None
|
| 18 |
+
INSTANT_RUNNER_STOP_BUTTON : Optional[gradio.Button] = None
|
| 19 |
+
INSTANT_RUNNER_CLEAR_BUTTON : Optional[gradio.Button] = None
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def render() -> None:
|
| 23 |
+
global INSTANT_RUNNER_WRAPPER
|
| 24 |
+
global INSTANT_RUNNER_START_BUTTON
|
| 25 |
+
global INSTANT_RUNNER_STOP_BUTTON
|
| 26 |
+
global INSTANT_RUNNER_CLEAR_BUTTON
|
| 27 |
+
|
| 28 |
+
if job_manager.init_jobs(state_manager.get_item('jobs_path')):
|
| 29 |
+
is_instant_runner = state_manager.get_item('ui_workflow') == 'instant_runner'
|
| 30 |
+
|
| 31 |
+
with gradio.Row(visible = is_instant_runner) as INSTANT_RUNNER_WRAPPER:
|
| 32 |
+
INSTANT_RUNNER_START_BUTTON = gradio.Button(
|
| 33 |
+
value = translator.get('uis.start_button'),
|
| 34 |
+
variant = 'primary',
|
| 35 |
+
size = 'sm'
|
| 36 |
+
)
|
| 37 |
+
INSTANT_RUNNER_STOP_BUTTON = gradio.Button(
|
| 38 |
+
value = translator.get('uis.stop_button'),
|
| 39 |
+
variant = 'primary',
|
| 40 |
+
size = 'sm',
|
| 41 |
+
visible = False
|
| 42 |
+
)
|
| 43 |
+
INSTANT_RUNNER_CLEAR_BUTTON = gradio.Button(
|
| 44 |
+
value = translator.get('uis.clear_button'),
|
| 45 |
+
size = 'sm'
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def listen() -> None:
|
| 50 |
+
output_image = get_ui_component('output_image')
|
| 51 |
+
output_video = get_ui_component('output_video')
|
| 52 |
+
ui_workflow_dropdown = get_ui_component('ui_workflow_dropdown')
|
| 53 |
+
|
| 54 |
+
if output_image and output_video:
|
| 55 |
+
INSTANT_RUNNER_START_BUTTON.click(start, outputs = [ INSTANT_RUNNER_START_BUTTON, INSTANT_RUNNER_STOP_BUTTON ])
|
| 56 |
+
INSTANT_RUNNER_START_BUTTON.click(run, outputs = [ INSTANT_RUNNER_START_BUTTON, INSTANT_RUNNER_STOP_BUTTON, output_image, output_video ])
|
| 57 |
+
INSTANT_RUNNER_STOP_BUTTON.click(stop, outputs = [ INSTANT_RUNNER_START_BUTTON, INSTANT_RUNNER_STOP_BUTTON, output_image, output_video ])
|
| 58 |
+
INSTANT_RUNNER_CLEAR_BUTTON.click(clear, outputs = [ output_image, output_video ])
|
| 59 |
+
if ui_workflow_dropdown:
|
| 60 |
+
ui_workflow_dropdown.change(remote_update, inputs = ui_workflow_dropdown, outputs = INSTANT_RUNNER_WRAPPER)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def remote_update(ui_workflow : UiWorkflow) -> gradio.Row:
|
| 64 |
+
is_instant_runner = ui_workflow == 'instant_runner'
|
| 65 |
+
|
| 66 |
+
return gradio.Row(visible = is_instant_runner)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def start() -> Tuple[gradio.Button, gradio.Button]:
|
| 70 |
+
while not process_manager.is_processing():
|
| 71 |
+
sleep(0.5)
|
| 72 |
+
return gradio.Button(visible = False), gradio.Button(visible = True)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def run() -> Tuple[gradio.Button, gradio.Button, gradio.Image, gradio.Video]:
|
| 76 |
+
step_args = collect_step_args()
|
| 77 |
+
output_path = step_args.get('output_path')
|
| 78 |
+
|
| 79 |
+
if is_directory(step_args.get('output_path')):
|
| 80 |
+
step_args['output_path'] = suggest_output_path(step_args.get('output_path'), state_manager.get_item('target_path'))
|
| 81 |
+
if job_manager.init_jobs(state_manager.get_item('jobs_path')):
|
| 82 |
+
create_and_run_job(step_args)
|
| 83 |
+
state_manager.set_item('output_path', output_path)
|
| 84 |
+
if is_image(step_args.get('output_path')):
|
| 85 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = step_args.get('output_path'), visible = True), gradio.Video(value = None, visible = False)
|
| 86 |
+
if is_video(step_args.get('output_path')):
|
| 87 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = None, visible = False), gradio.Video(value = step_args.get('output_path'), visible = True)
|
| 88 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = None), gradio.Video(value = None)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def create_and_run_job(step_args : Args) -> bool:
|
| 92 |
+
job_id = job_helper.suggest_job_id('ui')
|
| 93 |
+
|
| 94 |
+
for key in job_store.get_job_keys():
|
| 95 |
+
state_manager.sync_item(key) #type:ignore[arg-type]
|
| 96 |
+
|
| 97 |
+
return job_manager.create_job(job_id) and job_manager.add_step(job_id, step_args) and job_manager.submit_job(job_id) and job_runner.run_job(job_id, process_step)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def stop() -> Tuple[gradio.Button, gradio.Button, gradio.Image, gradio.Video]:
|
| 101 |
+
process_manager.stop()
|
| 102 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = None), gradio.Video(value = None)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def clear() -> Tuple[gradio.Image, gradio.Video]:
|
| 106 |
+
while process_manager.is_processing():
|
| 107 |
+
sleep(0.5)
|
| 108 |
+
if state_manager.get_item('target_path'):
|
| 109 |
+
clear_temp_directory(state_manager.get_item('target_path'))
|
| 110 |
+
return gradio.Image(value = None), gradio.Video(value = None)
|
uis/components/job_list.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.common_helper import get_first
|
| 8 |
+
from facefusion.jobs import job_list, job_manager
|
| 9 |
+
from facefusion.types import JobStatus
|
| 10 |
+
from facefusion.uis.core import get_ui_component
|
| 11 |
+
|
| 12 |
+
JOB_LIST_JOBS_DATAFRAME : Optional[gradio.Dataframe] = None
|
| 13 |
+
JOB_LIST_REFRESH_BUTTON : Optional[gradio.Button] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global JOB_LIST_JOBS_DATAFRAME
|
| 18 |
+
global JOB_LIST_REFRESH_BUTTON
|
| 19 |
+
|
| 20 |
+
if job_manager.init_jobs(state_manager.get_item('jobs_path')):
|
| 21 |
+
job_status = get_first(facefusion.choices.job_statuses)
|
| 22 |
+
job_headers, job_contents = job_list.compose_job_list(job_status)
|
| 23 |
+
|
| 24 |
+
JOB_LIST_JOBS_DATAFRAME = gradio.Dataframe(
|
| 25 |
+
headers = job_headers,
|
| 26 |
+
value = job_contents,
|
| 27 |
+
datatype = [ 'str', 'number', 'date', 'date', 'str' ],
|
| 28 |
+
show_label = False
|
| 29 |
+
)
|
| 30 |
+
JOB_LIST_REFRESH_BUTTON = gradio.Button(
|
| 31 |
+
value = translator.get('uis.refresh_button'),
|
| 32 |
+
variant = 'primary',
|
| 33 |
+
size = 'sm'
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def listen() -> None:
|
| 38 |
+
job_list_job_status_checkbox_group = get_ui_component('job_list_job_status_checkbox_group')
|
| 39 |
+
if job_list_job_status_checkbox_group:
|
| 40 |
+
job_list_job_status_checkbox_group.change(update_job_dataframe, inputs = job_list_job_status_checkbox_group, outputs = JOB_LIST_JOBS_DATAFRAME)
|
| 41 |
+
JOB_LIST_REFRESH_BUTTON.click(update_job_dataframe, inputs = job_list_job_status_checkbox_group, outputs = JOB_LIST_JOBS_DATAFRAME)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def update_job_dataframe(job_statuses : List[JobStatus]) -> gradio.Dataframe:
|
| 45 |
+
all_job_contents = []
|
| 46 |
+
|
| 47 |
+
for job_status in job_statuses:
|
| 48 |
+
_, job_contents = job_list.compose_job_list(job_status)
|
| 49 |
+
all_job_contents.extend(job_contents)
|
| 50 |
+
return gradio.Dataframe(value = all_job_contents)
|
uis/components/job_list_options.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.common_helper import get_first
|
| 8 |
+
from facefusion.jobs import job_manager
|
| 9 |
+
from facefusion.types import JobStatus
|
| 10 |
+
from facefusion.uis.core import register_ui_component
|
| 11 |
+
|
| 12 |
+
JOB_LIST_JOB_STATUS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def render() -> None:
|
| 16 |
+
global JOB_LIST_JOB_STATUS_CHECKBOX_GROUP
|
| 17 |
+
|
| 18 |
+
if job_manager.init_jobs(state_manager.get_item('jobs_path')):
|
| 19 |
+
job_status = get_first(facefusion.choices.job_statuses)
|
| 20 |
+
|
| 21 |
+
JOB_LIST_JOB_STATUS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 22 |
+
label = translator.get('uis.job_list_status_checkbox_group'),
|
| 23 |
+
choices = facefusion.choices.job_statuses,
|
| 24 |
+
value = job_status
|
| 25 |
+
)
|
| 26 |
+
register_ui_component('job_list_job_status_checkbox_group', JOB_LIST_JOB_STATUS_CHECKBOX_GROUP)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def listen() -> None:
|
| 30 |
+
JOB_LIST_JOB_STATUS_CHECKBOX_GROUP.change(update_job_status_checkbox_group, inputs = JOB_LIST_JOB_STATUS_CHECKBOX_GROUP, outputs = JOB_LIST_JOB_STATUS_CHECKBOX_GROUP)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def update_job_status_checkbox_group(job_statuses : List[JobStatus]) -> gradio.CheckboxGroup:
|
| 34 |
+
job_statuses = job_statuses or facefusion.choices.job_statuses
|
| 35 |
+
return gradio.CheckboxGroup(value = job_statuses)
|
uis/components/job_manager.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import logger, state_manager, translator
|
| 6 |
+
from facefusion.args import collect_step_args
|
| 7 |
+
from facefusion.common_helper import get_first, get_last
|
| 8 |
+
from facefusion.filesystem import is_directory
|
| 9 |
+
from facefusion.jobs import job_manager
|
| 10 |
+
from facefusion.types import UiWorkflow
|
| 11 |
+
from facefusion.uis import choices as uis_choices
|
| 12 |
+
from facefusion.uis.core import get_ui_component
|
| 13 |
+
from facefusion.uis.types import JobManagerAction
|
| 14 |
+
from facefusion.uis.ui_helper import convert_int_none, convert_str_none, suggest_output_path
|
| 15 |
+
|
| 16 |
+
JOB_MANAGER_WRAPPER : Optional[gradio.Column] = None
|
| 17 |
+
JOB_MANAGER_JOB_ACTION_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 18 |
+
JOB_MANAGER_JOB_ID_TEXTBOX : Optional[gradio.Textbox] = None
|
| 19 |
+
JOB_MANAGER_JOB_ID_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 20 |
+
JOB_MANAGER_STEP_INDEX_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 21 |
+
JOB_MANAGER_APPLY_BUTTON : Optional[gradio.Button] = None
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def render() -> None:
|
| 25 |
+
global JOB_MANAGER_WRAPPER
|
| 26 |
+
global JOB_MANAGER_JOB_ACTION_DROPDOWN
|
| 27 |
+
global JOB_MANAGER_JOB_ID_TEXTBOX
|
| 28 |
+
global JOB_MANAGER_JOB_ID_DROPDOWN
|
| 29 |
+
global JOB_MANAGER_STEP_INDEX_DROPDOWN
|
| 30 |
+
global JOB_MANAGER_APPLY_BUTTON
|
| 31 |
+
|
| 32 |
+
if job_manager.init_jobs(state_manager.get_item('jobs_path')):
|
| 33 |
+
is_job_manager = state_manager.get_item('ui_workflow') == 'job_manager'
|
| 34 |
+
drafted_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
|
| 35 |
+
|
| 36 |
+
with gradio.Column(visible = is_job_manager) as JOB_MANAGER_WRAPPER:
|
| 37 |
+
JOB_MANAGER_JOB_ACTION_DROPDOWN = gradio.Dropdown(
|
| 38 |
+
label = translator.get('uis.job_manager_job_action_dropdown'),
|
| 39 |
+
choices = uis_choices.job_manager_actions,
|
| 40 |
+
value = get_first(uis_choices.job_manager_actions)
|
| 41 |
+
)
|
| 42 |
+
JOB_MANAGER_JOB_ID_TEXTBOX = gradio.Textbox(
|
| 43 |
+
label = translator.get('uis.job_manager_job_id_dropdown'),
|
| 44 |
+
max_lines = 1,
|
| 45 |
+
interactive = True
|
| 46 |
+
)
|
| 47 |
+
JOB_MANAGER_JOB_ID_DROPDOWN = gradio.Dropdown(
|
| 48 |
+
label = translator.get('uis.job_manager_job_id_dropdown'),
|
| 49 |
+
choices = drafted_job_ids,
|
| 50 |
+
value = get_last(drafted_job_ids),
|
| 51 |
+
interactive = True,
|
| 52 |
+
visible = False
|
| 53 |
+
)
|
| 54 |
+
JOB_MANAGER_STEP_INDEX_DROPDOWN = gradio.Dropdown(
|
| 55 |
+
label = translator.get('uis.job_manager_step_index_dropdown'),
|
| 56 |
+
choices = [ 'none' ],
|
| 57 |
+
value = 'none',
|
| 58 |
+
interactive = True,
|
| 59 |
+
visible = False
|
| 60 |
+
)
|
| 61 |
+
JOB_MANAGER_APPLY_BUTTON = gradio.Button(
|
| 62 |
+
value = translator.get('uis.apply_button'),
|
| 63 |
+
variant = 'primary',
|
| 64 |
+
size = 'sm'
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def listen() -> None:
|
| 69 |
+
JOB_MANAGER_JOB_ACTION_DROPDOWN.change(update, inputs = [ JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_DROPDOWN ], outputs = [ JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ])
|
| 70 |
+
JOB_MANAGER_JOB_ID_DROPDOWN.change(update_step_index, inputs = JOB_MANAGER_JOB_ID_DROPDOWN, outputs = JOB_MANAGER_STEP_INDEX_DROPDOWN)
|
| 71 |
+
JOB_MANAGER_APPLY_BUTTON.click(apply, inputs = [ JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ], outputs = [ JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ])
|
| 72 |
+
|
| 73 |
+
ui_workflow_dropdown = get_ui_component('ui_workflow_dropdown')
|
| 74 |
+
if ui_workflow_dropdown:
|
| 75 |
+
ui_workflow_dropdown.change(remote_update, inputs = ui_workflow_dropdown, outputs = [ JOB_MANAGER_WRAPPER, JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ])
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def remote_update(ui_workflow : UiWorkflow) -> Tuple[gradio.Row, gradio.Dropdown, gradio.Textbox, gradio.Dropdown, gradio.Dropdown]:
|
| 79 |
+
is_job_manager = ui_workflow == 'job_manager'
|
| 80 |
+
return gradio.Row(visible = is_job_manager), gradio.Dropdown(value = get_first(uis_choices.job_manager_actions)), gradio.Textbox(value = None, visible = True), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def apply(job_action : JobManagerAction, created_job_id : str, selected_job_id : str, selected_step_index : int) -> Tuple[gradio.Dropdown, gradio.Textbox, gradio.Dropdown, gradio.Dropdown]:
|
| 84 |
+
created_job_id = convert_str_none(created_job_id)
|
| 85 |
+
selected_job_id = convert_str_none(selected_job_id)
|
| 86 |
+
selected_step_index = convert_int_none(selected_step_index)
|
| 87 |
+
step_args = collect_step_args()
|
| 88 |
+
output_path = step_args.get('output_path')
|
| 89 |
+
|
| 90 |
+
if is_directory(step_args.get('output_path')):
|
| 91 |
+
step_args['output_path'] = suggest_output_path(step_args.get('output_path'), state_manager.get_item('target_path'))
|
| 92 |
+
|
| 93 |
+
if job_action == 'job-create':
|
| 94 |
+
if created_job_id and job_manager.create_job(created_job_id):
|
| 95 |
+
updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
|
| 96 |
+
|
| 97 |
+
logger.info(translator.get('job_created').format(job_id = created_job_id), __name__)
|
| 98 |
+
return gradio.Dropdown(value = 'job-add-step'), gradio.Textbox(visible = False), gradio.Dropdown(value = created_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown()
|
| 99 |
+
else:
|
| 100 |
+
logger.error(translator.get('job_not_created').format(job_id = created_job_id), __name__)
|
| 101 |
+
|
| 102 |
+
if job_action == 'job-submit':
|
| 103 |
+
if selected_job_id and job_manager.submit_job(selected_job_id):
|
| 104 |
+
updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
|
| 105 |
+
|
| 106 |
+
logger.info(translator.get('job_submitted').format(job_id = selected_job_id), __name__)
|
| 107 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True), gradio.Dropdown()
|
| 108 |
+
else:
|
| 109 |
+
logger.error(translator.get('job_not_submitted').format(job_id = selected_job_id), __name__)
|
| 110 |
+
|
| 111 |
+
if job_action == 'job-delete':
|
| 112 |
+
if selected_job_id and job_manager.delete_job(selected_job_id):
|
| 113 |
+
updated_job_ids = job_manager.find_job_ids('drafted') + job_manager.find_job_ids('queued') + job_manager.find_job_ids('failed') + job_manager.find_job_ids('completed') or [ 'none' ]
|
| 114 |
+
|
| 115 |
+
logger.info(translator.get('job_deleted').format(job_id = selected_job_id), __name__)
|
| 116 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True), gradio.Dropdown()
|
| 117 |
+
else:
|
| 118 |
+
logger.error(translator.get('job_not_deleted').format(job_id = selected_job_id), __name__)
|
| 119 |
+
|
| 120 |
+
if job_action == 'job-add-step':
|
| 121 |
+
if selected_job_id and job_manager.add_step(selected_job_id, step_args):
|
| 122 |
+
state_manager.set_item('output_path', output_path)
|
| 123 |
+
logger.info(translator.get('job_step_added').format(job_id = selected_job_id), __name__)
|
| 124 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(visible = False)
|
| 125 |
+
else:
|
| 126 |
+
state_manager.set_item('output_path', output_path)
|
| 127 |
+
logger.error(translator.get('job_step_not_added').format(job_id = selected_job_id), __name__)
|
| 128 |
+
|
| 129 |
+
if job_action == 'job-remix-step':
|
| 130 |
+
if selected_job_id and job_manager.has_step(selected_job_id, selected_step_index) and job_manager.remix_step(selected_job_id, selected_step_index, step_args):
|
| 131 |
+
updated_step_choices = get_step_choices(selected_job_id) or [ 'none' ] #type:ignore[list-item]
|
| 132 |
+
|
| 133 |
+
state_manager.set_item('output_path', output_path)
|
| 134 |
+
logger.info(translator.get('job_remix_step_added').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
|
| 135 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
|
| 136 |
+
else:
|
| 137 |
+
state_manager.set_item('output_path', output_path)
|
| 138 |
+
logger.error(translator.get('job_remix_step_not_added').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
|
| 139 |
+
|
| 140 |
+
if job_action == 'job-insert-step':
|
| 141 |
+
if selected_job_id and job_manager.has_step(selected_job_id, selected_step_index) and job_manager.insert_step(selected_job_id, selected_step_index, step_args):
|
| 142 |
+
updated_step_choices = get_step_choices(selected_job_id) or [ 'none' ] #type:ignore[list-item]
|
| 143 |
+
|
| 144 |
+
state_manager.set_item('output_path', output_path)
|
| 145 |
+
logger.info(translator.get('job_step_inserted').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
|
| 146 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
|
| 147 |
+
else:
|
| 148 |
+
state_manager.set_item('output_path', output_path)
|
| 149 |
+
logger.error(translator.get('job_step_not_inserted').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
|
| 150 |
+
|
| 151 |
+
if job_action == 'job-remove-step':
|
| 152 |
+
if selected_job_id and job_manager.has_step(selected_job_id, selected_step_index) and job_manager.remove_step(selected_job_id, selected_step_index):
|
| 153 |
+
updated_step_choices = get_step_choices(selected_job_id) or [ 'none' ] #type:ignore[list-item]
|
| 154 |
+
|
| 155 |
+
logger.info(translator.get('job_step_removed').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
|
| 156 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
|
| 157 |
+
else:
|
| 158 |
+
logger.error(translator.get('job_step_not_removed').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
|
| 159 |
+
return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(), gradio.Dropdown()
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def get_step_choices(job_id : str) -> List[int]:
|
| 163 |
+
steps = job_manager.get_steps(job_id)
|
| 164 |
+
return [ index for index, _ in enumerate(steps) ]
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def update(job_action : JobManagerAction, selected_job_id : str) -> Tuple[gradio.Textbox, gradio.Dropdown, gradio.Dropdown]:
|
| 168 |
+
if job_action == 'job-create':
|
| 169 |
+
return gradio.Textbox(value = None, visible = True), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False)
|
| 170 |
+
|
| 171 |
+
if job_action == 'job-delete':
|
| 172 |
+
updated_job_ids = job_manager.find_job_ids('drafted') + job_manager.find_job_ids('queued') + job_manager.find_job_ids('failed') + job_manager.find_job_ids('completed') or [ 'none' ]
|
| 173 |
+
updated_job_id = selected_job_id if selected_job_id in updated_job_ids else get_last(updated_job_ids)
|
| 174 |
+
|
| 175 |
+
return gradio.Textbox(visible = False), gradio.Dropdown(value = updated_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown(visible = False)
|
| 176 |
+
|
| 177 |
+
if job_action in [ 'job-submit', 'job-add-step' ]:
|
| 178 |
+
updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
|
| 179 |
+
updated_job_id = selected_job_id if selected_job_id in updated_job_ids else get_last(updated_job_ids)
|
| 180 |
+
|
| 181 |
+
return gradio.Textbox(visible = False), gradio.Dropdown(value = updated_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown(visible = False)
|
| 182 |
+
|
| 183 |
+
if job_action in [ 'job-remix-step', 'job-insert-step', 'job-remove-step' ]:
|
| 184 |
+
updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
|
| 185 |
+
updated_job_id = selected_job_id if selected_job_id in updated_job_ids else get_last(updated_job_ids)
|
| 186 |
+
updated_step_choices = get_step_choices(updated_job_id) or [ 'none' ] #type:ignore[list-item]
|
| 187 |
+
|
| 188 |
+
return gradio.Textbox(visible = False), gradio.Dropdown(value = updated_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
|
| 189 |
+
return gradio.Textbox(visible = False), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False)
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
def update_step_index(job_id : str) -> gradio.Dropdown:
|
| 193 |
+
step_choices = get_step_choices(job_id) or [ 'none' ] #type:ignore[list-item]
|
| 194 |
+
return gradio.Dropdown(value = get_last(step_choices), choices = step_choices)
|
uis/components/job_runner.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from time import sleep
|
| 2 |
+
from typing import Optional, Tuple
|
| 3 |
+
|
| 4 |
+
import gradio
|
| 5 |
+
|
| 6 |
+
from facefusion import logger, process_manager, state_manager, translator
|
| 7 |
+
from facefusion.common_helper import get_first, get_last
|
| 8 |
+
from facefusion.core import process_step
|
| 9 |
+
from facefusion.jobs import job_manager, job_runner, job_store
|
| 10 |
+
from facefusion.types import UiWorkflow
|
| 11 |
+
from facefusion.uis import choices as uis_choices
|
| 12 |
+
from facefusion.uis.core import get_ui_component
|
| 13 |
+
from facefusion.uis.types import JobRunnerAction
|
| 14 |
+
from facefusion.uis.ui_helper import convert_str_none
|
| 15 |
+
|
| 16 |
+
JOB_RUNNER_WRAPPER : Optional[gradio.Column] = None
|
| 17 |
+
JOB_RUNNER_JOB_ACTION_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 18 |
+
JOB_RUNNER_JOB_ID_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 19 |
+
JOB_RUNNER_START_BUTTON : Optional[gradio.Button] = None
|
| 20 |
+
JOB_RUNNER_STOP_BUTTON : Optional[gradio.Button] = None
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def render() -> None:
|
| 24 |
+
global JOB_RUNNER_WRAPPER
|
| 25 |
+
global JOB_RUNNER_JOB_ACTION_DROPDOWN
|
| 26 |
+
global JOB_RUNNER_JOB_ID_DROPDOWN
|
| 27 |
+
global JOB_RUNNER_START_BUTTON
|
| 28 |
+
global JOB_RUNNER_STOP_BUTTON
|
| 29 |
+
|
| 30 |
+
if job_manager.init_jobs(state_manager.get_item('jobs_path')):
|
| 31 |
+
is_job_runner = state_manager.get_item('ui_workflow') == 'job_runner'
|
| 32 |
+
queued_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
|
| 33 |
+
|
| 34 |
+
with gradio.Column(visible = is_job_runner) as JOB_RUNNER_WRAPPER:
|
| 35 |
+
JOB_RUNNER_JOB_ACTION_DROPDOWN = gradio.Dropdown(
|
| 36 |
+
label = translator.get('uis.job_runner_job_action_dropdown'),
|
| 37 |
+
choices = uis_choices.job_runner_actions,
|
| 38 |
+
value = get_first(uis_choices.job_runner_actions)
|
| 39 |
+
)
|
| 40 |
+
JOB_RUNNER_JOB_ID_DROPDOWN = gradio.Dropdown(
|
| 41 |
+
label = translator.get('uis.job_runner_job_id_dropdown'),
|
| 42 |
+
choices = queued_job_ids,
|
| 43 |
+
value = get_last(queued_job_ids)
|
| 44 |
+
)
|
| 45 |
+
with gradio.Row():
|
| 46 |
+
JOB_RUNNER_START_BUTTON = gradio.Button(
|
| 47 |
+
value = translator.get('uis.start_button'),
|
| 48 |
+
variant = 'primary',
|
| 49 |
+
size = 'sm'
|
| 50 |
+
)
|
| 51 |
+
JOB_RUNNER_STOP_BUTTON = gradio.Button(
|
| 52 |
+
value = translator.get('uis.stop_button'),
|
| 53 |
+
variant = 'primary',
|
| 54 |
+
size = 'sm',
|
| 55 |
+
visible = False
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def listen() -> None:
|
| 60 |
+
JOB_RUNNER_JOB_ACTION_DROPDOWN.change(update_job_action, inputs = JOB_RUNNER_JOB_ACTION_DROPDOWN, outputs = JOB_RUNNER_JOB_ID_DROPDOWN)
|
| 61 |
+
JOB_RUNNER_START_BUTTON.click(start, outputs = [ JOB_RUNNER_START_BUTTON, JOB_RUNNER_STOP_BUTTON ])
|
| 62 |
+
JOB_RUNNER_START_BUTTON.click(run, inputs = [ JOB_RUNNER_JOB_ACTION_DROPDOWN, JOB_RUNNER_JOB_ID_DROPDOWN ], outputs = [ JOB_RUNNER_START_BUTTON, JOB_RUNNER_STOP_BUTTON, JOB_RUNNER_JOB_ID_DROPDOWN ])
|
| 63 |
+
JOB_RUNNER_STOP_BUTTON.click(stop, outputs = [ JOB_RUNNER_START_BUTTON, JOB_RUNNER_STOP_BUTTON ])
|
| 64 |
+
|
| 65 |
+
ui_workflow_dropdown = get_ui_component('ui_workflow_dropdown')
|
| 66 |
+
if ui_workflow_dropdown:
|
| 67 |
+
ui_workflow_dropdown.change(remote_update, inputs = ui_workflow_dropdown, outputs = [ JOB_RUNNER_WRAPPER, JOB_RUNNER_JOB_ACTION_DROPDOWN, JOB_RUNNER_JOB_ID_DROPDOWN ])
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def remote_update(ui_workflow : UiWorkflow) -> Tuple[gradio.Row, gradio.Dropdown, gradio.Dropdown]:
|
| 71 |
+
is_job_runner = ui_workflow == 'job_runner'
|
| 72 |
+
queued_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
|
| 73 |
+
|
| 74 |
+
return gradio.Row(visible = is_job_runner), gradio.Dropdown(value = get_first(uis_choices.job_runner_actions), choices = uis_choices.job_runner_actions), gradio.Dropdown(value = get_last(queued_job_ids), choices = queued_job_ids)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def start() -> Tuple[gradio.Button, gradio.Button]:
|
| 78 |
+
while not process_manager.is_processing():
|
| 79 |
+
sleep(0.5)
|
| 80 |
+
return gradio.Button(visible = False), gradio.Button(visible = True)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def run(job_action : JobRunnerAction, job_id : str) -> Tuple[gradio.Button, gradio.Button, gradio.Dropdown]:
|
| 84 |
+
job_id = convert_str_none(job_id)
|
| 85 |
+
|
| 86 |
+
for key in job_store.get_job_keys():
|
| 87 |
+
state_manager.sync_item(key) #type:ignore[arg-type]
|
| 88 |
+
|
| 89 |
+
if job_action == 'job-run':
|
| 90 |
+
logger.info(translator.get('running_job').format(job_id = job_id), __name__)
|
| 91 |
+
if job_id and job_runner.run_job(job_id, process_step):
|
| 92 |
+
logger.info(translator.get('processing_job_succeeded').format(job_id = job_id), __name__)
|
| 93 |
+
else:
|
| 94 |
+
logger.info(translator.get('processing_job_failed').format(job_id = job_id), __name__)
|
| 95 |
+
updated_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
|
| 96 |
+
|
| 97 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids)
|
| 98 |
+
|
| 99 |
+
if job_action == 'job-run-all':
|
| 100 |
+
logger.info(translator.get('running_jobs'), __name__)
|
| 101 |
+
halt_on_error = False
|
| 102 |
+
if job_runner.run_jobs(process_step, halt_on_error):
|
| 103 |
+
logger.info(translator.get('processing_jobs_succeeded'), __name__)
|
| 104 |
+
else:
|
| 105 |
+
logger.info(translator.get('processing_jobs_failed'), __name__)
|
| 106 |
+
|
| 107 |
+
if job_action == 'job-retry':
|
| 108 |
+
logger.info(translator.get('retrying_job').format(job_id = job_id), __name__)
|
| 109 |
+
if job_id and job_runner.retry_job(job_id, process_step):
|
| 110 |
+
logger.info(translator.get('processing_job_succeeded').format(job_id = job_id), __name__)
|
| 111 |
+
else:
|
| 112 |
+
logger.info(translator.get('processing_job_failed').format(job_id = job_id), __name__)
|
| 113 |
+
updated_job_ids = job_manager.find_job_ids('failed') or [ 'none' ]
|
| 114 |
+
|
| 115 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids)
|
| 116 |
+
|
| 117 |
+
if job_action == 'job-retry-all':
|
| 118 |
+
logger.info(translator.get('retrying_jobs'), __name__)
|
| 119 |
+
halt_on_error = False
|
| 120 |
+
if job_runner.retry_jobs(process_step, halt_on_error):
|
| 121 |
+
logger.info(translator.get('processing_jobs_succeeded'), __name__)
|
| 122 |
+
else:
|
| 123 |
+
logger.info(translator.get('processing_jobs_failed'), __name__)
|
| 124 |
+
return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Dropdown()
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def stop() -> Tuple[gradio.Button, gradio.Button]:
|
| 128 |
+
process_manager.stop()
|
| 129 |
+
return gradio.Button(visible = True), gradio.Button(visible = False)
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def update_job_action(job_action : JobRunnerAction) -> gradio.Dropdown:
|
| 133 |
+
if job_action == 'job-run':
|
| 134 |
+
updated_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
|
| 135 |
+
|
| 136 |
+
return gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True)
|
| 137 |
+
|
| 138 |
+
if job_action == 'job-retry':
|
| 139 |
+
updated_job_ids = job_manager.find_job_ids('failed') or [ 'none' ]
|
| 140 |
+
|
| 141 |
+
return gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True)
|
| 142 |
+
return gradio.Dropdown(visible = False)
|
uis/components/lip_syncer_options.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import calculate_float_step
|
| 7 |
+
from facefusion.processors.core import load_processor_module
|
| 8 |
+
from facefusion.processors.modules.lip_syncer import choices as lip_syncer_choices
|
| 9 |
+
from facefusion.processors.modules.lip_syncer.types import LipSyncerModel, LipSyncerWeight
|
| 10 |
+
from facefusion.uis.core import get_ui_component, register_ui_component
|
| 11 |
+
|
| 12 |
+
LIP_SYNCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 13 |
+
LIP_SYNCER_WEIGHT_SLIDER : Optional[gradio.Slider] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global LIP_SYNCER_MODEL_DROPDOWN
|
| 18 |
+
global LIP_SYNCER_WEIGHT_SLIDER
|
| 19 |
+
|
| 20 |
+
has_lip_syncer = 'lip_syncer' in state_manager.get_item('processors')
|
| 21 |
+
LIP_SYNCER_MODEL_DROPDOWN = gradio.Dropdown(
|
| 22 |
+
label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.lip_syncer'),
|
| 23 |
+
choices = lip_syncer_choices.lip_syncer_models,
|
| 24 |
+
value = state_manager.get_item('lip_syncer_model'),
|
| 25 |
+
visible = has_lip_syncer
|
| 26 |
+
)
|
| 27 |
+
LIP_SYNCER_WEIGHT_SLIDER = gradio.Slider(
|
| 28 |
+
label = translator.get('uis.weight_slider', 'facefusion.processors.modules.lip_syncer'),
|
| 29 |
+
value = state_manager.get_item('lip_syncer_weight'),
|
| 30 |
+
step = calculate_float_step(lip_syncer_choices.lip_syncer_weight_range),
|
| 31 |
+
minimum = lip_syncer_choices.lip_syncer_weight_range[0],
|
| 32 |
+
maximum = lip_syncer_choices.lip_syncer_weight_range[-1],
|
| 33 |
+
visible = has_lip_syncer
|
| 34 |
+
)
|
| 35 |
+
register_ui_component('lip_syncer_model_dropdown', LIP_SYNCER_MODEL_DROPDOWN)
|
| 36 |
+
register_ui_component('lip_syncer_weight_slider', LIP_SYNCER_WEIGHT_SLIDER)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def listen() -> None:
|
| 40 |
+
LIP_SYNCER_MODEL_DROPDOWN.change(update_lip_syncer_model, inputs = LIP_SYNCER_MODEL_DROPDOWN, outputs = LIP_SYNCER_MODEL_DROPDOWN)
|
| 41 |
+
LIP_SYNCER_WEIGHT_SLIDER.release(update_lip_syncer_weight, inputs = LIP_SYNCER_WEIGHT_SLIDER)
|
| 42 |
+
|
| 43 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 44 |
+
if processors_checkbox_group:
|
| 45 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ LIP_SYNCER_MODEL_DROPDOWN, LIP_SYNCER_WEIGHT_SLIDER ])
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
|
| 49 |
+
has_lip_syncer = 'lip_syncer' in processors
|
| 50 |
+
return gradio.Dropdown(visible = has_lip_syncer), gradio.Slider(visible = has_lip_syncer)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def update_lip_syncer_model(lip_syncer_model : LipSyncerModel) -> gradio.Dropdown:
|
| 54 |
+
lip_syncer_module = load_processor_module('lip_syncer')
|
| 55 |
+
lip_syncer_module.clear_inference_pool()
|
| 56 |
+
state_manager.set_item('lip_syncer_model', lip_syncer_model)
|
| 57 |
+
|
| 58 |
+
if lip_syncer_module.pre_check():
|
| 59 |
+
return gradio.Dropdown(value = state_manager.get_item('lip_syncer_model'))
|
| 60 |
+
return gradio.Dropdown()
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def update_lip_syncer_weight(lip_syncer_weight : LipSyncerWeight) -> None:
|
| 64 |
+
state_manager.set_item('lip_syncer_weight', lip_syncer_weight)
|
uis/components/memory.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.types import VideoMemoryStrategy
|
| 8 |
+
|
| 9 |
+
VIDEO_MEMORY_STRATEGY_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def render() -> None:
|
| 13 |
+
global VIDEO_MEMORY_STRATEGY_DROPDOWN
|
| 14 |
+
|
| 15 |
+
VIDEO_MEMORY_STRATEGY_DROPDOWN = gradio.Dropdown(
|
| 16 |
+
label = translator.get('uis.video_memory_strategy_dropdown'),
|
| 17 |
+
choices = facefusion.choices.video_memory_strategies,
|
| 18 |
+
value = state_manager.get_item('video_memory_strategy')
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def listen() -> None:
|
| 23 |
+
VIDEO_MEMORY_STRATEGY_DROPDOWN.change(update_video_memory_strategy, inputs = VIDEO_MEMORY_STRATEGY_DROPDOWN)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def update_video_memory_strategy(video_memory_strategy : VideoMemoryStrategy) -> None:
|
| 27 |
+
state_manager.set_item('video_memory_strategy', video_memory_strategy)
|
uis/components/output.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import tempfile
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from typing import Optional
|
| 4 |
+
|
| 5 |
+
import gradio
|
| 6 |
+
|
| 7 |
+
from facefusion import state_manager, translator
|
| 8 |
+
from facefusion.uis.core import register_ui_component
|
| 9 |
+
|
| 10 |
+
OUTPUT_PATH_TEXTBOX : Optional[gradio.Textbox] = None
|
| 11 |
+
OUTPUT_IMAGE : Optional[gradio.Image] = None
|
| 12 |
+
OUTPUT_VIDEO : Optional[gradio.Video] = None
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def render() -> None:
|
| 16 |
+
global OUTPUT_PATH_TEXTBOX
|
| 17 |
+
global OUTPUT_IMAGE
|
| 18 |
+
global OUTPUT_VIDEO
|
| 19 |
+
|
| 20 |
+
if not state_manager.get_item('output_path'):
|
| 21 |
+
documents_directory = Path.home().joinpath('Documents')
|
| 22 |
+
|
| 23 |
+
if documents_directory.exists():
|
| 24 |
+
state_manager.set_item('output_path', documents_directory)
|
| 25 |
+
else:
|
| 26 |
+
state_manager.set_item('output_path', tempfile.gettempdir())
|
| 27 |
+
OUTPUT_PATH_TEXTBOX = gradio.Textbox(
|
| 28 |
+
label = translator.get('uis.output_path_textbox'),
|
| 29 |
+
value = state_manager.get_item('output_path'),
|
| 30 |
+
max_lines = 1
|
| 31 |
+
)
|
| 32 |
+
OUTPUT_IMAGE = gradio.Image(
|
| 33 |
+
label = translator.get('uis.output_image_or_video'),
|
| 34 |
+
visible = False
|
| 35 |
+
)
|
| 36 |
+
OUTPUT_VIDEO = gradio.Video(
|
| 37 |
+
label = translator.get('uis.output_image_or_video')
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def listen() -> None:
|
| 42 |
+
OUTPUT_PATH_TEXTBOX.change(update_output_path, inputs = OUTPUT_PATH_TEXTBOX)
|
| 43 |
+
register_ui_component('output_image', OUTPUT_IMAGE)
|
| 44 |
+
register_ui_component('output_video', OUTPUT_VIDEO)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def update_output_path(output_path : str) -> None:
|
| 48 |
+
state_manager.set_item('output_path', output_path)
|
uis/components/output_options.py
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.common_helper import calculate_float_step, calculate_int_step
|
| 8 |
+
from facefusion.ffmpeg import get_available_encoder_set
|
| 9 |
+
from facefusion.filesystem import is_image, is_video
|
| 10 |
+
from facefusion.types import AudioEncoder, Fps, Scale, VideoEncoder, VideoPreset
|
| 11 |
+
from facefusion.uis.core import get_ui_components, register_ui_component
|
| 12 |
+
from facefusion.vision import detect_video_fps
|
| 13 |
+
|
| 14 |
+
OUTPUT_IMAGE_QUALITY_SLIDER : Optional[gradio.Slider] = None
|
| 15 |
+
OUTPUT_IMAGE_SCALE_SLIDER : Optional[gradio.Slider] = None
|
| 16 |
+
OUTPUT_AUDIO_ENCODER_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 17 |
+
OUTPUT_AUDIO_QUALITY_SLIDER : Optional[gradio.Slider] = None
|
| 18 |
+
OUTPUT_AUDIO_VOLUME_SLIDER : Optional[gradio.Slider] = None
|
| 19 |
+
OUTPUT_VIDEO_ENCODER_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 20 |
+
OUTPUT_VIDEO_PRESET_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 21 |
+
OUTPUT_VIDEO_SCALE_SLIDER : Optional[gradio.Slider] = None
|
| 22 |
+
OUTPUT_VIDEO_QUALITY_SLIDER : Optional[gradio.Slider] = None
|
| 23 |
+
OUTPUT_VIDEO_FPS_SLIDER : Optional[gradio.Slider] = None
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def render() -> None:
|
| 27 |
+
global OUTPUT_IMAGE_QUALITY_SLIDER
|
| 28 |
+
global OUTPUT_IMAGE_SCALE_SLIDER
|
| 29 |
+
global OUTPUT_AUDIO_ENCODER_DROPDOWN
|
| 30 |
+
global OUTPUT_AUDIO_QUALITY_SLIDER
|
| 31 |
+
global OUTPUT_AUDIO_VOLUME_SLIDER
|
| 32 |
+
global OUTPUT_VIDEO_ENCODER_DROPDOWN
|
| 33 |
+
global OUTPUT_VIDEO_PRESET_DROPDOWN
|
| 34 |
+
global OUTPUT_VIDEO_SCALE_SLIDER
|
| 35 |
+
global OUTPUT_VIDEO_QUALITY_SLIDER
|
| 36 |
+
global OUTPUT_VIDEO_FPS_SLIDER
|
| 37 |
+
|
| 38 |
+
available_encoder_set = get_available_encoder_set()
|
| 39 |
+
|
| 40 |
+
OUTPUT_IMAGE_QUALITY_SLIDER = gradio.Slider(
|
| 41 |
+
label = translator.get('uis.output_image_quality_slider'),
|
| 42 |
+
value = state_manager.get_item('output_image_quality'),
|
| 43 |
+
step = calculate_int_step(facefusion.choices.output_image_quality_range),
|
| 44 |
+
minimum = facefusion.choices.output_image_quality_range[0],
|
| 45 |
+
maximum = facefusion.choices.output_image_quality_range[-1],
|
| 46 |
+
visible = is_image(state_manager.get_item('target_path'))
|
| 47 |
+
)
|
| 48 |
+
OUTPUT_IMAGE_SCALE_SLIDER = gradio.Slider(
|
| 49 |
+
label = translator.get('uis.output_image_scale_slider'),
|
| 50 |
+
step = calculate_float_step(facefusion.choices.output_image_scale_range),
|
| 51 |
+
value = state_manager.get_item('output_image_scale'),
|
| 52 |
+
minimum = facefusion.choices.output_image_scale_range[0],
|
| 53 |
+
maximum = facefusion.choices.output_image_scale_range[-1],
|
| 54 |
+
visible = is_image(state_manager.get_item('target_path'))
|
| 55 |
+
)
|
| 56 |
+
OUTPUT_AUDIO_ENCODER_DROPDOWN = gradio.Dropdown(
|
| 57 |
+
label = translator.get('uis.output_audio_encoder_dropdown'),
|
| 58 |
+
choices = available_encoder_set.get('audio'),
|
| 59 |
+
value = state_manager.get_item('output_audio_encoder'),
|
| 60 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 61 |
+
)
|
| 62 |
+
OUTPUT_AUDIO_QUALITY_SLIDER = gradio.Slider(
|
| 63 |
+
label = translator.get('uis.output_audio_quality_slider'),
|
| 64 |
+
value = state_manager.get_item('output_audio_quality'),
|
| 65 |
+
step = calculate_int_step(facefusion.choices.output_audio_quality_range),
|
| 66 |
+
minimum = facefusion.choices.output_audio_quality_range[0],
|
| 67 |
+
maximum = facefusion.choices.output_audio_quality_range[-1],
|
| 68 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 69 |
+
)
|
| 70 |
+
OUTPUT_AUDIO_VOLUME_SLIDER = gradio.Slider(
|
| 71 |
+
label = translator.get('uis.output_audio_volume_slider'),
|
| 72 |
+
value = state_manager.get_item('output_audio_volume'),
|
| 73 |
+
step = calculate_int_step(facefusion.choices.output_audio_volume_range),
|
| 74 |
+
minimum = facefusion.choices.output_audio_volume_range[0],
|
| 75 |
+
maximum = facefusion.choices.output_audio_volume_range[-1],
|
| 76 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 77 |
+
)
|
| 78 |
+
OUTPUT_VIDEO_ENCODER_DROPDOWN = gradio.Dropdown(
|
| 79 |
+
label = translator.get('uis.output_video_encoder_dropdown'),
|
| 80 |
+
choices = available_encoder_set.get('video'),
|
| 81 |
+
value = state_manager.get_item('output_video_encoder'),
|
| 82 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 83 |
+
)
|
| 84 |
+
OUTPUT_VIDEO_PRESET_DROPDOWN = gradio.Dropdown(
|
| 85 |
+
label = translator.get('uis.output_video_preset_dropdown'),
|
| 86 |
+
choices = facefusion.choices.output_video_presets,
|
| 87 |
+
value = state_manager.get_item('output_video_preset'),
|
| 88 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 89 |
+
)
|
| 90 |
+
OUTPUT_VIDEO_QUALITY_SLIDER = gradio.Slider(
|
| 91 |
+
label = translator.get('uis.output_video_quality_slider'),
|
| 92 |
+
value = state_manager.get_item('output_video_quality'),
|
| 93 |
+
step = calculate_int_step(facefusion.choices.output_video_quality_range),
|
| 94 |
+
minimum = facefusion.choices.output_video_quality_range[0],
|
| 95 |
+
maximum = facefusion.choices.output_video_quality_range[-1],
|
| 96 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 97 |
+
)
|
| 98 |
+
OUTPUT_VIDEO_SCALE_SLIDER = gradio.Slider(
|
| 99 |
+
label = translator.get('uis.output_video_scale_slider'),
|
| 100 |
+
step = calculate_float_step(facefusion.choices.output_video_scale_range),
|
| 101 |
+
value = state_manager.get_item('output_video_scale'),
|
| 102 |
+
minimum = facefusion.choices.output_video_scale_range[0],
|
| 103 |
+
maximum = facefusion.choices.output_video_scale_range[-1],
|
| 104 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 105 |
+
)
|
| 106 |
+
OUTPUT_VIDEO_FPS_SLIDER = gradio.Slider(
|
| 107 |
+
label = translator.get('uis.output_video_fps_slider'),
|
| 108 |
+
value = state_manager.get_item('output_video_fps'),
|
| 109 |
+
step = 0.01,
|
| 110 |
+
minimum = 1,
|
| 111 |
+
maximum = 60,
|
| 112 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 113 |
+
)
|
| 114 |
+
register_ui_component('output_video_fps_slider', OUTPUT_VIDEO_FPS_SLIDER)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def listen() -> None:
|
| 118 |
+
OUTPUT_IMAGE_QUALITY_SLIDER.release(update_output_image_quality, inputs = OUTPUT_IMAGE_QUALITY_SLIDER)
|
| 119 |
+
OUTPUT_IMAGE_SCALE_SLIDER.release(update_output_image_scale, inputs = OUTPUT_IMAGE_SCALE_SLIDER)
|
| 120 |
+
OUTPUT_AUDIO_ENCODER_DROPDOWN.change(update_output_audio_encoder, inputs = OUTPUT_AUDIO_ENCODER_DROPDOWN)
|
| 121 |
+
OUTPUT_AUDIO_QUALITY_SLIDER.release(update_output_audio_quality, inputs = OUTPUT_AUDIO_QUALITY_SLIDER)
|
| 122 |
+
OUTPUT_AUDIO_VOLUME_SLIDER.release(update_output_audio_volume, inputs = OUTPUT_AUDIO_VOLUME_SLIDER)
|
| 123 |
+
OUTPUT_VIDEO_ENCODER_DROPDOWN.change(update_output_video_encoder, inputs = OUTPUT_VIDEO_ENCODER_DROPDOWN)
|
| 124 |
+
OUTPUT_VIDEO_PRESET_DROPDOWN.change(update_output_video_preset, inputs = OUTPUT_VIDEO_PRESET_DROPDOWN)
|
| 125 |
+
OUTPUT_VIDEO_QUALITY_SLIDER.release(update_output_video_quality, inputs = OUTPUT_VIDEO_QUALITY_SLIDER)
|
| 126 |
+
OUTPUT_VIDEO_SCALE_SLIDER.release(update_output_video_scale, inputs = OUTPUT_VIDEO_SCALE_SLIDER)
|
| 127 |
+
OUTPUT_VIDEO_FPS_SLIDER.release(update_output_video_fps, inputs = OUTPUT_VIDEO_FPS_SLIDER)
|
| 128 |
+
|
| 129 |
+
for ui_component in get_ui_components(
|
| 130 |
+
[
|
| 131 |
+
'target_image',
|
| 132 |
+
'target_video'
|
| 133 |
+
]):
|
| 134 |
+
for method in [ 'change', 'clear' ]:
|
| 135 |
+
getattr(ui_component, method)(remote_update, outputs = [ OUTPUT_IMAGE_QUALITY_SLIDER, OUTPUT_IMAGE_SCALE_SLIDER, OUTPUT_AUDIO_ENCODER_DROPDOWN, OUTPUT_AUDIO_QUALITY_SLIDER, OUTPUT_AUDIO_VOLUME_SLIDER, OUTPUT_VIDEO_ENCODER_DROPDOWN, OUTPUT_VIDEO_PRESET_DROPDOWN, OUTPUT_VIDEO_QUALITY_SLIDER, OUTPUT_VIDEO_SCALE_SLIDER, OUTPUT_VIDEO_FPS_SLIDER ])
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
def remote_update() -> Tuple[gradio.Slider, gradio.Slider, gradio.Dropdown, gradio.Slider, gradio.Slider, gradio.Dropdown, gradio.Dropdown, gradio.Slider, gradio.Slider, gradio.Slider]:
|
| 139 |
+
if is_image(state_manager.get_item('target_path')):
|
| 140 |
+
return gradio.Slider(visible = True), gradio.Slider(visible = True), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False)
|
| 141 |
+
if is_video(state_manager.get_item('target_path')):
|
| 142 |
+
state_manager.set_item('output_video_fps', detect_video_fps(state_manager.get_item('target_path')))
|
| 143 |
+
return gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = True), gradio.Slider(visible = True), gradio.Slider(visible = True), gradio.Dropdown(visible = True), gradio.Dropdown(visible = True), gradio.Slider(visible = True), gradio.Slider(visible = True), gradio.Slider(value = state_manager.get_item('output_video_fps'), visible = True)
|
| 144 |
+
return gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def update_output_image_quality(output_image_quality : float) -> None:
|
| 148 |
+
state_manager.set_item('output_image_quality', int(output_image_quality))
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def update_output_image_scale(output_image_scale : Scale) -> None:
|
| 152 |
+
state_manager.set_item('output_image_scale', output_image_scale)
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
def update_output_audio_encoder(output_audio_encoder : AudioEncoder) -> None:
|
| 156 |
+
state_manager.set_item('output_audio_encoder', output_audio_encoder)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def update_output_audio_quality(output_audio_quality : float) -> None:
|
| 160 |
+
state_manager.set_item('output_audio_quality', int(output_audio_quality))
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
def update_output_audio_volume(output_audio_volume: float) -> None:
|
| 164 |
+
state_manager.set_item('output_audio_volume', int(output_audio_volume))
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def update_output_video_encoder(output_video_encoder : VideoEncoder) -> None:
|
| 168 |
+
state_manager.set_item('output_video_encoder', output_video_encoder)
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
def update_output_video_preset(output_video_preset : VideoPreset) -> None:
|
| 172 |
+
state_manager.set_item('output_video_preset', output_video_preset)
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def update_output_video_quality(output_video_quality : float) -> None:
|
| 176 |
+
state_manager.set_item('output_video_quality', int(output_video_quality))
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def update_output_video_scale(output_video_scale : Scale) -> None:
|
| 180 |
+
state_manager.set_item('output_video_scale', output_video_scale)
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def update_output_video_fps(output_video_fps : Fps) -> None:
|
| 184 |
+
state_manager.set_item('output_video_fps', output_video_fps)
|
uis/components/preview.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from time import sleep
|
| 2 |
+
from typing import List, Optional, Tuple
|
| 3 |
+
|
| 4 |
+
import cv2
|
| 5 |
+
import gradio
|
| 6 |
+
import numpy
|
| 7 |
+
|
| 8 |
+
from facefusion import logger, process_manager, state_manager, translator
|
| 9 |
+
from facefusion.audio import create_empty_audio_frame, get_voice_frame
|
| 10 |
+
from facefusion.common_helper import get_first, get_middle
|
| 11 |
+
from facefusion.content_analyser import analyse_frame
|
| 12 |
+
from facefusion.face_creator import get_one_face
|
| 13 |
+
from facefusion.face_selector import select_faces
|
| 14 |
+
from facefusion.face_store import clear_faces
|
| 15 |
+
from facefusion.filesystem import filter_audio_paths, is_image, is_video
|
| 16 |
+
from facefusion.processors.core import get_processors_modules
|
| 17 |
+
from facefusion.types import AudioFrame, Face, Mask, VisionFrame
|
| 18 |
+
from facefusion.uis import choices as uis_choices
|
| 19 |
+
from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
|
| 20 |
+
from facefusion.uis.types import ComponentOptions, PreviewMode
|
| 21 |
+
from facefusion.vision import detect_frame_orientation, extract_vision_mask, fit_cover_frame, is_vision_frame, merge_vision_mask, obscure_frame, read_static_image, read_static_images, read_video_frame, restrict_frame, select_video_frames, unpack_resolution
|
| 22 |
+
|
| 23 |
+
PREVIEW_IMAGE : Optional[gradio.Image] = None
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def render() -> None:
|
| 27 |
+
global PREVIEW_IMAGE
|
| 28 |
+
|
| 29 |
+
preview_image_options : ComponentOptions =\
|
| 30 |
+
{
|
| 31 |
+
'label': translator.get('uis.preview_image')
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
|
| 35 |
+
source_audio_path = get_first(filter_audio_paths(state_manager.get_item('source_paths')))
|
| 36 |
+
source_audio_frame = create_empty_audio_frame()
|
| 37 |
+
source_voice_frame = create_empty_audio_frame()
|
| 38 |
+
|
| 39 |
+
if source_audio_path and state_manager.get_item('output_video_fps'):
|
| 40 |
+
temp_voice_frame = get_voice_frame(source_audio_path, state_manager.get_item('output_video_fps'), state_manager.get_item('reference_frame_number'))
|
| 41 |
+
if numpy.any(temp_voice_frame):
|
| 42 |
+
source_voice_frame = temp_voice_frame
|
| 43 |
+
|
| 44 |
+
if is_image(state_manager.get_item('target_path')):
|
| 45 |
+
target_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
| 46 |
+
reference_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
| 47 |
+
preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, [ target_vision_frame ], uis_choices.preview_modes[0], uis_choices.preview_resolutions[-1])
|
| 48 |
+
preview_image_options['value'] = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGR2RGB)
|
| 49 |
+
preview_image_options['elem_classes'] = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ]
|
| 50 |
+
|
| 51 |
+
if is_video(state_manager.get_item('target_path')):
|
| 52 |
+
reference_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
| 53 |
+
target_vision_frames = select_video_frames(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'), state_manager.get_item('target_frame_amount'))
|
| 54 |
+
preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, target_vision_frames, uis_choices.preview_modes[0], uis_choices.preview_resolutions[-1])
|
| 55 |
+
preview_image_options['value'] = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGR2RGB)
|
| 56 |
+
preview_image_options['elem_classes'] = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ]
|
| 57 |
+
preview_image_options['visible'] = True
|
| 58 |
+
PREVIEW_IMAGE = gradio.Image(**preview_image_options)
|
| 59 |
+
register_ui_component('preview_image', PREVIEW_IMAGE)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def listen() -> None:
|
| 63 |
+
preview_frame_slider = get_ui_component('preview_frame_slider')
|
| 64 |
+
preview_mode_dropdown = get_ui_component('preview_mode_dropdown')
|
| 65 |
+
preview_resolution_dropdown = get_ui_component('preview_resolution_dropdown')
|
| 66 |
+
|
| 67 |
+
if preview_mode_dropdown:
|
| 68 |
+
preview_mode_dropdown.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 69 |
+
|
| 70 |
+
if preview_resolution_dropdown:
|
| 71 |
+
preview_resolution_dropdown.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 72 |
+
|
| 73 |
+
if preview_frame_slider:
|
| 74 |
+
preview_frame_slider.release(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE, show_progress = 'hidden')
|
| 75 |
+
preview_frame_slider.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE, show_progress = 'hidden', trigger_mode = 'once')
|
| 76 |
+
|
| 77 |
+
reference_face_position_gallery = get_ui_component('reference_face_position_gallery')
|
| 78 |
+
if reference_face_position_gallery:
|
| 79 |
+
reference_face_position_gallery.select(clear_and_update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 80 |
+
|
| 81 |
+
for ui_component in get_ui_components(
|
| 82 |
+
[
|
| 83 |
+
'source_audio',
|
| 84 |
+
'source_image',
|
| 85 |
+
'target_image',
|
| 86 |
+
'target_video'
|
| 87 |
+
]):
|
| 88 |
+
for method in [ 'change', 'clear' ]:
|
| 89 |
+
getattr(ui_component, method)(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 90 |
+
|
| 91 |
+
for ui_component in get_ui_components(
|
| 92 |
+
[
|
| 93 |
+
'background_remover_fill_color_red_number',
|
| 94 |
+
'background_remover_fill_color_green_number',
|
| 95 |
+
'background_remover_fill_color_blue_number',
|
| 96 |
+
'background_remover_fill_color_alpha_number',
|
| 97 |
+
'background_remover_despill_color_red_number',
|
| 98 |
+
'background_remover_despill_color_green_number',
|
| 99 |
+
'background_remover_despill_color_blue_number',
|
| 100 |
+
'background_remover_despill_color_alpha_number',
|
| 101 |
+
'face_debugger_items_checkbox_group',
|
| 102 |
+
'frame_colorizer_size_dropdown',
|
| 103 |
+
'face_mask_types_checkbox_group',
|
| 104 |
+
'face_mask_areas_checkbox_group',
|
| 105 |
+
'face_mask_regions_checkbox_group',
|
| 106 |
+
'expression_restorer_areas_checkbox_group'
|
| 107 |
+
]):
|
| 108 |
+
ui_component.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 109 |
+
|
| 110 |
+
for ui_component in get_ui_components(
|
| 111 |
+
[
|
| 112 |
+
'age_modifier_direction_slider',
|
| 113 |
+
'deep_swapper_morph_slider',
|
| 114 |
+
'expression_restorer_factor_slider',
|
| 115 |
+
'face_editor_eyebrow_direction_slider',
|
| 116 |
+
'face_editor_eye_gaze_horizontal_slider',
|
| 117 |
+
'face_editor_eye_gaze_vertical_slider',
|
| 118 |
+
'face_editor_eye_open_ratio_slider',
|
| 119 |
+
'face_editor_lip_open_ratio_slider',
|
| 120 |
+
'face_editor_mouth_grim_slider',
|
| 121 |
+
'face_editor_mouth_pout_slider',
|
| 122 |
+
'face_editor_mouth_purse_slider',
|
| 123 |
+
'face_editor_mouth_smile_slider',
|
| 124 |
+
'face_editor_mouth_position_horizontal_slider',
|
| 125 |
+
'face_editor_mouth_position_vertical_slider',
|
| 126 |
+
'face_editor_head_pitch_slider',
|
| 127 |
+
'face_editor_head_yaw_slider',
|
| 128 |
+
'face_editor_head_roll_slider',
|
| 129 |
+
'face_enhancer_blend_slider',
|
| 130 |
+
'face_enhancer_weight_slider',
|
| 131 |
+
'face_swapper_weight_slider',
|
| 132 |
+
'frame_colorizer_blend_slider',
|
| 133 |
+
'frame_enhancer_blend_slider',
|
| 134 |
+
'lip_syncer_weight_slider',
|
| 135 |
+
'reference_face_distance_slider',
|
| 136 |
+
'face_selector_age_range_slider',
|
| 137 |
+
'face_tracker_score_slider',
|
| 138 |
+
'face_mask_blur_slider',
|
| 139 |
+
'face_mask_padding_top_slider',
|
| 140 |
+
'face_mask_padding_bottom_slider',
|
| 141 |
+
'face_mask_padding_left_slider',
|
| 142 |
+
'face_mask_padding_right_slider',
|
| 143 |
+
'output_video_fps_slider'
|
| 144 |
+
]):
|
| 145 |
+
ui_component.release(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 146 |
+
|
| 147 |
+
for ui_component in get_ui_components(
|
| 148 |
+
[
|
| 149 |
+
'age_modifier_model_dropdown',
|
| 150 |
+
'background_remover_model_dropdown',
|
| 151 |
+
'deep_swapper_model_dropdown',
|
| 152 |
+
'expression_restorer_model_dropdown',
|
| 153 |
+
'processors_checkbox_group',
|
| 154 |
+
'face_editor_model_dropdown',
|
| 155 |
+
'face_enhancer_model_dropdown',
|
| 156 |
+
'face_swapper_model_dropdown',
|
| 157 |
+
'face_swapper_pixel_boost_dropdown',
|
| 158 |
+
'frame_colorizer_model_dropdown',
|
| 159 |
+
'frame_enhancer_model_dropdown',
|
| 160 |
+
'lip_syncer_model_dropdown',
|
| 161 |
+
'face_selector_mode_dropdown',
|
| 162 |
+
'face_selector_order_dropdown',
|
| 163 |
+
'face_selector_gender_dropdown',
|
| 164 |
+
'face_selector_race_dropdown',
|
| 165 |
+
'face_detector_model_dropdown',
|
| 166 |
+
'face_detector_size_dropdown',
|
| 167 |
+
'face_detector_angles_checkbox_group',
|
| 168 |
+
'face_landmarker_model_dropdown',
|
| 169 |
+
'face_occluder_model_dropdown',
|
| 170 |
+
'face_parser_model_dropdown',
|
| 171 |
+
'voice_extractor_model_dropdown'
|
| 172 |
+
]):
|
| 173 |
+
ui_component.change(clear_and_update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 174 |
+
|
| 175 |
+
for ui_component in get_ui_components(
|
| 176 |
+
[
|
| 177 |
+
'face_detector_margin_slider',
|
| 178 |
+
'face_detector_score_slider',
|
| 179 |
+
'face_landmarker_score_slider'
|
| 180 |
+
]):
|
| 181 |
+
ui_component.release(clear_and_update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
def update_preview_image(preview_mode : PreviewMode, preview_resolution : str, frame_number : int = 0) -> gradio.Image:
|
| 185 |
+
while process_manager.is_checking():
|
| 186 |
+
sleep(0.5)
|
| 187 |
+
|
| 188 |
+
source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
|
| 189 |
+
source_audio_path = get_first(filter_audio_paths(state_manager.get_item('source_paths')))
|
| 190 |
+
source_audio_frame = create_empty_audio_frame()
|
| 191 |
+
source_voice_frame = create_empty_audio_frame()
|
| 192 |
+
|
| 193 |
+
if source_audio_path and state_manager.get_item('output_video_fps'):
|
| 194 |
+
audio_frame_number = frame_number
|
| 195 |
+
if state_manager.get_item('trim_frame_start'):
|
| 196 |
+
audio_frame_number -= state_manager.get_item('trim_frame_start')
|
| 197 |
+
temp_voice_frame = get_voice_frame(source_audio_path, state_manager.get_item('output_video_fps'), audio_frame_number)
|
| 198 |
+
if numpy.any(temp_voice_frame):
|
| 199 |
+
source_voice_frame = temp_voice_frame
|
| 200 |
+
|
| 201 |
+
if is_image(state_manager.get_item('target_path')):
|
| 202 |
+
reference_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
| 203 |
+
target_vision_frame = read_static_image(state_manager.get_item('target_path'), 'rgba')
|
| 204 |
+
preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, [ target_vision_frame ], preview_mode, preview_resolution)
|
| 205 |
+
preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
|
| 206 |
+
return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
|
| 207 |
+
|
| 208 |
+
if is_video(state_manager.get_item('target_path')):
|
| 209 |
+
reference_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
| 210 |
+
target_vision_frames = select_video_frames(state_manager.get_item('target_path'), frame_number, state_manager.get_item('target_frame_amount'))
|
| 211 |
+
preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, target_vision_frames, preview_mode, preview_resolution)
|
| 212 |
+
preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
|
| 213 |
+
return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
|
| 214 |
+
return gradio.Image(value = None, elem_classes = None)
|
| 215 |
+
|
| 216 |
+
|
| 217 |
+
def clear_and_update_preview_image(preview_mode : PreviewMode, preview_resolution : str, frame_number : int = 0) -> gradio.Image:
|
| 218 |
+
clear_faces()
|
| 219 |
+
return update_preview_image(preview_mode, preview_resolution, frame_number)
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
def process_preview_frame(reference_vision_frame : VisionFrame, source_vision_frames : List[VisionFrame], source_audio_frame : AudioFrame, source_voice_frame : AudioFrame, target_vision_frames : List[VisionFrame], preview_mode : PreviewMode, preview_resolution : str) -> VisionFrame:
|
| 223 |
+
target_vision_frame = get_middle(target_vision_frames)
|
| 224 |
+
target_vision_frame = restrict_frame(target_vision_frame, unpack_resolution(preview_resolution))
|
| 225 |
+
temp_vision_mask = extract_vision_mask(target_vision_frame)
|
| 226 |
+
target_vision_frame = merge_vision_mask(target_vision_frame, temp_vision_mask)
|
| 227 |
+
target_vision_frames = [ restrict_frame(vision_frame, unpack_resolution(preview_resolution))[:, :, :3] for vision_frame in target_vision_frames ]
|
| 228 |
+
temp_vision_frame = target_vision_frame.copy()
|
| 229 |
+
|
| 230 |
+
if analyse_frame(target_vision_frame[:, :, :3]):
|
| 231 |
+
if preview_mode == 'frame-by-frame':
|
| 232 |
+
temp_vision_frame = obscure_frame(temp_vision_frame[:, :, :3])
|
| 233 |
+
return numpy.hstack((temp_vision_frame, temp_vision_frame))
|
| 234 |
+
|
| 235 |
+
if preview_mode == 'face-by-face':
|
| 236 |
+
target_crop_vision_frame, output_crop_vision_frame = create_face_by_face(reference_vision_frame, source_vision_frames, target_vision_frame[:, :, :3], temp_vision_frame[:, :, :3])
|
| 237 |
+
target_crop_vision_frame = obscure_frame(target_crop_vision_frame)
|
| 238 |
+
output_crop_vision_frame = obscure_frame(output_crop_vision_frame)
|
| 239 |
+
return numpy.hstack((target_crop_vision_frame, output_crop_vision_frame))
|
| 240 |
+
|
| 241 |
+
temp_vision_frame = obscure_frame(temp_vision_frame)
|
| 242 |
+
return temp_vision_frame
|
| 243 |
+
|
| 244 |
+
for processor_module in get_processors_modules(state_manager.get_item('processors')):
|
| 245 |
+
logger.disable()
|
| 246 |
+
if processor_module.pre_process('preview'):
|
| 247 |
+
logger.enable()
|
| 248 |
+
temp_vision_frame, temp_vision_mask = processor_module.process_frame(
|
| 249 |
+
{
|
| 250 |
+
'reference_vision_frame': reference_vision_frame,
|
| 251 |
+
'source_audio_frame': source_audio_frame,
|
| 252 |
+
'source_voice_frame': source_voice_frame,
|
| 253 |
+
'source_vision_frames': source_vision_frames,
|
| 254 |
+
'target_vision_frames': target_vision_frames,
|
| 255 |
+
'temp_vision_frame': temp_vision_frame[:, :, :3],
|
| 256 |
+
'temp_vision_mask': temp_vision_mask
|
| 257 |
+
})
|
| 258 |
+
logger.enable()
|
| 259 |
+
|
| 260 |
+
temp_vision_frame = prepare_output_frame(target_vision_frame, temp_vision_frame, temp_vision_mask)
|
| 261 |
+
|
| 262 |
+
if preview_mode == 'frame-by-frame':
|
| 263 |
+
return numpy.hstack((target_vision_frame, temp_vision_frame))
|
| 264 |
+
|
| 265 |
+
if preview_mode == 'face-by-face':
|
| 266 |
+
target_crop_vision_frame, output_crop_vision_frame = create_face_by_face(reference_vision_frame, source_vision_frames, target_vision_frame, temp_vision_frame)
|
| 267 |
+
return numpy.hstack((target_crop_vision_frame, output_crop_vision_frame))
|
| 268 |
+
|
| 269 |
+
return temp_vision_frame
|
| 270 |
+
|
| 271 |
+
|
| 272 |
+
def create_face_by_face(reference_vision_frame : VisionFrame, source_vision_frames : List[VisionFrame], target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame) -> Tuple[VisionFrame, VisionFrame]:
|
| 273 |
+
target_faces = select_faces(reference_vision_frame[:, :, :3], source_vision_frames, [ target_vision_frame[:, :, :3] ])
|
| 274 |
+
target_face = get_one_face(target_faces)
|
| 275 |
+
|
| 276 |
+
if target_face:
|
| 277 |
+
target_crop_vision_frame = extract_crop_frame(target_vision_frame, target_face)
|
| 278 |
+
output_crop_vision_frame = extract_crop_frame(temp_vision_frame, target_face)
|
| 279 |
+
|
| 280 |
+
if is_vision_frame(target_crop_vision_frame) and is_vision_frame(output_crop_vision_frame):
|
| 281 |
+
target_crop_dimension = min(target_crop_vision_frame.shape[:2])
|
| 282 |
+
target_crop_vision_frame = fit_cover_frame(target_crop_vision_frame, (target_crop_dimension, target_crop_dimension))
|
| 283 |
+
output_crop_vision_frame = fit_cover_frame(output_crop_vision_frame, (target_crop_dimension, target_crop_dimension))
|
| 284 |
+
return target_crop_vision_frame, output_crop_vision_frame
|
| 285 |
+
|
| 286 |
+
empty_vision_frame = numpy.zeros((512, 512, 4), dtype = numpy.uint8)
|
| 287 |
+
return empty_vision_frame, empty_vision_frame
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
def extract_crop_frame(vision_frame : VisionFrame, face : Face) -> Optional[VisionFrame]:
|
| 291 |
+
start_x, start_y, end_x, end_y = map(int, face.bounding_box)
|
| 292 |
+
padding_x = int((end_x - start_x) * 0.25)
|
| 293 |
+
padding_y = int((end_y - start_y) * 0.25)
|
| 294 |
+
start_x = max(0, start_x - padding_x)
|
| 295 |
+
start_y = max(0, start_y - padding_y)
|
| 296 |
+
end_x = max(0, end_x + padding_x)
|
| 297 |
+
end_y = max(0, end_y + padding_y)
|
| 298 |
+
crop_vision_frame = vision_frame[start_y:end_y, start_x:end_x]
|
| 299 |
+
return crop_vision_frame
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
def prepare_output_frame(target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame, temp_vision_mask : Mask) -> VisionFrame:
|
| 303 |
+
temp_vision_mask = temp_vision_mask.clip(state_manager.get_item('background_remover_fill_color')[-1], 255)
|
| 304 |
+
temp_vision_frame = merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
| 305 |
+
temp_vision_frame = cv2.resize(temp_vision_frame, target_vision_frame.shape[1::-1])
|
| 306 |
+
return temp_vision_frame
|
uis/components/preview_options.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.filesystem import is_video
|
| 7 |
+
from facefusion.uis import choices as uis_choices
|
| 8 |
+
from facefusion.uis.core import get_ui_components, register_ui_component
|
| 9 |
+
from facefusion.uis.types import ComponentOptions
|
| 10 |
+
from facefusion.vision import count_video_frame_total
|
| 11 |
+
|
| 12 |
+
PREVIEW_FRAME_SLIDER: Optional[gradio.Slider] = None
|
| 13 |
+
PREVIEW_MODE_DROPDOWN: Optional[gradio.Dropdown] = None
|
| 14 |
+
PREVIEW_RESOLUTION_DROPDOWN: Optional[gradio.Dropdown] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def render() -> None:
|
| 18 |
+
global PREVIEW_FRAME_SLIDER, PREVIEW_MODE_DROPDOWN, PREVIEW_RESOLUTION_DROPDOWN
|
| 19 |
+
|
| 20 |
+
preview_frame_slider_options : ComponentOptions =\
|
| 21 |
+
{
|
| 22 |
+
'label': translator.get('uis.preview_frame_slider'),
|
| 23 |
+
'step': 1,
|
| 24 |
+
'minimum': 0,
|
| 25 |
+
'maximum': 100,
|
| 26 |
+
'visible': False
|
| 27 |
+
}
|
| 28 |
+
if is_video(state_manager.get_item('target_path')):
|
| 29 |
+
video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
|
| 30 |
+
preview_frame_slider_options['value'] = state_manager.get_item('reference_frame_number')
|
| 31 |
+
preview_frame_slider_options['maximum'] = video_frame_total - 1
|
| 32 |
+
preview_frame_slider_options['visible'] = True
|
| 33 |
+
PREVIEW_FRAME_SLIDER = gradio.Slider(**preview_frame_slider_options)
|
| 34 |
+
with gradio.Row():
|
| 35 |
+
PREVIEW_MODE_DROPDOWN = gradio.Dropdown(
|
| 36 |
+
label = translator.get('uis.preview_mode_dropdown'),
|
| 37 |
+
value = uis_choices.preview_modes[0],
|
| 38 |
+
choices = uis_choices.preview_modes,
|
| 39 |
+
visible = True
|
| 40 |
+
)
|
| 41 |
+
PREVIEW_RESOLUTION_DROPDOWN = gradio.Dropdown(
|
| 42 |
+
label = translator.get('uis.preview_resolution_dropdown'),
|
| 43 |
+
value = uis_choices.preview_resolutions[-1],
|
| 44 |
+
choices = uis_choices.preview_resolutions,
|
| 45 |
+
visible = True
|
| 46 |
+
)
|
| 47 |
+
register_ui_component('preview_mode_dropdown', PREVIEW_MODE_DROPDOWN)
|
| 48 |
+
register_ui_component('preview_resolution_dropdown', PREVIEW_RESOLUTION_DROPDOWN)
|
| 49 |
+
register_ui_component('preview_frame_slider', PREVIEW_FRAME_SLIDER)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def listen() -> None:
|
| 53 |
+
for ui_component in get_ui_components([ 'target_image', 'target_video' ]):
|
| 54 |
+
for method in [ 'change', 'clear' ]:
|
| 55 |
+
getattr(ui_component, method)(update_preview_frame_slider, outputs = PREVIEW_FRAME_SLIDER)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def update_preview_frame_slider() -> gradio.Slider:
|
| 59 |
+
if is_video(state_manager.get_item('target_path')):
|
| 60 |
+
video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
|
| 61 |
+
return gradio.Slider(maximum = video_frame_total - 1, visible = True)
|
| 62 |
+
return gradio.Slider(value = 0, visible = False)
|
uis/components/processors.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.filesystem import get_file_name, resolve_file_paths
|
| 7 |
+
from facefusion.processors.core import get_processors_modules
|
| 8 |
+
from facefusion.uis.core import register_ui_component
|
| 9 |
+
|
| 10 |
+
PROCESSORS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def render() -> None:
|
| 14 |
+
global PROCESSORS_CHECKBOX_GROUP
|
| 15 |
+
|
| 16 |
+
PROCESSORS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
| 17 |
+
label = translator.get('uis.processors_checkbox_group'),
|
| 18 |
+
choices = sort_processors(state_manager.get_item('processors')),
|
| 19 |
+
value = state_manager.get_item('processors')
|
| 20 |
+
)
|
| 21 |
+
register_ui_component('processors_checkbox_group', PROCESSORS_CHECKBOX_GROUP)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def listen() -> None:
|
| 25 |
+
PROCESSORS_CHECKBOX_GROUP.change(update_processors, inputs = PROCESSORS_CHECKBOX_GROUP, outputs = PROCESSORS_CHECKBOX_GROUP)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def update_processors(processors : List[str]) -> gradio.CheckboxGroup:
|
| 29 |
+
for processor_module in get_processors_modules(state_manager.get_item('processors')):
|
| 30 |
+
if hasattr(processor_module, 'clear_inference_pool'):
|
| 31 |
+
processor_module.clear_inference_pool()
|
| 32 |
+
|
| 33 |
+
for processor_module in get_processors_modules(processors):
|
| 34 |
+
if not processor_module.pre_check():
|
| 35 |
+
return gradio.CheckboxGroup()
|
| 36 |
+
|
| 37 |
+
state_manager.set_item('processors', processors)
|
| 38 |
+
return gradio.CheckboxGroup(value = state_manager.get_item('processors'), choices = sort_processors(state_manager.get_item('processors')))
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def sort_processors(processors : List[str]) -> List[str]:
|
| 42 |
+
available_processors = [ get_file_name(file_path) for file_path in resolve_file_paths('facefusion/processors/modules') ]
|
| 43 |
+
current_processors = []
|
| 44 |
+
|
| 45 |
+
for processor in processors + available_processors:
|
| 46 |
+
if processor in available_processors and processor not in current_processors:
|
| 47 |
+
current_processors.append(processor)
|
| 48 |
+
|
| 49 |
+
return current_processors
|
uis/components/source.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.common_helper import get_first
|
| 7 |
+
from facefusion.filesystem import filter_audio_paths, filter_image_paths, has_audio, has_image
|
| 8 |
+
from facefusion.uis.core import register_ui_component
|
| 9 |
+
from facefusion.uis.types import File
|
| 10 |
+
|
| 11 |
+
SOURCE_FILE : Optional[gradio.File] = None
|
| 12 |
+
SOURCE_AUDIO : Optional[gradio.Audio] = None
|
| 13 |
+
SOURCE_IMAGE : Optional[gradio.Image] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global SOURCE_FILE
|
| 18 |
+
global SOURCE_AUDIO
|
| 19 |
+
global SOURCE_IMAGE
|
| 20 |
+
|
| 21 |
+
has_source_audio = has_audio(state_manager.get_item('source_paths'))
|
| 22 |
+
has_source_image = has_image(state_manager.get_item('source_paths'))
|
| 23 |
+
SOURCE_FILE = gradio.File(
|
| 24 |
+
label = translator.get('uis.source_file'),
|
| 25 |
+
file_count = 'multiple',
|
| 26 |
+
value = state_manager.get_item('source_paths') if has_source_audio or has_source_image else None
|
| 27 |
+
)
|
| 28 |
+
source_file_names = [ source_file_value.get('path') for source_file_value in SOURCE_FILE.value ] if SOURCE_FILE.value else None
|
| 29 |
+
source_audio_path = get_first(filter_audio_paths(source_file_names))
|
| 30 |
+
source_image_path = get_first(filter_image_paths(source_file_names))
|
| 31 |
+
SOURCE_AUDIO = gradio.Audio(
|
| 32 |
+
value = source_audio_path if has_source_audio else None,
|
| 33 |
+
visible = has_source_audio,
|
| 34 |
+
show_label = False
|
| 35 |
+
)
|
| 36 |
+
SOURCE_IMAGE = gradio.Image(
|
| 37 |
+
value = source_image_path if has_source_image else None,
|
| 38 |
+
visible = has_source_image,
|
| 39 |
+
show_label = False
|
| 40 |
+
)
|
| 41 |
+
register_ui_component('source_audio', SOURCE_AUDIO)
|
| 42 |
+
register_ui_component('source_image', SOURCE_IMAGE)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def listen() -> None:
|
| 46 |
+
SOURCE_FILE.change(update, inputs = SOURCE_FILE, outputs = [ SOURCE_AUDIO, SOURCE_IMAGE ])
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def update(files : List[File]) -> Tuple[gradio.Audio, gradio.Image]:
|
| 50 |
+
file_names = [ file.name for file in files ] if files else None
|
| 51 |
+
has_source_audio = has_audio(file_names)
|
| 52 |
+
has_source_image = has_image(file_names)
|
| 53 |
+
|
| 54 |
+
if has_source_audio or has_source_image:
|
| 55 |
+
source_audio_path = get_first(filter_audio_paths(file_names))
|
| 56 |
+
source_image_path = get_first(filter_image_paths(file_names))
|
| 57 |
+
state_manager.set_item('source_paths', file_names)
|
| 58 |
+
return gradio.Audio(value = source_audio_path, visible = has_source_audio), gradio.Image(value = source_image_path, visible = has_source_image)
|
| 59 |
+
|
| 60 |
+
state_manager.clear_item('source_paths')
|
| 61 |
+
return gradio.Audio(value = None, visible = False), gradio.Image(value = None, visible = False)
|
uis/components/target.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.face_store import clear_faces
|
| 7 |
+
from facefusion.filesystem import is_image, is_video
|
| 8 |
+
from facefusion.uis.core import register_ui_component
|
| 9 |
+
from facefusion.uis.types import ComponentOptions, File
|
| 10 |
+
|
| 11 |
+
TARGET_FILE : Optional[gradio.File] = None
|
| 12 |
+
TARGET_IMAGE : Optional[gradio.Image] = None
|
| 13 |
+
TARGET_VIDEO : Optional[gradio.Video] = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def render() -> None:
|
| 17 |
+
global TARGET_FILE
|
| 18 |
+
global TARGET_IMAGE
|
| 19 |
+
global TARGET_VIDEO
|
| 20 |
+
|
| 21 |
+
is_target_image = is_image(state_manager.get_item('target_path'))
|
| 22 |
+
is_target_video = is_video(state_manager.get_item('target_path'))
|
| 23 |
+
TARGET_FILE = gradio.File(
|
| 24 |
+
label = translator.get('uis.target_file'),
|
| 25 |
+
value = state_manager.get_item('target_path') if is_target_image or is_target_video else None
|
| 26 |
+
)
|
| 27 |
+
target_image_options : ComponentOptions =\
|
| 28 |
+
{
|
| 29 |
+
'show_label': False,
|
| 30 |
+
'visible': False
|
| 31 |
+
}
|
| 32 |
+
target_video_options : ComponentOptions =\
|
| 33 |
+
{
|
| 34 |
+
'show_label': False,
|
| 35 |
+
'visible': False
|
| 36 |
+
}
|
| 37 |
+
if is_target_image:
|
| 38 |
+
target_image_options['value'] = TARGET_FILE.value.get('path')
|
| 39 |
+
target_image_options['visible'] = True
|
| 40 |
+
if is_target_video:
|
| 41 |
+
target_video_options['value'] = TARGET_FILE.value.get('path')
|
| 42 |
+
target_video_options['visible'] = True
|
| 43 |
+
TARGET_IMAGE = gradio.Image(**target_image_options)
|
| 44 |
+
TARGET_VIDEO = gradio.Video(**target_video_options)
|
| 45 |
+
register_ui_component('target_image', TARGET_IMAGE)
|
| 46 |
+
register_ui_component('target_video', TARGET_VIDEO)
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def listen() -> None:
|
| 50 |
+
TARGET_FILE.change(update, inputs = TARGET_FILE, outputs = [ TARGET_IMAGE, TARGET_VIDEO ])
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def update(file : File) -> Tuple[gradio.Image, gradio.Video]:
|
| 54 |
+
clear_faces()
|
| 55 |
+
|
| 56 |
+
if file and is_image(file.name):
|
| 57 |
+
state_manager.set_item('target_path', file.name)
|
| 58 |
+
return gradio.Image(value = file.name, visible = True), gradio.Video(value = None, visible = False)
|
| 59 |
+
|
| 60 |
+
if file and is_video(file.name):
|
| 61 |
+
state_manager.set_item('target_path', file.name)
|
| 62 |
+
return gradio.Image(value = None, visible = False), gradio.Video(value = file.name, visible = True)
|
| 63 |
+
|
| 64 |
+
state_manager.clear_item('target_path')
|
| 65 |
+
return gradio.Image(value = None, visible = False), gradio.Video(value = None, visible = False)
|
uis/components/temp_frame.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.filesystem import is_video
|
| 8 |
+
from facefusion.types import TempFrameFormat
|
| 9 |
+
from facefusion.uis.core import get_ui_component
|
| 10 |
+
|
| 11 |
+
TEMP_FRAME_FORMAT_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def render() -> None:
|
| 15 |
+
global TEMP_FRAME_FORMAT_DROPDOWN
|
| 16 |
+
|
| 17 |
+
TEMP_FRAME_FORMAT_DROPDOWN = gradio.Dropdown(
|
| 18 |
+
label = translator.get('uis.temp_frame_format_dropdown'),
|
| 19 |
+
choices = facefusion.choices.temp_frame_formats,
|
| 20 |
+
value = state_manager.get_item('temp_frame_format'),
|
| 21 |
+
visible = is_video(state_manager.get_item('target_path'))
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def listen() -> None:
|
| 26 |
+
TEMP_FRAME_FORMAT_DROPDOWN.change(update_temp_frame_format, inputs = TEMP_FRAME_FORMAT_DROPDOWN)
|
| 27 |
+
|
| 28 |
+
target_video = get_ui_component('target_video')
|
| 29 |
+
if target_video:
|
| 30 |
+
for method in [ 'change', 'clear' ]:
|
| 31 |
+
getattr(target_video, method)(remote_update, outputs = TEMP_FRAME_FORMAT_DROPDOWN)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def remote_update() -> gradio.Dropdown:
|
| 35 |
+
if is_video(state_manager.get_item('target_path')):
|
| 36 |
+
return gradio.Dropdown(visible = True)
|
| 37 |
+
return gradio.Dropdown(visible = False)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def update_temp_frame_format(temp_frame_format : TempFrameFormat) -> None:
|
| 41 |
+
state_manager.set_item('temp_frame_format', temp_frame_format)
|
| 42 |
+
|
uis/components/terminal.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import logging
|
| 3 |
+
import math
|
| 4 |
+
import os
|
| 5 |
+
from typing import Optional
|
| 6 |
+
|
| 7 |
+
import gradio
|
| 8 |
+
from tqdm import tqdm
|
| 9 |
+
|
| 10 |
+
import facefusion.choices
|
| 11 |
+
from facefusion import logger, state_manager, translator
|
| 12 |
+
from facefusion.types import LogLevel
|
| 13 |
+
|
| 14 |
+
LOG_LEVEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 15 |
+
TERMINAL_TEXTBOX : Optional[gradio.Textbox] = None
|
| 16 |
+
LOG_BUFFER = io.StringIO()
|
| 17 |
+
LOG_HANDLER = logging.StreamHandler(LOG_BUFFER)
|
| 18 |
+
TQDM_UPDATE = tqdm.update
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def render() -> None:
|
| 22 |
+
global LOG_LEVEL_DROPDOWN
|
| 23 |
+
global TERMINAL_TEXTBOX
|
| 24 |
+
|
| 25 |
+
LOG_LEVEL_DROPDOWN = gradio.Dropdown(
|
| 26 |
+
label = translator.get('uis.log_level_dropdown'),
|
| 27 |
+
choices = facefusion.choices.log_levels,
|
| 28 |
+
value = state_manager.get_item('log_level')
|
| 29 |
+
)
|
| 30 |
+
TERMINAL_TEXTBOX = gradio.Textbox(
|
| 31 |
+
label = translator.get('uis.terminal_textbox'),
|
| 32 |
+
value = read_logs,
|
| 33 |
+
lines = 8,
|
| 34 |
+
max_lines = 8,
|
| 35 |
+
every = 0.5,
|
| 36 |
+
show_copy_button = True
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def listen() -> None:
|
| 41 |
+
LOG_LEVEL_DROPDOWN.change(update_log_level, inputs = LOG_LEVEL_DROPDOWN)
|
| 42 |
+
logger.get_package_logger().addHandler(LOG_HANDLER)
|
| 43 |
+
tqdm.update = tqdm_update
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def update_log_level(log_level : LogLevel) -> None:
|
| 47 |
+
state_manager.set_item('log_level', log_level)
|
| 48 |
+
logger.init(state_manager.get_item('log_level'))
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def tqdm_update(self : tqdm, n : int = 1) -> None:
|
| 52 |
+
TQDM_UPDATE(self, n)
|
| 53 |
+
output = create_tqdm_output(self)
|
| 54 |
+
|
| 55 |
+
if output:
|
| 56 |
+
LOG_BUFFER.seek(0)
|
| 57 |
+
log_buffer = LOG_BUFFER.read()
|
| 58 |
+
lines = log_buffer.splitlines()
|
| 59 |
+
if lines and lines[-1].startswith(self.desc):
|
| 60 |
+
position = log_buffer.rfind(lines[-1])
|
| 61 |
+
LOG_BUFFER.seek(position)
|
| 62 |
+
else:
|
| 63 |
+
LOG_BUFFER.seek(0, os.SEEK_END)
|
| 64 |
+
LOG_BUFFER.write(output + os.linesep)
|
| 65 |
+
LOG_BUFFER.flush()
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def create_tqdm_output(self : tqdm) -> Optional[str]:
|
| 69 |
+
if not self.disable and self.desc and self.total:
|
| 70 |
+
percentage = math.floor(self.n / self.total * 100)
|
| 71 |
+
return self.desc + translator.get('colon') + ' ' + str(percentage) + '% (' + str(self.n) + '/' + str(self.total) + ')'
|
| 72 |
+
if not self.disable and self.desc and self.unit:
|
| 73 |
+
return self.desc + translator.get('colon') + ' ' + str(self.n) + ' ' + self.unit
|
| 74 |
+
return None
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def read_logs() -> str:
|
| 78 |
+
LOG_BUFFER.seek(0)
|
| 79 |
+
logs = LOG_BUFFER.read().strip()
|
| 80 |
+
return logs
|
uis/components/trim_frame.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional, Tuple
|
| 2 |
+
|
| 3 |
+
from gradio_rangeslider import RangeSlider
|
| 4 |
+
|
| 5 |
+
from facefusion import state_manager, translator
|
| 6 |
+
from facefusion.face_store import clear_faces
|
| 7 |
+
from facefusion.filesystem import is_video
|
| 8 |
+
from facefusion.uis.core import get_ui_components
|
| 9 |
+
from facefusion.uis.types import ComponentOptions
|
| 10 |
+
from facefusion.vision import count_video_frame_total
|
| 11 |
+
|
| 12 |
+
TRIM_FRAME_RANGE_SLIDER : Optional[RangeSlider] = None
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def render() -> None:
|
| 16 |
+
global TRIM_FRAME_RANGE_SLIDER
|
| 17 |
+
|
| 18 |
+
trim_frame_range_slider_options : ComponentOptions =\
|
| 19 |
+
{
|
| 20 |
+
'label': translator.get('uis.trim_frame_slider'),
|
| 21 |
+
'minimum': 0,
|
| 22 |
+
'step': 1,
|
| 23 |
+
'visible': False
|
| 24 |
+
}
|
| 25 |
+
if is_video(state_manager.get_item('target_path')):
|
| 26 |
+
video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
|
| 27 |
+
trim_frame_start = state_manager.get_item('trim_frame_start') or 0
|
| 28 |
+
trim_frame_end = state_manager.get_item('trim_frame_end') or video_frame_total
|
| 29 |
+
trim_frame_range_slider_options['maximum'] = video_frame_total
|
| 30 |
+
trim_frame_range_slider_options['value'] = (trim_frame_start, trim_frame_end)
|
| 31 |
+
trim_frame_range_slider_options['visible'] = True
|
| 32 |
+
TRIM_FRAME_RANGE_SLIDER = RangeSlider(**trim_frame_range_slider_options)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def listen() -> None:
|
| 36 |
+
TRIM_FRAME_RANGE_SLIDER.release(update_trim_frame, inputs = TRIM_FRAME_RANGE_SLIDER)
|
| 37 |
+
for ui_component in get_ui_components(
|
| 38 |
+
[
|
| 39 |
+
'target_image',
|
| 40 |
+
'target_video'
|
| 41 |
+
]):
|
| 42 |
+
for method in [ 'change', 'clear' ]:
|
| 43 |
+
getattr(ui_component, method)(remote_update, outputs = [ TRIM_FRAME_RANGE_SLIDER ])
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def remote_update() -> RangeSlider:
|
| 47 |
+
if is_video(state_manager.get_item('target_path')):
|
| 48 |
+
video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
|
| 49 |
+
state_manager.clear_item('trim_frame_start')
|
| 50 |
+
state_manager.clear_item('trim_frame_end')
|
| 51 |
+
return RangeSlider(value = (0, video_frame_total), maximum = video_frame_total, visible = True)
|
| 52 |
+
return RangeSlider(visible = False)
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def update_trim_frame(trim_frame : Tuple[float, float]) -> None:
|
| 56 |
+
clear_faces()
|
| 57 |
+
trim_frame_start, trim_frame_end = trim_frame
|
| 58 |
+
video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
|
| 59 |
+
trim_frame_start = int(trim_frame_start) if trim_frame_start > 0 else None
|
| 60 |
+
trim_frame_end = int(trim_frame_end) if trim_frame_end < video_frame_total else None
|
| 61 |
+
state_manager.set_item('trim_frame_start', trim_frame_start)
|
| 62 |
+
state_manager.set_item('trim_frame_end', trim_frame_end)
|
uis/components/ui_workflow.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.uis.core import register_ui_component
|
| 8 |
+
|
| 9 |
+
UI_WORKFLOW_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def render() -> None:
|
| 13 |
+
global UI_WORKFLOW_DROPDOWN
|
| 14 |
+
|
| 15 |
+
UI_WORKFLOW_DROPDOWN = gradio.Dropdown(
|
| 16 |
+
label = translator.get('uis.ui_workflow'),
|
| 17 |
+
choices = facefusion.choices.ui_workflows,
|
| 18 |
+
value = state_manager.get_item('ui_workflow'),
|
| 19 |
+
interactive = True
|
| 20 |
+
)
|
| 21 |
+
register_ui_component('ui_workflow_dropdown', UI_WORKFLOW_DROPDOWN)
|
uis/components/voice_extractor.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List, Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator, voice_extractor
|
| 7 |
+
from facefusion.filesystem import is_video
|
| 8 |
+
from facefusion.types import VoiceExtractorModel
|
| 9 |
+
from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
|
| 10 |
+
|
| 11 |
+
VOICE_EXTRACTOR_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def render() -> None:
|
| 15 |
+
global VOICE_EXTRACTOR_MODEL_DROPDOWN
|
| 16 |
+
|
| 17 |
+
has_lip_syncer = 'lip_syncer' in state_manager.get_item('processors')
|
| 18 |
+
VOICE_EXTRACTOR_MODEL_DROPDOWN = gradio.Dropdown(
|
| 19 |
+
label = translator.get('uis.voice_extractor_model_dropdown'),
|
| 20 |
+
choices = facefusion.choices.voice_extractor_models,
|
| 21 |
+
value = state_manager.get_item('voice_extractor_model'),
|
| 22 |
+
visible = is_video(state_manager.get_item('target_path')) and has_lip_syncer
|
| 23 |
+
)
|
| 24 |
+
register_ui_component('voice_extractor_model_dropdown', VOICE_EXTRACTOR_MODEL_DROPDOWN)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def listen() -> None:
|
| 28 |
+
VOICE_EXTRACTOR_MODEL_DROPDOWN.change(update_voice_extractor_model, inputs = VOICE_EXTRACTOR_MODEL_DROPDOWN, outputs = VOICE_EXTRACTOR_MODEL_DROPDOWN)
|
| 29 |
+
|
| 30 |
+
processors_checkbox_group = get_ui_component('processors_checkbox_group')
|
| 31 |
+
if processors_checkbox_group:
|
| 32 |
+
processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = VOICE_EXTRACTOR_MODEL_DROPDOWN)
|
| 33 |
+
|
| 34 |
+
for ui_component in get_ui_components(
|
| 35 |
+
[
|
| 36 |
+
'target_image',
|
| 37 |
+
'target_video'
|
| 38 |
+
]):
|
| 39 |
+
for method in [ 'change', 'clear' ]:
|
| 40 |
+
getattr(ui_component, method)(remote_update, inputs = processors_checkbox_group, outputs = VOICE_EXTRACTOR_MODEL_DROPDOWN)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def remote_update(processors : List[str]) -> gradio.Dropdown:
|
| 44 |
+
has_lip_syncer = 'lip_syncer' in processors
|
| 45 |
+
if is_video(state_manager.get_item('target_path')) and has_lip_syncer:
|
| 46 |
+
return gradio.Dropdown(visible = True)
|
| 47 |
+
return gradio.Dropdown(visible = False)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def update_voice_extractor_model(voice_extractor_model : VoiceExtractorModel) -> gradio.Dropdown:
|
| 51 |
+
voice_extractor.clear_inference_pool()
|
| 52 |
+
state_manager.set_item('voice_extractor_model', voice_extractor_model)
|
| 53 |
+
|
| 54 |
+
if voice_extractor.pre_check():
|
| 55 |
+
gradio.Dropdown(value = state_manager.get_item('voice_extractor_model'))
|
| 56 |
+
return gradio.Dropdown()
|
uis/components/webcam.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Iterator, List, Optional, Tuple
|
| 2 |
+
|
| 3 |
+
import cv2
|
| 4 |
+
import gradio
|
| 5 |
+
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.camera_manager import clear_camera_pool, get_local_camera_capture
|
| 8 |
+
from facefusion.filesystem import has_image
|
| 9 |
+
from facefusion.streamer import multi_process_capture, open_stream
|
| 10 |
+
from facefusion.types import Fps, VisionFrame, WebcamMode
|
| 11 |
+
from facefusion.uis.core import get_ui_component
|
| 12 |
+
from facefusion.uis.types import File
|
| 13 |
+
from facefusion.vision import fit_cover_frame, unpack_resolution
|
| 14 |
+
|
| 15 |
+
SOURCE_FILE : Optional[gradio.File] = None
|
| 16 |
+
WEBCAM_IMAGE : Optional[gradio.Image] = None
|
| 17 |
+
WEBCAM_START_BUTTON : Optional[gradio.Button] = None
|
| 18 |
+
WEBCAM_STOP_BUTTON : Optional[gradio.Button] = None
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def render() -> None:
|
| 22 |
+
global SOURCE_FILE
|
| 23 |
+
global WEBCAM_IMAGE
|
| 24 |
+
global WEBCAM_START_BUTTON
|
| 25 |
+
global WEBCAM_STOP_BUTTON
|
| 26 |
+
|
| 27 |
+
has_source_image = has_image(state_manager.get_item('source_paths'))
|
| 28 |
+
SOURCE_FILE = gradio.File(
|
| 29 |
+
label = translator.get('uis.source_file'),
|
| 30 |
+
file_count = 'multiple',
|
| 31 |
+
value = state_manager.get_item('source_paths') if has_source_image else None
|
| 32 |
+
)
|
| 33 |
+
WEBCAM_IMAGE = gradio.Image(
|
| 34 |
+
label = translator.get('uis.webcam_image'),
|
| 35 |
+
format = 'jpeg',
|
| 36 |
+
visible = False
|
| 37 |
+
)
|
| 38 |
+
WEBCAM_START_BUTTON = gradio.Button(
|
| 39 |
+
value = translator.get('uis.start_button'),
|
| 40 |
+
variant = 'primary',
|
| 41 |
+
size = 'sm'
|
| 42 |
+
)
|
| 43 |
+
WEBCAM_STOP_BUTTON = gradio.Button(
|
| 44 |
+
value = translator.get('uis.stop_button'),
|
| 45 |
+
size = 'sm',
|
| 46 |
+
visible = False
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def listen() -> None:
|
| 51 |
+
SOURCE_FILE.change(update_source, inputs = SOURCE_FILE, outputs = SOURCE_FILE)
|
| 52 |
+
webcam_device_id_dropdown = get_ui_component('webcam_device_id_dropdown')
|
| 53 |
+
webcam_mode_radio = get_ui_component('webcam_mode_radio')
|
| 54 |
+
webcam_resolution_dropdown = get_ui_component('webcam_resolution_dropdown')
|
| 55 |
+
webcam_fps_slider = get_ui_component('webcam_fps_slider')
|
| 56 |
+
|
| 57 |
+
if webcam_device_id_dropdown and webcam_mode_radio and webcam_resolution_dropdown and webcam_fps_slider:
|
| 58 |
+
WEBCAM_START_BUTTON.click(pre_start, outputs = [ SOURCE_FILE, WEBCAM_IMAGE, WEBCAM_START_BUTTON, WEBCAM_STOP_BUTTON ])
|
| 59 |
+
start_event = WEBCAM_START_BUTTON.click(start, inputs = [ webcam_device_id_dropdown, webcam_mode_radio, webcam_resolution_dropdown, webcam_fps_slider ], outputs = WEBCAM_IMAGE)
|
| 60 |
+
start_event.then(pre_stop)
|
| 61 |
+
WEBCAM_STOP_BUTTON.click(stop, cancels = start_event, outputs = WEBCAM_IMAGE)
|
| 62 |
+
WEBCAM_STOP_BUTTON.click(pre_stop, outputs = [ SOURCE_FILE, WEBCAM_IMAGE, WEBCAM_START_BUTTON, WEBCAM_STOP_BUTTON ])
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def update_source(files : List[File]) -> gradio.File:
|
| 66 |
+
file_names = [ file.name for file in files ] if files else None
|
| 67 |
+
has_source_image = has_image(file_names)
|
| 68 |
+
|
| 69 |
+
if has_source_image:
|
| 70 |
+
state_manager.set_item('source_paths', file_names)
|
| 71 |
+
return gradio.File(value = file_names)
|
| 72 |
+
|
| 73 |
+
state_manager.clear_item('source_paths')
|
| 74 |
+
return gradio.File(value = None)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def pre_start() -> Tuple[gradio.File, gradio.Image, gradio.Button, gradio.Button]:
|
| 78 |
+
return gradio.File(visible = False), gradio.Image(visible = True), gradio.Button(visible = False), gradio.Button(visible = True)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def pre_stop() -> Tuple[gradio.File, gradio.Image, gradio.Button, gradio.Button]:
|
| 82 |
+
return gradio.File(visible = True), gradio.Image(visible = False), gradio.Button(visible = True), gradio.Button(visible = False)
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def start(webcam_device_id : int, webcam_mode : WebcamMode, webcam_resolution : str, webcam_fps : Fps) -> Iterator[VisionFrame]:
|
| 86 |
+
state_manager.init_item('face_selector_mode', 'one')
|
| 87 |
+
state_manager.sync_state()
|
| 88 |
+
|
| 89 |
+
camera_capture = get_local_camera_capture(webcam_device_id)
|
| 90 |
+
stream = None
|
| 91 |
+
|
| 92 |
+
if webcam_mode in [ 'udp', 'v4l2' ]:
|
| 93 |
+
stream = open_stream(webcam_mode, webcam_resolution, webcam_fps) #type:ignore[arg-type]
|
| 94 |
+
webcam_width, webcam_height = unpack_resolution(webcam_resolution)
|
| 95 |
+
|
| 96 |
+
if camera_capture and camera_capture.isOpened():
|
| 97 |
+
camera_capture.set(cv2.CAP_PROP_FRAME_WIDTH, webcam_width)
|
| 98 |
+
camera_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, webcam_height)
|
| 99 |
+
camera_capture.set(cv2.CAP_PROP_FPS, webcam_fps)
|
| 100 |
+
|
| 101 |
+
for capture_vision_frame in multi_process_capture(camera_capture, webcam_fps):
|
| 102 |
+
capture_vision_frame = cv2.cvtColor(capture_vision_frame, cv2.COLOR_BGR2RGB)
|
| 103 |
+
capture_vision_frame = fit_cover_frame(capture_vision_frame, (webcam_width, webcam_height))
|
| 104 |
+
|
| 105 |
+
if webcam_mode == 'inline':
|
| 106 |
+
yield capture_vision_frame
|
| 107 |
+
if webcam_mode in [ 'udp', 'v4l2' ]:
|
| 108 |
+
try:
|
| 109 |
+
stream.stdin.write(capture_vision_frame.data)
|
| 110 |
+
except Exception:
|
| 111 |
+
pass
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def stop() -> gradio.Image:
|
| 115 |
+
clear_camera_pool()
|
| 116 |
+
return gradio.Image(value = None)
|
uis/components/webcam_options.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
from facefusion import translator
|
| 6 |
+
from facefusion.camera_manager import detect_local_camera_ids
|
| 7 |
+
from facefusion.common_helper import get_first
|
| 8 |
+
from facefusion.uis import choices as uis_choices
|
| 9 |
+
from facefusion.uis.core import register_ui_component
|
| 10 |
+
|
| 11 |
+
WEBCAM_DEVICE_ID_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 12 |
+
WEBCAM_MODE_RADIO : Optional[gradio.Radio] = None
|
| 13 |
+
WEBCAM_RESOLUTION_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 14 |
+
WEBCAM_FPS_SLIDER : Optional[gradio.Slider] = None
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def render() -> None:
|
| 18 |
+
global WEBCAM_DEVICE_ID_DROPDOWN
|
| 19 |
+
global WEBCAM_MODE_RADIO
|
| 20 |
+
global WEBCAM_RESOLUTION_DROPDOWN
|
| 21 |
+
global WEBCAM_FPS_SLIDER
|
| 22 |
+
|
| 23 |
+
local_camera_ids = detect_local_camera_ids(0, 10) or [ 'none' ] #type:ignore[list-item]
|
| 24 |
+
WEBCAM_DEVICE_ID_DROPDOWN = gradio.Dropdown(
|
| 25 |
+
value = get_first(local_camera_ids),
|
| 26 |
+
label = translator.get('uis.webcam_device_id_dropdown'),
|
| 27 |
+
choices = local_camera_ids
|
| 28 |
+
)
|
| 29 |
+
WEBCAM_MODE_RADIO = gradio.Radio(
|
| 30 |
+
label = translator.get('uis.webcam_mode_radio'),
|
| 31 |
+
choices = uis_choices.webcam_modes,
|
| 32 |
+
value = uis_choices.webcam_modes[0]
|
| 33 |
+
)
|
| 34 |
+
WEBCAM_RESOLUTION_DROPDOWN = gradio.Dropdown(
|
| 35 |
+
label = translator.get('uis.webcam_resolution_dropdown'),
|
| 36 |
+
choices = uis_choices.webcam_resolutions,
|
| 37 |
+
value = uis_choices.webcam_resolutions[0]
|
| 38 |
+
)
|
| 39 |
+
WEBCAM_FPS_SLIDER = gradio.Slider(
|
| 40 |
+
label = translator.get('uis.webcam_fps_slider'),
|
| 41 |
+
value = 30,
|
| 42 |
+
step = 1,
|
| 43 |
+
minimum = 1,
|
| 44 |
+
maximum = 30
|
| 45 |
+
)
|
| 46 |
+
register_ui_component('webcam_device_id_dropdown', WEBCAM_DEVICE_ID_DROPDOWN)
|
| 47 |
+
register_ui_component('webcam_mode_radio', WEBCAM_MODE_RADIO)
|
| 48 |
+
register_ui_component('webcam_resolution_dropdown', WEBCAM_RESOLUTION_DROPDOWN)
|
| 49 |
+
register_ui_component('webcam_fps_slider', WEBCAM_FPS_SLIDER)
|
uis/components/workflow.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import gradio
|
| 4 |
+
|
| 5 |
+
import facefusion.choices
|
| 6 |
+
from facefusion import state_manager, translator
|
| 7 |
+
from facefusion.types import WorkflowStrategy
|
| 8 |
+
|
| 9 |
+
WORKFLOW_STRATEGY_DROPDOWN : Optional[gradio.Dropdown] = None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def render() -> None:
|
| 13 |
+
global WORKFLOW_STRATEGY_DROPDOWN
|
| 14 |
+
|
| 15 |
+
WORKFLOW_STRATEGY_DROPDOWN = gradio.Dropdown(
|
| 16 |
+
label = translator.get('uis.workflow_strategy_dropdown'),
|
| 17 |
+
choices = facefusion.choices.workflow_strategies,
|
| 18 |
+
value = state_manager.get_item('workflow_strategy')
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def listen() -> None:
|
| 23 |
+
WORKFLOW_STRATEGY_DROPDOWN.change(update_workflow_strategy, inputs = WORKFLOW_STRATEGY_DROPDOWN)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def update_workflow_strategy(workflow_strategy : WorkflowStrategy) -> None:
|
| 27 |
+
state_manager.set_item('workflow_strategy', workflow_strategy)
|