Next (#107)
* Allow passing the onnxruntime to install.py * Fix CI * Disallow none execution providers in the UI * Use CV2 to detect fps * Respect trim on videos with audio * Respect trim on videos with audio (finally) * Implement caching to speed up preview and webcam * Define webcam UI and webcam performance * Remove layout from components * Add primary buttons * Extract benchmark and webcam settings * Introduce compact UI settings * Caching for IO and **** prediction * Caching for IO and **** prediction * Introduce face analyser caching * Fix some typing * Improve setup for benchmark * Clear image cache via post process * Fix settings in UI, Simplify restore_audio() using shortest * Select resolution and fps via webcam ui * Introduce read_static_image() to stop caching temp images * Use DirectShow under Windows * Multi-threading for webcam * Fix typing * Refactor frame processor * Refactor webcam processing * Avoid warnings due capture.isOpened() * Resume downloads (#110) * Introduce resumable downloads * Fix CURL commands * Break execution_settings into pieces * Cosmetic changes on cv2 webcam * Update Gradio * Move face cache to own file * Uniform namings for threading * Fix sorting of get_temp_frame_paths(), extend get_temp_frames_pattern() * Minor changes from the review * Looks stable to tme * Update the disclaimer * Update the disclaimer * Update the disclaimer
This commit is contained in:
7
facefusion/uis/choices.py
Normal file
7
facefusion/uis/choices.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from typing import List
|
||||
|
||||
from facefusion.uis.typing import WebcamMode
|
||||
|
||||
settings : List[str] = [ 'keep-fps', 'keep-temp', 'skip-audio' ]
|
||||
webcam_mode : List[WebcamMode] = [ 'inline', 'stream_udp', 'stream_v4l2' ]
|
||||
webcam_resolution : List[str] = [ '320x240', '640x480', '1280x720', '1920x1080', '2560x1440', '3840x2160' ]
|
||||
@@ -9,5 +9,4 @@ ABOUT_HTML : Optional[gradio.HTML] = None
|
||||
def render() -> None:
|
||||
global ABOUT_HTML
|
||||
|
||||
with gradio.Box():
|
||||
ABOUT_HTML = gradio.HTML('<center><a href="' + metadata.get('url') + '">' + metadata.get('name') + ' ' + metadata.get('version') + '</a></center>')
|
||||
ABOUT_HTML = gradio.HTML('<center><a href="' + metadata.get('url') + '">' + metadata.get('name') + ' ' + metadata.get('version') + '</a></center>')
|
||||
|
||||
@@ -6,17 +6,19 @@ import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.face_analyser import get_face_analyser
|
||||
from facefusion.face_cache import clear_faces_cache
|
||||
from facefusion.processors.frame.core import get_frame_processors_modules
|
||||
from facefusion.vision import count_video_frame_total
|
||||
from facefusion.core import limit_resources, conditional_process
|
||||
from facefusion.uis.typing import Update
|
||||
from facefusion.uis import core as ui
|
||||
from facefusion.utilities import normalize_output_path, clear_temp
|
||||
|
||||
BENCHMARK_RESULTS_DATAFRAME : Optional[gradio.Dataframe] = None
|
||||
BENCHMARK_RUNS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
BENCHMARK_CYCLES_SLIDER : Optional[gradio.Button] = None
|
||||
BENCHMARK_START_BUTTON : Optional[gradio.Button] = None
|
||||
BENCHMARK_CLEAR_BUTTON : Optional[gradio.Button] = None
|
||||
BENCHMARKS : Dict[str, str] = \
|
||||
BENCHMARKS : Dict[str, str] =\
|
||||
{
|
||||
'240p': '.assets/examples/target-240p.mp4',
|
||||
'360p': '.assets/examples/target-360p.mp4',
|
||||
@@ -30,77 +32,68 @@ BENCHMARKS : Dict[str, str] = \
|
||||
|
||||
def render() -> None:
|
||||
global BENCHMARK_RESULTS_DATAFRAME
|
||||
global BENCHMARK_RUNS_CHECKBOX_GROUP
|
||||
global BENCHMARK_CYCLES_SLIDER
|
||||
global BENCHMARK_START_BUTTON
|
||||
global BENCHMARK_CLEAR_BUTTON
|
||||
|
||||
with gradio.Box():
|
||||
BENCHMARK_RESULTS_DATAFRAME = gradio.Dataframe(
|
||||
label = wording.get('benchmark_results_dataframe_label'),
|
||||
headers =
|
||||
[
|
||||
'target_path',
|
||||
'benchmark_cycles',
|
||||
'average_run',
|
||||
'fastest_run',
|
||||
'slowest_run',
|
||||
'relative_fps'
|
||||
],
|
||||
row_count = len(BENCHMARKS),
|
||||
datatype =
|
||||
[
|
||||
'str',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number'
|
||||
]
|
||||
)
|
||||
with gradio.Box():
|
||||
BENCHMARK_RUNS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('benchmark_runs_checkbox_group_label'),
|
||||
value = list(BENCHMARKS.keys()),
|
||||
choices = list(BENCHMARKS.keys())
|
||||
)
|
||||
BENCHMARK_CYCLES_SLIDER = gradio.Slider(
|
||||
label = wording.get('benchmark_cycles_slider_label'),
|
||||
minimum = 1,
|
||||
step = 1,
|
||||
value = 3,
|
||||
maximum = 10
|
||||
)
|
||||
with gradio.Row():
|
||||
BENCHMARK_START_BUTTON = gradio.Button(wording.get('start_button_label'))
|
||||
BENCHMARK_CLEAR_BUTTON = gradio.Button(wording.get('clear_button_label'))
|
||||
BENCHMARK_RESULTS_DATAFRAME = gradio.Dataframe(
|
||||
label = wording.get('benchmark_results_dataframe_label'),
|
||||
headers =
|
||||
[
|
||||
'target_path',
|
||||
'benchmark_cycles',
|
||||
'average_run',
|
||||
'fastest_run',
|
||||
'slowest_run',
|
||||
'relative_fps'
|
||||
],
|
||||
datatype =
|
||||
[
|
||||
'str',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number',
|
||||
'number'
|
||||
]
|
||||
)
|
||||
BENCHMARK_START_BUTTON = gradio.Button(
|
||||
value = wording.get('start_button_label'),
|
||||
variant = 'primary'
|
||||
)
|
||||
BENCHMARK_CLEAR_BUTTON = gradio.Button(
|
||||
value = wording.get('clear_button_label')
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
BENCHMARK_RUNS_CHECKBOX_GROUP.change(update_benchmark_runs, inputs = BENCHMARK_RUNS_CHECKBOX_GROUP, outputs = BENCHMARK_RUNS_CHECKBOX_GROUP)
|
||||
BENCHMARK_START_BUTTON.click(start, inputs = [ BENCHMARK_RUNS_CHECKBOX_GROUP, BENCHMARK_CYCLES_SLIDER ], outputs = BENCHMARK_RESULTS_DATAFRAME)
|
||||
benchmark_runs_checkbox_group = ui.get_component('benchmark_runs_checkbox_group')
|
||||
benchmark_cycles_slider = ui.get_component('benchmark_cycles_slider')
|
||||
if benchmark_runs_checkbox_group and benchmark_cycles_slider:
|
||||
BENCHMARK_START_BUTTON.click(start, inputs = [ benchmark_runs_checkbox_group, benchmark_cycles_slider ], outputs = BENCHMARK_RESULTS_DATAFRAME)
|
||||
BENCHMARK_CLEAR_BUTTON.click(clear, outputs = BENCHMARK_RESULTS_DATAFRAME)
|
||||
|
||||
|
||||
def update_benchmark_runs(benchmark_runs : List[str]) -> Update:
|
||||
return gradio.update(value = benchmark_runs)
|
||||
|
||||
|
||||
def start(benchmark_runs : List[str], benchmark_cycles : int) -> Generator[List[Any], None, None]:
|
||||
facefusion.globals.source_path = '.assets/examples/source.jpg'
|
||||
target_paths = [ BENCHMARKS[benchmark_run] for benchmark_run in benchmark_runs if benchmark_run in BENCHMARKS ]
|
||||
benchmark_results = []
|
||||
if target_paths:
|
||||
warm_up(BENCHMARKS['240p'])
|
||||
pre_process()
|
||||
for target_path in target_paths:
|
||||
benchmark_results.append(benchmark(target_path, benchmark_cycles))
|
||||
yield benchmark_results
|
||||
post_process()
|
||||
|
||||
|
||||
def warm_up(target_path : str) -> None:
|
||||
facefusion.globals.target_path = target_path
|
||||
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_path, facefusion.globals.target_path, tempfile.gettempdir())
|
||||
conditional_process()
|
||||
def pre_process() -> None:
|
||||
limit_resources()
|
||||
get_face_analyser()
|
||||
for frame_processor_module in get_frame_processors_modules(facefusion.globals.frame_processors):
|
||||
frame_processor_module.get_frame_processor()
|
||||
|
||||
|
||||
def post_process() -> None:
|
||||
clear_faces_cache()
|
||||
|
||||
|
||||
def benchmark(target_path : str, benchmark_cycles : int) -> List[Any]:
|
||||
@@ -111,7 +104,6 @@ def benchmark(target_path : str, benchmark_cycles : int) -> List[Any]:
|
||||
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_path, facefusion.globals.target_path, tempfile.gettempdir())
|
||||
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
|
||||
start_time = time.perf_counter()
|
||||
limit_resources()
|
||||
conditional_process()
|
||||
end_time = time.perf_counter()
|
||||
process_time = end_time - start_time
|
||||
|
||||
38
facefusion/uis/components/benchmark_settings.py
Normal file
38
facefusion/uis/components/benchmark_settings.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from typing import Optional, List
|
||||
import gradio
|
||||
|
||||
from facefusion import wording
|
||||
from facefusion.uis.typing import Update
|
||||
from facefusion.uis import core as ui
|
||||
from facefusion.uis.components.benchmark import BENCHMARKS
|
||||
|
||||
BENCHMARK_RUNS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
BENCHMARK_CYCLES_SLIDER : Optional[gradio.Button] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global BENCHMARK_RUNS_CHECKBOX_GROUP
|
||||
global BENCHMARK_CYCLES_SLIDER
|
||||
|
||||
BENCHMARK_RUNS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('benchmark_runs_checkbox_group_label'),
|
||||
value = list(BENCHMARKS.keys()),
|
||||
choices = list(BENCHMARKS.keys())
|
||||
)
|
||||
BENCHMARK_CYCLES_SLIDER = gradio.Slider(
|
||||
label = wording.get('benchmark_cycles_slider_label'),
|
||||
minimum = 1,
|
||||
step = 1,
|
||||
value = 3,
|
||||
maximum = 10
|
||||
)
|
||||
ui.register_component('benchmark_runs_checkbox_group', BENCHMARK_RUNS_CHECKBOX_GROUP)
|
||||
ui.register_component('benchmark_cycles_slider', BENCHMARK_CYCLES_SLIDER)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
BENCHMARK_RUNS_CHECKBOX_GROUP.change(update_benchmark_runs, inputs = BENCHMARK_RUNS_CHECKBOX_GROUP, outputs = BENCHMARK_RUNS_CHECKBOX_GROUP)
|
||||
|
||||
|
||||
def update_benchmark_runs(benchmark_runs : List[str]) -> Update:
|
||||
return gradio.update(value = benchmark_runs)
|
||||
@@ -10,55 +10,26 @@ from facefusion.uis.typing import Update
|
||||
from facefusion.utilities import encode_execution_providers, decode_execution_providers
|
||||
|
||||
EXECUTION_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
EXECUTION_THREAD_COUNT_SLIDER : Optional[gradio.Slider] = None
|
||||
EXECUTION_QUEUE_COUNT_SLIDER : Optional[gradio.Slider] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global EXECUTION_PROVIDERS_CHECKBOX_GROUP
|
||||
global EXECUTION_THREAD_COUNT_SLIDER
|
||||
global EXECUTION_QUEUE_COUNT_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
EXECUTION_PROVIDERS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('execution_providers_checkbox_group_label'),
|
||||
choices = encode_execution_providers(onnxruntime.get_available_providers()),
|
||||
value = encode_execution_providers(facefusion.globals.execution_providers)
|
||||
)
|
||||
EXECUTION_THREAD_COUNT_SLIDER = gradio.Slider(
|
||||
label = wording.get('execution_thread_count_slider_label'),
|
||||
value = facefusion.globals.execution_thread_count,
|
||||
step = 1,
|
||||
minimum = 1,
|
||||
maximum = 128
|
||||
)
|
||||
EXECUTION_QUEUE_COUNT_SLIDER = gradio.Slider(
|
||||
label = wording.get('execution_queue_count_slider_label'),
|
||||
value = facefusion.globals.execution_queue_count,
|
||||
step = 1,
|
||||
minimum = 1,
|
||||
maximum = 16
|
||||
)
|
||||
EXECUTION_PROVIDERS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('execution_providers_checkbox_group_label'),
|
||||
choices = encode_execution_providers(onnxruntime.get_available_providers()),
|
||||
value = encode_execution_providers(facefusion.globals.execution_providers)
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
EXECUTION_PROVIDERS_CHECKBOX_GROUP.change(update_execution_providers, inputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP, outputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP)
|
||||
EXECUTION_THREAD_COUNT_SLIDER.change(update_execution_thread_count, inputs = EXECUTION_THREAD_COUNT_SLIDER, outputs = EXECUTION_THREAD_COUNT_SLIDER)
|
||||
EXECUTION_QUEUE_COUNT_SLIDER.change(update_execution_queue_count, inputs = EXECUTION_QUEUE_COUNT_SLIDER, outputs = EXECUTION_QUEUE_COUNT_SLIDER)
|
||||
|
||||
|
||||
def update_execution_providers(execution_providers : List[str]) -> Update:
|
||||
clear_face_analyser()
|
||||
clear_frame_processors_modules()
|
||||
if not execution_providers:
|
||||
execution_providers = encode_execution_providers(onnxruntime.get_available_providers())
|
||||
facefusion.globals.execution_providers = decode_execution_providers(execution_providers)
|
||||
return gradio.update(value = execution_providers)
|
||||
|
||||
|
||||
def update_execution_thread_count(execution_thread_count : int = 1) -> Update:
|
||||
facefusion.globals.execution_thread_count = execution_thread_count
|
||||
return gradio.update(value = execution_thread_count)
|
||||
|
||||
|
||||
def update_execution_queue_count(execution_queue_count : int = 1) -> Update:
|
||||
facefusion.globals.execution_queue_count = execution_queue_count
|
||||
return gradio.update(value = execution_queue_count)
|
||||
|
||||
29
facefusion/uis/components/execution_queue_count.py
Normal file
29
facefusion/uis/components/execution_queue_count.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from typing import Optional
|
||||
import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.uis.typing import Update
|
||||
|
||||
EXECUTION_QUEUE_COUNT_SLIDER : Optional[gradio.Slider] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global EXECUTION_QUEUE_COUNT_SLIDER
|
||||
|
||||
EXECUTION_QUEUE_COUNT_SLIDER = gradio.Slider(
|
||||
label = wording.get('execution_queue_count_slider_label'),
|
||||
value = facefusion.globals.execution_queue_count,
|
||||
step = 1,
|
||||
minimum = 1,
|
||||
maximum = 16
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
EXECUTION_QUEUE_COUNT_SLIDER.change(update_execution_queue_count, inputs = EXECUTION_QUEUE_COUNT_SLIDER, outputs = EXECUTION_QUEUE_COUNT_SLIDER)
|
||||
|
||||
|
||||
def update_execution_queue_count(execution_queue_count : int = 1) -> Update:
|
||||
facefusion.globals.execution_queue_count = execution_queue_count
|
||||
return gradio.update(value = execution_queue_count)
|
||||
29
facefusion/uis/components/execution_thread_count.py
Normal file
29
facefusion/uis/components/execution_thread_count.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from typing import Optional
|
||||
import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.uis.typing import Update
|
||||
|
||||
EXECUTION_THREAD_COUNT_SLIDER : Optional[gradio.Slider] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global EXECUTION_THREAD_COUNT_SLIDER
|
||||
|
||||
EXECUTION_THREAD_COUNT_SLIDER = gradio.Slider(
|
||||
label = wording.get('execution_thread_count_slider_label'),
|
||||
value = facefusion.globals.execution_thread_count,
|
||||
step = 1,
|
||||
minimum = 1,
|
||||
maximum = 128
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
EXECUTION_THREAD_COUNT_SLIDER.change(update_execution_thread_count, inputs = EXECUTION_THREAD_COUNT_SLIDER, outputs = EXECUTION_THREAD_COUNT_SLIDER)
|
||||
|
||||
|
||||
def update_execution_thread_count(execution_thread_count : int = 1) -> Update:
|
||||
facefusion.globals.execution_thread_count = execution_thread_count
|
||||
return gradio.update(value = execution_thread_count)
|
||||
@@ -18,26 +18,24 @@ def render() -> None:
|
||||
global FACE_ANALYSER_AGE_DROPDOWN
|
||||
global FACE_ANALYSER_GENDER_DROPDOWN
|
||||
|
||||
with gradio.Box():
|
||||
with gradio.Row():
|
||||
FACE_ANALYSER_DIRECTION_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_analyser_direction_dropdown_label'),
|
||||
choices = facefusion.choices.face_analyser_direction,
|
||||
value = facefusion.globals.face_analyser_direction
|
||||
)
|
||||
FACE_ANALYSER_AGE_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_analyser_age_dropdown_label'),
|
||||
choices = ['none'] + facefusion.choices.face_analyser_age,
|
||||
value = facefusion.globals.face_analyser_age or 'none'
|
||||
)
|
||||
FACE_ANALYSER_GENDER_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_analyser_gender_dropdown_label'),
|
||||
choices = ['none'] + facefusion.choices.face_analyser_gender,
|
||||
value = facefusion.globals.face_analyser_gender or 'none'
|
||||
)
|
||||
ui.register_component('face_analyser_direction_dropdown', FACE_ANALYSER_DIRECTION_DROPDOWN)
|
||||
ui.register_component('face_analyser_age_dropdown', FACE_ANALYSER_AGE_DROPDOWN)
|
||||
ui.register_component('face_analyser_gender_dropdown', FACE_ANALYSER_GENDER_DROPDOWN)
|
||||
FACE_ANALYSER_DIRECTION_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_analyser_direction_dropdown_label'),
|
||||
choices = facefusion.choices.face_analyser_direction,
|
||||
value = facefusion.globals.face_analyser_direction
|
||||
)
|
||||
FACE_ANALYSER_AGE_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_analyser_age_dropdown_label'),
|
||||
choices = ['none'] + facefusion.choices.face_analyser_age,
|
||||
value = facefusion.globals.face_analyser_age or 'none'
|
||||
)
|
||||
FACE_ANALYSER_GENDER_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_analyser_gender_dropdown_label'),
|
||||
choices = ['none'] + facefusion.choices.face_analyser_gender,
|
||||
value = facefusion.globals.face_analyser_gender or 'none'
|
||||
)
|
||||
ui.register_component('face_analyser_direction_dropdown', FACE_ANALYSER_DIRECTION_DROPDOWN)
|
||||
ui.register_component('face_analyser_age_dropdown', FACE_ANALYSER_AGE_DROPDOWN)
|
||||
ui.register_component('face_analyser_gender_dropdown', FACE_ANALYSER_GENDER_DROPDOWN)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
from typing import List, Optional, Tuple, Any, Dict
|
||||
|
||||
import cv2
|
||||
import gradio
|
||||
|
||||
import facefusion.choices
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.vision import get_video_frame, normalize_frame_color
|
||||
from facefusion.vision import get_video_frame, normalize_frame_color, read_static_image
|
||||
from facefusion.face_analyser import get_many_faces
|
||||
from facefusion.face_reference import clear_face_reference
|
||||
from facefusion.typing import Frame, FaceRecognition
|
||||
@@ -24,38 +23,37 @@ def render() -> None:
|
||||
global REFERENCE_FACE_POSITION_GALLERY
|
||||
global REFERENCE_FACE_DISTANCE_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
reference_face_gallery_args: Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('reference_face_gallery_label'),
|
||||
'height': 120,
|
||||
'object_fit': 'cover',
|
||||
'columns': 10,
|
||||
'allow_preview': False,
|
||||
'visible': 'reference' in facefusion.globals.face_recognition
|
||||
}
|
||||
if is_image(facefusion.globals.target_path):
|
||||
reference_frame = cv2.imread(facefusion.globals.target_path)
|
||||
reference_face_gallery_args['value'] = extract_gallery_frames(reference_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
reference_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
reference_face_gallery_args['value'] = extract_gallery_frames(reference_frame)
|
||||
FACE_RECOGNITION_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_recognition_dropdown_label'),
|
||||
choices = facefusion.choices.face_recognition,
|
||||
value = facefusion.globals.face_recognition
|
||||
)
|
||||
REFERENCE_FACE_POSITION_GALLERY = gradio.Gallery(**reference_face_gallery_args)
|
||||
REFERENCE_FACE_DISTANCE_SLIDER = gradio.Slider(
|
||||
label = wording.get('reference_face_distance_slider_label'),
|
||||
value = facefusion.globals.reference_face_distance,
|
||||
maximum = 3,
|
||||
step = 0.05,
|
||||
visible = 'reference' in facefusion.globals.face_recognition
|
||||
)
|
||||
ui.register_component('face_recognition_dropdown', FACE_RECOGNITION_DROPDOWN)
|
||||
ui.register_component('reference_face_position_gallery', REFERENCE_FACE_POSITION_GALLERY)
|
||||
ui.register_component('reference_face_distance_slider', REFERENCE_FACE_DISTANCE_SLIDER)
|
||||
reference_face_gallery_args: Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('reference_face_gallery_label'),
|
||||
'height': 120,
|
||||
'object_fit': 'cover',
|
||||
'columns': 10,
|
||||
'allow_preview': False,
|
||||
'visible': 'reference' in facefusion.globals.face_recognition
|
||||
}
|
||||
if is_image(facefusion.globals.target_path):
|
||||
reference_frame = read_static_image(facefusion.globals.target_path)
|
||||
reference_face_gallery_args['value'] = extract_gallery_frames(reference_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
reference_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
reference_face_gallery_args['value'] = extract_gallery_frames(reference_frame)
|
||||
FACE_RECOGNITION_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('face_recognition_dropdown_label'),
|
||||
choices = facefusion.choices.face_recognition,
|
||||
value = facefusion.globals.face_recognition
|
||||
)
|
||||
REFERENCE_FACE_POSITION_GALLERY = gradio.Gallery(**reference_face_gallery_args)
|
||||
REFERENCE_FACE_DISTANCE_SLIDER = gradio.Slider(
|
||||
label = wording.get('reference_face_distance_slider_label'),
|
||||
value = facefusion.globals.reference_face_distance,
|
||||
maximum = 3,
|
||||
step = 0.05,
|
||||
visible = 'reference' in facefusion.globals.face_recognition
|
||||
)
|
||||
ui.register_component('face_recognition_dropdown', FACE_RECOGNITION_DROPDOWN)
|
||||
ui.register_component('reference_face_position_gallery', REFERENCE_FACE_POSITION_GALLERY)
|
||||
ui.register_component('reference_face_distance_slider', REFERENCE_FACE_DISTANCE_SLIDER)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
@@ -106,7 +104,7 @@ def update_face_reference_position(reference_face_position : int = 0) -> Update:
|
||||
gallery_frames = []
|
||||
facefusion.globals.reference_face_position = reference_face_position
|
||||
if is_image(facefusion.globals.target_path):
|
||||
reference_frame = cv2.imread(facefusion.globals.target_path)
|
||||
reference_frame = read_static_image(facefusion.globals.target_path)
|
||||
gallery_frames = extract_gallery_frames(reference_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
reference_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
|
||||
@@ -11,13 +11,12 @@ MAX_MEMORY_SLIDER : Optional[gradio.Slider] = None
|
||||
def render() -> None:
|
||||
global MAX_MEMORY_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
MAX_MEMORY_SLIDER = gradio.Slider(
|
||||
label = wording.get('max_memory_slider_label'),
|
||||
minimum = 0,
|
||||
maximum = 128,
|
||||
step = 1
|
||||
)
|
||||
MAX_MEMORY_SLIDER = gradio.Slider(
|
||||
label = wording.get('max_memory_slider_label'),
|
||||
minimum = 0,
|
||||
maximum = 128,
|
||||
step = 1
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -22,23 +22,25 @@ def render() -> None:
|
||||
global OUTPUT_START_BUTTON
|
||||
global OUTPUT_CLEAR_BUTTON
|
||||
|
||||
with gradio.Row():
|
||||
with gradio.Box():
|
||||
OUTPUT_IMAGE = gradio.Image(
|
||||
label = wording.get('output_image_or_video_label'),
|
||||
visible = False
|
||||
)
|
||||
OUTPUT_VIDEO = gradio.Video(
|
||||
label = wording.get('output_image_or_video_label')
|
||||
)
|
||||
OUTPUT_PATH_TEXTBOX = gradio.Textbox(
|
||||
label = wording.get('output_path_textbox_label'),
|
||||
value = facefusion.globals.output_path or tempfile.gettempdir(),
|
||||
max_lines = 1
|
||||
)
|
||||
with gradio.Row():
|
||||
OUTPUT_START_BUTTON = gradio.Button(wording.get('start_button_label'))
|
||||
OUTPUT_CLEAR_BUTTON = gradio.Button(wording.get('clear_button_label'))
|
||||
OUTPUT_IMAGE = gradio.Image(
|
||||
label = wording.get('output_image_or_video_label'),
|
||||
visible = False
|
||||
)
|
||||
OUTPUT_VIDEO = gradio.Video(
|
||||
label = wording.get('output_image_or_video_label')
|
||||
)
|
||||
OUTPUT_PATH_TEXTBOX = gradio.Textbox(
|
||||
label = wording.get('output_path_textbox_label'),
|
||||
value = facefusion.globals.output_path or tempfile.gettempdir(),
|
||||
max_lines = 1
|
||||
)
|
||||
OUTPUT_START_BUTTON = gradio.Button(
|
||||
value = wording.get('start_button_label'),
|
||||
variant = 'primary'
|
||||
)
|
||||
OUTPUT_CLEAR_BUTTON = gradio.Button(
|
||||
value = wording.get('clear_button_label'),
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -19,25 +19,24 @@ def render() -> None:
|
||||
global OUTPUT_VIDEO_ENCODER_DROPDOWN
|
||||
global OUTPUT_VIDEO_QUALITY_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
OUTPUT_IMAGE_QUALITY_SLIDER = gradio.Slider(
|
||||
label = wording.get('output_image_quality_slider_label'),
|
||||
value = facefusion.globals.output_image_quality,
|
||||
step = 1,
|
||||
visible = is_image(facefusion.globals.target_path)
|
||||
)
|
||||
OUTPUT_VIDEO_ENCODER_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('output_video_encoder_dropdown_label'),
|
||||
choices = facefusion.choices.output_video_encoder,
|
||||
value = facefusion.globals.output_video_encoder,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
OUTPUT_VIDEO_QUALITY_SLIDER = gradio.Slider(
|
||||
label = wording.get('output_video_quality_slider_label'),
|
||||
value = facefusion.globals.output_video_quality,
|
||||
step = 1,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
OUTPUT_IMAGE_QUALITY_SLIDER = gradio.Slider(
|
||||
label = wording.get('output_image_quality_slider_label'),
|
||||
value = facefusion.globals.output_image_quality,
|
||||
step = 1,
|
||||
visible = is_image(facefusion.globals.target_path)
|
||||
)
|
||||
OUTPUT_VIDEO_ENCODER_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('output_video_encoder_dropdown_label'),
|
||||
choices = facefusion.choices.output_video_encoder,
|
||||
value = facefusion.globals.output_video_encoder,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
OUTPUT_VIDEO_QUALITY_SLIDER = gradio.Slider(
|
||||
label = wording.get('output_video_quality_slider_label'),
|
||||
value = facefusion.globals.output_video_quality,
|
||||
step = 1,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -4,12 +4,12 @@ import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.vision import get_video_frame, count_video_frame_total, normalize_frame_color, resize_frame_dimension
|
||||
from facefusion.vision import get_video_frame, count_video_frame_total, normalize_frame_color, resize_frame_dimension, read_static_image
|
||||
from facefusion.face_analyser import get_one_face
|
||||
from facefusion.face_reference import get_face_reference, set_face_reference
|
||||
from facefusion.predictor import predict_frame
|
||||
from facefusion.processors.frame.core import load_frame_processor_module
|
||||
from facefusion.typing import Frame
|
||||
from facefusion.typing import Frame, Face
|
||||
from facefusion.uis import core as ui
|
||||
from facefusion.uis.typing import ComponentName, Update
|
||||
from facefusion.utilities import is_video, is_image
|
||||
@@ -22,32 +22,34 @@ def render() -> None:
|
||||
global PREVIEW_IMAGE
|
||||
global PREVIEW_FRAME_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
preview_image_args: Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('preview_image_label')
|
||||
}
|
||||
preview_frame_slider_args: Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('preview_frame_slider_label'),
|
||||
'step': 1,
|
||||
'visible': False
|
||||
}
|
||||
if is_image(facefusion.globals.target_path):
|
||||
target_frame = cv2.imread(facefusion.globals.target_path)
|
||||
preview_frame = process_preview_frame(target_frame)
|
||||
preview_image_args['value'] = normalize_frame_color(preview_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
temp_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
preview_frame = process_preview_frame(temp_frame)
|
||||
preview_image_args['value'] = normalize_frame_color(preview_frame)
|
||||
preview_image_args['visible'] = True
|
||||
preview_frame_slider_args['value'] = facefusion.globals.reference_frame_number
|
||||
preview_frame_slider_args['maximum'] = count_video_frame_total(facefusion.globals.target_path)
|
||||
preview_frame_slider_args['visible'] = True
|
||||
PREVIEW_IMAGE = gradio.Image(**preview_image_args)
|
||||
PREVIEW_FRAME_SLIDER = gradio.Slider(**preview_frame_slider_args)
|
||||
ui.register_component('preview_frame_slider', PREVIEW_FRAME_SLIDER)
|
||||
preview_image_args: Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('preview_image_label')
|
||||
}
|
||||
preview_frame_slider_args: Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('preview_frame_slider_label'),
|
||||
'step': 1,
|
||||
'visible': False
|
||||
}
|
||||
conditional_set_face_reference()
|
||||
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
|
||||
reference_face = get_face_reference() if 'reference' in facefusion.globals.face_recognition else None
|
||||
if is_image(facefusion.globals.target_path):
|
||||
target_frame = read_static_image(facefusion.globals.target_path)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, target_frame)
|
||||
preview_image_args['value'] = normalize_frame_color(preview_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
temp_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, temp_frame)
|
||||
preview_image_args['value'] = normalize_frame_color(preview_frame)
|
||||
preview_image_args['visible'] = True
|
||||
preview_frame_slider_args['value'] = facefusion.globals.reference_frame_number
|
||||
preview_frame_slider_args['maximum'] = count_video_frame_total(facefusion.globals.target_path)
|
||||
preview_frame_slider_args['visible'] = True
|
||||
PREVIEW_IMAGE = gradio.Image(**preview_image_args)
|
||||
PREVIEW_FRAME_SLIDER = gradio.Slider(**preview_frame_slider_args)
|
||||
ui.register_component('preview_frame_slider', PREVIEW_FRAME_SLIDER)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
@@ -90,17 +92,18 @@ def listen() -> None:
|
||||
|
||||
|
||||
def update_preview_image(frame_number : int = 0) -> Update:
|
||||
conditional_set_face_reference()
|
||||
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
|
||||
reference_face = get_face_reference() if 'reference' in facefusion.globals.face_recognition else None
|
||||
if is_image(facefusion.globals.target_path):
|
||||
conditional_set_face_reference()
|
||||
target_frame = cv2.imread(facefusion.globals.target_path)
|
||||
preview_frame = process_preview_frame(target_frame)
|
||||
target_frame = read_static_image(facefusion.globals.target_path)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, target_frame)
|
||||
preview_frame = normalize_frame_color(preview_frame)
|
||||
return gradio.update(value = preview_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
conditional_set_face_reference()
|
||||
facefusion.globals.reference_frame_number = frame_number
|
||||
temp_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
preview_frame = process_preview_frame(temp_frame)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, temp_frame)
|
||||
preview_frame = normalize_frame_color(preview_frame)
|
||||
return gradio.update(value = preview_frame)
|
||||
return gradio.update(value = None)
|
||||
@@ -116,11 +119,9 @@ def update_preview_frame_slider(frame_number : int = 0) -> Update:
|
||||
return gradio.update(value = None, maximum = None, visible = False)
|
||||
|
||||
|
||||
def process_preview_frame(temp_frame : Frame) -> Frame:
|
||||
def process_preview_frame(source_face : Face, reference_face : Face, temp_frame : Frame) -> Frame:
|
||||
if predict_frame(temp_frame):
|
||||
return cv2.GaussianBlur(temp_frame, (99, 99), 0)
|
||||
source_face = get_one_face(cv2.imread(facefusion.globals.source_path)) if facefusion.globals.source_path else None
|
||||
reference_face = get_face_reference() if 'reference' in facefusion.globals.face_recognition else None
|
||||
temp_frame = resize_frame_dimension(temp_frame, 480)
|
||||
for frame_processor in facefusion.globals.frame_processors:
|
||||
frame_processor_module = load_frame_processor_module(frame_processor)
|
||||
|
||||
@@ -14,13 +14,12 @@ FRAME_PROCESSORS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
def render() -> None:
|
||||
global FRAME_PROCESSORS_CHECKBOX_GROUP
|
||||
|
||||
with gradio.Box():
|
||||
FRAME_PROCESSORS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('frame_processors_checkbox_group_label'),
|
||||
choices = sort_frame_processors(facefusion.globals.frame_processors),
|
||||
value = facefusion.globals.frame_processors
|
||||
)
|
||||
ui.register_component('frame_processors_checkbox_group', FRAME_PROCESSORS_CHECKBOX_GROUP)
|
||||
FRAME_PROCESSORS_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('frame_processors_checkbox_group_label'),
|
||||
choices = sort_frame_processors(facefusion.globals.frame_processors),
|
||||
value = facefusion.globals.frame_processors
|
||||
)
|
||||
ui.register_component('frame_processors_checkbox_group', FRAME_PROCESSORS_CHECKBOX_GROUP)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -1,41 +1,37 @@
|
||||
from typing import Optional
|
||||
from typing import Optional, List
|
||||
import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.uis import choices
|
||||
from facefusion.uis.typing import Update
|
||||
|
||||
KEEP_FPS_CHECKBOX : Optional[gradio.Checkbox] = None
|
||||
KEEP_TEMP_CHECKBOX : Optional[gradio.Checkbox] = None
|
||||
SKIP_AUDIO_CHECKBOX : Optional[gradio.Checkbox] = None
|
||||
SETTINGS_CHECKBOX_GROUP : Optional[gradio.Checkboxgroup] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global KEEP_FPS_CHECKBOX
|
||||
global KEEP_TEMP_CHECKBOX
|
||||
global SKIP_AUDIO_CHECKBOX
|
||||
global SETTINGS_CHECKBOX_GROUP
|
||||
|
||||
with gradio.Box():
|
||||
KEEP_FPS_CHECKBOX = gradio.Checkbox(
|
||||
label = wording.get('keep_fps_checkbox_label'),
|
||||
value = facefusion.globals.keep_fps
|
||||
)
|
||||
KEEP_TEMP_CHECKBOX = gradio.Checkbox(
|
||||
label = wording.get('keep_temp_checkbox_label'),
|
||||
value = facefusion.globals.keep_temp
|
||||
)
|
||||
SKIP_AUDIO_CHECKBOX = gradio.Checkbox(
|
||||
label = wording.get('skip_audio_checkbox_label'),
|
||||
value = facefusion.globals.skip_audio
|
||||
)
|
||||
value = []
|
||||
if facefusion.globals.keep_fps:
|
||||
value.append('keep-fps')
|
||||
if facefusion.globals.keep_temp:
|
||||
value.append('keep-temp')
|
||||
if facefusion.globals.skip_audio:
|
||||
value.append('skip-audio')
|
||||
SETTINGS_CHECKBOX_GROUP = gradio.Checkboxgroup(
|
||||
label = wording.get('settings_checkbox_group_label'),
|
||||
choices = choices.settings,
|
||||
value = value
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
KEEP_FPS_CHECKBOX.change(lambda value: update_checkbox('keep_fps', value), inputs = KEEP_FPS_CHECKBOX, outputs = KEEP_FPS_CHECKBOX)
|
||||
KEEP_TEMP_CHECKBOX.change(lambda value: update_checkbox('keep_temp', value), inputs = KEEP_TEMP_CHECKBOX, outputs = KEEP_TEMP_CHECKBOX)
|
||||
SKIP_AUDIO_CHECKBOX.change(lambda value: update_checkbox('skip_audio', value), inputs = SKIP_AUDIO_CHECKBOX, outputs = SKIP_AUDIO_CHECKBOX)
|
||||
SETTINGS_CHECKBOX_GROUP.change(update, inputs = SETTINGS_CHECKBOX_GROUP, outputs = SETTINGS_CHECKBOX_GROUP)
|
||||
|
||||
|
||||
def update_checkbox(name : str, value: bool) -> Update:
|
||||
setattr(facefusion.globals, name, value)
|
||||
return gradio.update(value = value)
|
||||
def update(settings : List[str]) -> Update:
|
||||
facefusion.globals.keep_fps = 'keep-fps' in settings
|
||||
facefusion.globals.keep_temp = 'keep-temp' in settings
|
||||
facefusion.globals.skip_audio = 'skip-audio' in settings
|
||||
return gradio.update(value = settings)
|
||||
|
||||
@@ -15,25 +15,24 @@ def render() -> None:
|
||||
global SOURCE_FILE
|
||||
global SOURCE_IMAGE
|
||||
|
||||
with gradio.Box():
|
||||
is_source_image = is_image(facefusion.globals.source_path)
|
||||
SOURCE_FILE = gradio.File(
|
||||
file_count = 'single',
|
||||
file_types =
|
||||
[
|
||||
'.png',
|
||||
'.jpg',
|
||||
'.webp'
|
||||
],
|
||||
label = wording.get('source_file_label'),
|
||||
value = facefusion.globals.source_path if is_source_image else None
|
||||
)
|
||||
SOURCE_IMAGE = gradio.Image(
|
||||
value = SOURCE_FILE.value['name'] if is_source_image else None,
|
||||
visible = is_source_image,
|
||||
show_label = False
|
||||
)
|
||||
ui.register_component('source_image', SOURCE_IMAGE)
|
||||
is_source_image = is_image(facefusion.globals.source_path)
|
||||
SOURCE_FILE = gradio.File(
|
||||
file_count = 'single',
|
||||
file_types =
|
||||
[
|
||||
'.png',
|
||||
'.jpg',
|
||||
'.webp'
|
||||
],
|
||||
label = wording.get('source_file_label'),
|
||||
value = facefusion.globals.source_path if is_source_image else None
|
||||
)
|
||||
SOURCE_IMAGE = gradio.Image(
|
||||
value = SOURCE_FILE.value['name'] if is_source_image else None,
|
||||
visible = is_source_image,
|
||||
show_label = False
|
||||
)
|
||||
ui.register_component('source_image', SOURCE_IMAGE)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -18,33 +18,32 @@ def render() -> None:
|
||||
global TARGET_IMAGE
|
||||
global TARGET_VIDEO
|
||||
|
||||
with gradio.Box():
|
||||
is_target_image = is_image(facefusion.globals.target_path)
|
||||
is_target_video = is_video(facefusion.globals.target_path)
|
||||
TARGET_FILE = gradio.File(
|
||||
label = wording.get('target_file_label'),
|
||||
file_count = 'single',
|
||||
file_types =
|
||||
[
|
||||
'.png',
|
||||
'.jpg',
|
||||
'.webp',
|
||||
'.mp4'
|
||||
],
|
||||
value = facefusion.globals.target_path if is_target_image or is_target_video else None
|
||||
)
|
||||
TARGET_IMAGE = gradio.Image(
|
||||
value = TARGET_FILE.value['name'] if is_target_image else None,
|
||||
visible = is_target_image,
|
||||
show_label = False
|
||||
)
|
||||
TARGET_VIDEO = gradio.Video(
|
||||
value = TARGET_FILE.value['name'] if is_target_video else None,
|
||||
visible = is_target_video,
|
||||
show_label = False
|
||||
)
|
||||
ui.register_component('target_image', TARGET_IMAGE)
|
||||
ui.register_component('target_video', TARGET_VIDEO)
|
||||
is_target_image = is_image(facefusion.globals.target_path)
|
||||
is_target_video = is_video(facefusion.globals.target_path)
|
||||
TARGET_FILE = gradio.File(
|
||||
label = wording.get('target_file_label'),
|
||||
file_count = 'single',
|
||||
file_types =
|
||||
[
|
||||
'.png',
|
||||
'.jpg',
|
||||
'.webp',
|
||||
'.mp4'
|
||||
],
|
||||
value = facefusion.globals.target_path if is_target_image or is_target_video else None
|
||||
)
|
||||
TARGET_IMAGE = gradio.Image(
|
||||
value = TARGET_FILE.value['name'] if is_target_image else None,
|
||||
visible = is_target_image,
|
||||
show_label = False
|
||||
)
|
||||
TARGET_VIDEO = gradio.Video(
|
||||
value = TARGET_FILE.value['name'] if is_target_video else None,
|
||||
visible = is_target_video,
|
||||
show_label = False
|
||||
)
|
||||
ui.register_component('target_image', TARGET_IMAGE)
|
||||
ui.register_component('target_video', TARGET_VIDEO)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -17,19 +17,18 @@ def render() -> None:
|
||||
global TEMP_FRAME_FORMAT_DROPDOWN
|
||||
global TEMP_FRAME_QUALITY_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
TEMP_FRAME_FORMAT_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('temp_frame_format_dropdown_label'),
|
||||
choices = facefusion.choices.temp_frame_format,
|
||||
value = facefusion.globals.temp_frame_format,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
TEMP_FRAME_QUALITY_SLIDER = gradio.Slider(
|
||||
label = wording.get('temp_frame_quality_slider_label'),
|
||||
value = facefusion.globals.temp_frame_quality,
|
||||
step = 1,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
TEMP_FRAME_FORMAT_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('temp_frame_format_dropdown_label'),
|
||||
choices = facefusion.choices.temp_frame_format,
|
||||
value = facefusion.globals.temp_frame_format,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
TEMP_FRAME_QUALITY_SLIDER = gradio.Slider(
|
||||
label = wording.get('temp_frame_quality_slider_label'),
|
||||
value = facefusion.globals.temp_frame_quality,
|
||||
step = 1,
|
||||
visible = is_video(facefusion.globals.target_path)
|
||||
)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -16,30 +16,28 @@ def render() -> None:
|
||||
global TRIM_FRAME_START_SLIDER
|
||||
global TRIM_FRAME_END_SLIDER
|
||||
|
||||
with gradio.Box():
|
||||
trim_frame_start_slider_args : Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('trim_frame_start_slider_label'),
|
||||
'step': 1,
|
||||
'visible': False
|
||||
}
|
||||
trim_frame_end_slider_args : Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('trim_frame_end_slider_label'),
|
||||
'step': 1,
|
||||
'visible': False
|
||||
}
|
||||
if is_video(facefusion.globals.target_path):
|
||||
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
|
||||
trim_frame_start_slider_args['value'] = facefusion.globals.trim_frame_start or 0
|
||||
trim_frame_start_slider_args['maximum'] = video_frame_total
|
||||
trim_frame_start_slider_args['visible'] = True
|
||||
trim_frame_end_slider_args['value'] = facefusion.globals.trim_frame_end or video_frame_total
|
||||
trim_frame_end_slider_args['maximum'] = video_frame_total
|
||||
trim_frame_end_slider_args['visible'] = True
|
||||
with gradio.Row():
|
||||
TRIM_FRAME_START_SLIDER = gradio.Slider(**trim_frame_start_slider_args)
|
||||
TRIM_FRAME_END_SLIDER = gradio.Slider(**trim_frame_end_slider_args)
|
||||
trim_frame_start_slider_args : Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('trim_frame_start_slider_label'),
|
||||
'step': 1,
|
||||
'visible': False
|
||||
}
|
||||
trim_frame_end_slider_args : Dict[str, Any] =\
|
||||
{
|
||||
'label': wording.get('trim_frame_end_slider_label'),
|
||||
'step': 1,
|
||||
'visible': False
|
||||
}
|
||||
if is_video(facefusion.globals.target_path):
|
||||
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
|
||||
trim_frame_start_slider_args['value'] = facefusion.globals.trim_frame_start or 0
|
||||
trim_frame_start_slider_args['maximum'] = video_frame_total
|
||||
trim_frame_start_slider_args['visible'] = True
|
||||
trim_frame_end_slider_args['value'] = facefusion.globals.trim_frame_end or video_frame_total
|
||||
trim_frame_end_slider_args['maximum'] = video_frame_total
|
||||
trim_frame_end_slider_args['visible'] = True
|
||||
TRIM_FRAME_START_SLIDER = gradio.Slider(**trim_frame_start_slider_args)
|
||||
TRIM_FRAME_END_SLIDER = gradio.Slider(**trim_frame_end_slider_args)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
|
||||
@@ -1,87 +1,114 @@
|
||||
from typing import Optional, Generator
|
||||
from typing import Optional, Generator, Deque
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from collections import deque
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import cv2
|
||||
import gradio
|
||||
from tqdm import tqdm
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.typing import Frame
|
||||
from facefusion.typing import Frame, Face
|
||||
from facefusion.face_analyser import get_one_face
|
||||
from facefusion.processors.frame.core import load_frame_processor_module
|
||||
from facefusion.uis import core as ui
|
||||
from facefusion.uis.typing import StreamMode, WebcamMode, Update
|
||||
from facefusion.utilities import open_ffmpeg
|
||||
from facefusion.vision import normalize_frame_color
|
||||
from facefusion.vision import normalize_frame_color, read_static_image
|
||||
|
||||
WEBCAM_IMAGE : Optional[gradio.Image] = None
|
||||
WEBCAM_MODE_RADIO : Optional[gradio.Radio] = None
|
||||
WEBCAM_START_BUTTON : Optional[gradio.Button] = None
|
||||
WEBCAM_STOP_BUTTON : Optional[gradio.Button] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global WEBCAM_IMAGE
|
||||
global WEBCAM_MODE_RADIO
|
||||
global WEBCAM_START_BUTTON
|
||||
global WEBCAM_STOP_BUTTON
|
||||
|
||||
WEBCAM_IMAGE = gradio.Image(
|
||||
label = wording.get('webcam_image_label')
|
||||
)
|
||||
WEBCAM_MODE_RADIO = gradio.Radio(
|
||||
label = wording.get('webcam_mode_radio_label'),
|
||||
choices = [ 'inline', 'stream_udp', 'stream_v4l2' ],
|
||||
value = 'inline'
|
||||
WEBCAM_START_BUTTON = gradio.Button(
|
||||
value = wording.get('start_button_label'),
|
||||
variant = 'primary'
|
||||
)
|
||||
WEBCAM_STOP_BUTTON = gradio.Button(
|
||||
value = wording.get('stop_button_label')
|
||||
)
|
||||
WEBCAM_START_BUTTON = gradio.Button(wording.get('start_button_label'))
|
||||
WEBCAM_STOP_BUTTON = gradio.Button(wording.get('stop_button_label'))
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
start_event = WEBCAM_START_BUTTON.click(start, inputs = WEBCAM_MODE_RADIO, outputs = WEBCAM_IMAGE)
|
||||
WEBCAM_MODE_RADIO.change(update, outputs = WEBCAM_IMAGE, cancels = start_event)
|
||||
WEBCAM_STOP_BUTTON.click(None, cancels = start_event)
|
||||
start_event = None
|
||||
webcam_mode_radio = ui.get_component('webcam_mode_radio')
|
||||
webcam_resolution_dropdown = ui.get_component('webcam_resolution_dropdown')
|
||||
webcam_fps_slider = ui.get_component('webcam_fps_slider')
|
||||
if webcam_mode_radio and webcam_resolution_dropdown and webcam_fps_slider:
|
||||
start_event = WEBCAM_START_BUTTON.click(start, inputs = [ webcam_mode_radio, webcam_resolution_dropdown, webcam_fps_slider ], outputs = WEBCAM_IMAGE)
|
||||
webcam_mode_radio.change(stop, outputs = WEBCAM_IMAGE, cancels = start_event)
|
||||
webcam_resolution_dropdown.change(stop, outputs = WEBCAM_IMAGE, cancels = start_event)
|
||||
webcam_fps_slider.change(stop, outputs = WEBCAM_IMAGE, cancels = start_event)
|
||||
WEBCAM_STOP_BUTTON.click(stop, cancels = start_event)
|
||||
source_image = ui.get_component('source_image')
|
||||
if source_image:
|
||||
for method in [ 'upload', 'change', 'clear' ]:
|
||||
getattr(source_image, method)(stop, cancels = start_event)
|
||||
|
||||
|
||||
def update() -> Update:
|
||||
def start(mode: WebcamMode, resolution: str, fps: float) -> Generator[Frame, None, None]:
|
||||
facefusion.globals.face_recognition = 'many'
|
||||
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
|
||||
stream = None
|
||||
if mode == 'stream_udp':
|
||||
stream = open_stream('udp', resolution, fps)
|
||||
if mode == 'stream_v4l2':
|
||||
stream = open_stream('v4l2', resolution, fps)
|
||||
capture = capture_webcam(resolution, fps)
|
||||
if capture.isOpened():
|
||||
for capture_frame in multi_process_capture(source_face, capture):
|
||||
if stream is not None:
|
||||
stream.stdin.write(capture_frame.tobytes())
|
||||
yield normalize_frame_color(capture_frame)
|
||||
|
||||
|
||||
def multi_process_capture(source_face: Face, capture : cv2.VideoCapture) -> Generator[Frame, None, None]:
|
||||
progress = tqdm(desc = wording.get('processing'), unit = 'frame', dynamic_ncols = True)
|
||||
with ThreadPoolExecutor(max_workers = facefusion.globals.execution_thread_count) as executor:
|
||||
futures = []
|
||||
deque_capture_frames : Deque[Frame] = deque()
|
||||
while True:
|
||||
_, capture_frame = capture.read()
|
||||
future = executor.submit(process_stream_frame, source_face, capture_frame)
|
||||
futures.append(future)
|
||||
for future_done in [ future for future in futures if future.done() ]:
|
||||
capture_frame = future_done.result()
|
||||
deque_capture_frames.append(capture_frame)
|
||||
futures.remove(future_done)
|
||||
while deque_capture_frames:
|
||||
yield deque_capture_frames.popleft()
|
||||
progress.update()
|
||||
|
||||
|
||||
def stop() -> Update:
|
||||
return gradio.update(value = None)
|
||||
|
||||
|
||||
def start(webcam_mode : WebcamMode) -> Generator[Frame, None, None]:
|
||||
if webcam_mode == 'inline':
|
||||
yield from start_inline()
|
||||
if webcam_mode == 'stream_udp':
|
||||
yield from start_stream('udp')
|
||||
if webcam_mode == 'stream_v4l2':
|
||||
yield from start_stream('v4l2')
|
||||
def capture_webcam(resolution : str, fps : float) -> cv2.VideoCapture:
|
||||
width, height = resolution.split('x')
|
||||
if platform.system().lower() == 'windows':
|
||||
capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
|
||||
else:
|
||||
capture = cv2.VideoCapture(0)
|
||||
capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) # type: ignore[attr-defined]
|
||||
capture.set(cv2.CAP_PROP_FRAME_WIDTH, int(width))
|
||||
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, int(height))
|
||||
capture.set(cv2.CAP_PROP_FPS, fps)
|
||||
return capture
|
||||
|
||||
|
||||
def start_inline() -> Generator[Frame, None, None]:
|
||||
facefusion.globals.face_recognition = 'many'
|
||||
capture = cv2.VideoCapture(0)
|
||||
if capture.isOpened():
|
||||
while True:
|
||||
_, temp_frame = capture.read()
|
||||
temp_frame = process_stream_frame(temp_frame)
|
||||
if temp_frame is not None:
|
||||
yield normalize_frame_color(temp_frame)
|
||||
|
||||
|
||||
def start_stream(mode : StreamMode) -> Generator[None, None, None]:
|
||||
facefusion.globals.face_recognition = 'many'
|
||||
capture = cv2.VideoCapture(0)
|
||||
ffmpeg_process = open_stream(mode)
|
||||
if capture.isOpened():
|
||||
while True:
|
||||
_, frame = capture.read()
|
||||
temp_frame = process_stream_frame(frame)
|
||||
if temp_frame is not None:
|
||||
ffmpeg_process.stdin.write(temp_frame.tobytes())
|
||||
yield normalize_frame_color(temp_frame)
|
||||
|
||||
|
||||
def process_stream_frame(temp_frame : Frame) -> Frame:
|
||||
source_face = get_one_face(cv2.imread(facefusion.globals.source_path)) if facefusion.globals.source_path else None
|
||||
def process_stream_frame(source_face : Face, temp_frame : Frame) -> Frame:
|
||||
for frame_processor in facefusion.globals.frame_processors:
|
||||
frame_processor_module = load_frame_processor_module(frame_processor)
|
||||
if frame_processor_module.pre_process('stream'):
|
||||
@@ -93,8 +120,8 @@ def process_stream_frame(temp_frame : Frame) -> Frame:
|
||||
return temp_frame
|
||||
|
||||
|
||||
def open_stream(mode : StreamMode) -> subprocess.Popen[bytes]:
|
||||
commands = [ '-f', 'rawvideo', '-pix_fmt', 'bgr24', '-s', '640x480', '-r', '30', '-i', '-' ]
|
||||
def open_stream(mode : StreamMode, resolution : str, fps : float) -> subprocess.Popen[bytes]:
|
||||
commands = [ '-f', 'rawvideo', '-pix_fmt', 'bgr24', '-s', resolution, '-r', str(fps), '-i', '-' ]
|
||||
if mode == 'udp':
|
||||
commands.extend([ '-b:v', '2000k', '-f', 'mpegts', 'udp://localhost:27000?pkt_size=1316' ])
|
||||
if mode == 'v4l2':
|
||||
|
||||
42
facefusion/uis/components/webcam_settings.py
Normal file
42
facefusion/uis/components/webcam_settings.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from typing import Optional
|
||||
import gradio
|
||||
|
||||
from facefusion import wording
|
||||
from facefusion.uis import choices
|
||||
from facefusion.uis import core as ui
|
||||
from facefusion.uis.typing import Update
|
||||
|
||||
WEBCAM_MODE_RADIO : Optional[gradio.Radio] = None
|
||||
WEBCAM_RESOLUTION_DROPDOWN : Optional[gradio.Dropdown] = None
|
||||
WEBCAM_FPS_SLIDER : Optional[gradio.Slider] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global WEBCAM_MODE_RADIO
|
||||
global WEBCAM_RESOLUTION_DROPDOWN
|
||||
global WEBCAM_FPS_SLIDER
|
||||
|
||||
WEBCAM_MODE_RADIO = gradio.Radio(
|
||||
label = wording.get('webcam_mode_radio_label'),
|
||||
choices = choices.webcam_mode,
|
||||
value = 'inline'
|
||||
)
|
||||
WEBCAM_RESOLUTION_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('webcam_resolution_dropdown'),
|
||||
choices = choices.webcam_resolution,
|
||||
value = choices.webcam_resolution[0]
|
||||
)
|
||||
WEBCAM_FPS_SLIDER = gradio.Slider(
|
||||
label = wording.get('webcam_fps_slider'),
|
||||
minimum = 1,
|
||||
maximum = 60,
|
||||
step = 1,
|
||||
value = 25
|
||||
)
|
||||
ui.register_component('webcam_mode_radio', WEBCAM_MODE_RADIO)
|
||||
ui.register_component('webcam_resolution_dropdown', WEBCAM_RESOLUTION_DROPDOWN)
|
||||
ui.register_component('webcam_fps_slider', WEBCAM_FPS_SLIDER)
|
||||
|
||||
|
||||
def update() -> Update:
|
||||
return gradio.update(value = None)
|
||||
@@ -1,6 +1,6 @@
|
||||
import gradio
|
||||
|
||||
from facefusion.uis.components import about, processors, execution, limit_resources, benchmark
|
||||
from facefusion.uis.components import about, processors, execution, execution_thread_count, execution_queue_count, limit_resources, benchmark_settings, benchmark
|
||||
from facefusion.utilities import conditional_download
|
||||
|
||||
|
||||
@@ -27,19 +27,31 @@ def render() -> gradio.Blocks:
|
||||
with gradio.Blocks() as layout:
|
||||
with gradio.Row():
|
||||
with gradio.Column(scale = 2):
|
||||
about.render()
|
||||
processors.render()
|
||||
execution.render()
|
||||
limit_resources.render()
|
||||
with gradio.Box():
|
||||
about.render()
|
||||
with gradio.Blocks():
|
||||
processors.render()
|
||||
with gradio.Blocks():
|
||||
execution.render()
|
||||
execution_thread_count.render()
|
||||
execution_queue_count.render()
|
||||
with gradio.Blocks():
|
||||
limit_resources.render()
|
||||
with gradio.Blocks():
|
||||
benchmark_settings.render()
|
||||
with gradio.Column(scale= 5):
|
||||
benchmark.render()
|
||||
with gradio.Blocks():
|
||||
benchmark.render()
|
||||
return layout
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
processors.listen()
|
||||
execution.listen()
|
||||
execution_thread_count.listen()
|
||||
execution_queue_count.listen()
|
||||
limit_resources.listen()
|
||||
benchmark_settings.listen()
|
||||
benchmark.listen()
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import gradio
|
||||
|
||||
from facefusion.uis.components import about, processors, execution, limit_resources, temp_frame, output_settings, settings, source, target, preview, trim_frame, face_analyser, face_selector, output
|
||||
from facefusion.uis.components import about, processors, execution, execution_thread_count, execution_queue_count, limit_resources, temp_frame, output_settings, settings, source, target, preview, trim_frame, face_analyser, face_selector, output
|
||||
|
||||
|
||||
def pre_check() -> bool:
|
||||
@@ -15,28 +15,46 @@ def render() -> gradio.Blocks:
|
||||
with gradio.Blocks() as layout:
|
||||
with gradio.Row():
|
||||
with gradio.Column(scale = 2):
|
||||
about.render()
|
||||
processors.render()
|
||||
execution.render()
|
||||
limit_resources.render()
|
||||
temp_frame.render()
|
||||
output_settings.render()
|
||||
settings.render()
|
||||
with gradio.Box():
|
||||
about.render()
|
||||
with gradio.Blocks():
|
||||
processors.render()
|
||||
with gradio.Blocks():
|
||||
execution.render()
|
||||
execution_thread_count.render()
|
||||
execution_queue_count.render()
|
||||
with gradio.Blocks():
|
||||
limit_resources.render()
|
||||
with gradio.Blocks():
|
||||
temp_frame.render()
|
||||
with gradio.Blocks():
|
||||
output_settings.render()
|
||||
with gradio.Blocks():
|
||||
settings.render()
|
||||
with gradio.Column(scale = 2):
|
||||
source.render()
|
||||
target.render()
|
||||
output.render()
|
||||
with gradio.Blocks():
|
||||
source.render()
|
||||
with gradio.Blocks():
|
||||
target.render()
|
||||
with gradio.Blocks():
|
||||
output.render()
|
||||
with gradio.Column(scale = 3):
|
||||
preview.render()
|
||||
trim_frame.render()
|
||||
face_selector.render()
|
||||
face_analyser.render()
|
||||
with gradio.Blocks():
|
||||
preview.render()
|
||||
with gradio.Row():
|
||||
trim_frame.render()
|
||||
with gradio.Blocks():
|
||||
face_selector.render()
|
||||
with gradio.Row():
|
||||
face_analyser.render()
|
||||
return layout
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
processors.listen()
|
||||
execution.listen()
|
||||
execution_thread_count.listen()
|
||||
execution_queue_count.listen()
|
||||
limit_resources.listen()
|
||||
temp_frame.listen()
|
||||
output_settings.listen()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import gradio
|
||||
|
||||
from facefusion.uis.components import about, processors, execution, limit_resources, source, webcam
|
||||
from facefusion.uis.components import about, processors, execution, execution_thread_count, webcam_settings, source, webcam
|
||||
|
||||
|
||||
def pre_check() -> bool:
|
||||
@@ -15,20 +15,27 @@ def render() -> gradio.Blocks:
|
||||
with gradio.Blocks() as layout:
|
||||
with gradio.Row():
|
||||
with gradio.Column(scale = 2):
|
||||
about.render()
|
||||
processors.render()
|
||||
execution.render()
|
||||
limit_resources.render()
|
||||
source.render()
|
||||
with gradio.Box():
|
||||
about.render()
|
||||
with gradio.Blocks():
|
||||
processors.render()
|
||||
with gradio.Blocks():
|
||||
execution.render()
|
||||
execution_thread_count.render()
|
||||
with gradio.Blocks():
|
||||
webcam_settings.render()
|
||||
with gradio.Blocks():
|
||||
source.render()
|
||||
with gradio.Column(scale = 5):
|
||||
webcam.render()
|
||||
with gradio.Blocks():
|
||||
webcam.render()
|
||||
return layout
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
processors.listen()
|
||||
execution.listen()
|
||||
limit_resources.listen()
|
||||
execution_thread_count.listen()
|
||||
source.listen()
|
||||
webcam.listen()
|
||||
|
||||
|
||||
@@ -14,8 +14,13 @@ ComponentName = Literal\
|
||||
'face_analyser_direction_dropdown',
|
||||
'face_analyser_age_dropdown',
|
||||
'face_analyser_gender_dropdown',
|
||||
'frame_processors_checkbox_group'
|
||||
'frame_processors_checkbox_group',
|
||||
'benchmark_runs_checkbox_group',
|
||||
'benchmark_cycles_slider',
|
||||
'webcam_mode_radio',
|
||||
'webcam_resolution_dropdown',
|
||||
'webcam_fps_slider'
|
||||
]
|
||||
WebcamMode = Literal[ 'inline', 'stream_udp', 'stream_v4l2' ]
|
||||
StreamMode = Literal['udp', 'v4l2']
|
||||
StreamMode = Literal[ 'udp', 'v4l2' ]
|
||||
Update = Dict[Any, Any]
|
||||
|
||||
Reference in New Issue
Block a user