mirror of
https://github.com/facefusion/facefusion.git
synced 2026-07-28 12:59:03 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
666c15f9da | ||
|
|
420d738a6b |
@@ -3,7 +3,7 @@ import os
|
|||||||
import statistics
|
import statistics
|
||||||
import tempfile
|
import tempfile
|
||||||
from time import perf_counter
|
from time import perf_counter
|
||||||
from typing import Generator, List
|
from typing import Iterator, List
|
||||||
|
|
||||||
import facefusion.choices
|
import facefusion.choices
|
||||||
from facefusion import content_analyser, core, state_manager
|
from facefusion import content_analyser, core, state_manager
|
||||||
@@ -31,7 +31,7 @@ def pre_check() -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def run() -> Generator[List[BenchmarkCycleSet], None, None]:
|
def run() -> Iterator[List[BenchmarkCycleSet]]:
|
||||||
benchmark_resolutions = state_manager.get_item('benchmark_resolutions')
|
benchmark_resolutions = state_manager.get_item('benchmark_resolutions')
|
||||||
benchmark_cycle_count = state_manager.get_item('benchmark_cycle_count')
|
benchmark_cycle_count = state_manager.get_item('benchmark_cycle_count')
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ def chain(*commands : List[Command]) -> List[Command]:
|
|||||||
return list(itertools.chain(*commands))
|
return list(itertools.chain(*commands))
|
||||||
|
|
||||||
|
|
||||||
def head(url : str) -> List[Command]:
|
def ping(url : str) -> List[Command]:
|
||||||
return [ '-I', url ]
|
return [ '-I', url ]
|
||||||
|
|
||||||
|
|
||||||
@@ -26,3 +26,7 @@ def download(url : str, download_file_path : str) -> List[Command]:
|
|||||||
|
|
||||||
def set_timeout(timeout : int) -> List[Command]:
|
def set_timeout(timeout : int) -> List[Command]:
|
||||||
return [ '--connect-timeout', str(timeout) ]
|
return [ '--connect-timeout', str(timeout) ]
|
||||||
|
|
||||||
|
|
||||||
|
def set_retry(retry : int) -> List[Command]:
|
||||||
|
return [ '--retry', str(retry) ]
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
|
|||||||
with tqdm(total = download_size, initial = initial_size, desc = translator.get('downloading'), unit = 'B', unit_scale = True, unit_divisor = 1024, ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
with tqdm(total = download_size, initial = initial_size, desc = translator.get('downloading'), unit = 'B', unit_scale = True, unit_divisor = 1024, ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||||
commands = curl_builder.chain(
|
commands = curl_builder.chain(
|
||||||
curl_builder.download(url, download_file_path),
|
curl_builder.download(url, download_file_path),
|
||||||
curl_builder.set_timeout(5)
|
curl_builder.set_timeout(5),
|
||||||
|
curl_builder.set_retry(5)
|
||||||
)
|
)
|
||||||
open_curl(commands)
|
open_curl(commands)
|
||||||
current_size = initial_size
|
current_size = initial_size
|
||||||
@@ -44,7 +45,7 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
|
|||||||
@lru_cache(maxsize = 64)
|
@lru_cache(maxsize = 64)
|
||||||
def get_static_download_size(url : str) -> int:
|
def get_static_download_size(url : str) -> int:
|
||||||
commands = curl_builder.chain(
|
commands = curl_builder.chain(
|
||||||
curl_builder.head(url),
|
curl_builder.ping(url),
|
||||||
curl_builder.set_timeout(5)
|
curl_builder.set_timeout(5)
|
||||||
)
|
)
|
||||||
process = open_curl(commands)
|
process = open_curl(commands)
|
||||||
@@ -62,7 +63,7 @@ def get_static_download_size(url : str) -> int:
|
|||||||
@lru_cache(maxsize = 64)
|
@lru_cache(maxsize = 64)
|
||||||
def ping_static_url(url : str) -> bool:
|
def ping_static_url(url : str) -> bool:
|
||||||
commands = curl_builder.chain(
|
commands = curl_builder.chain(
|
||||||
curl_builder.head(url),
|
curl_builder.ping(url),
|
||||||
curl_builder.set_timeout(5)
|
curl_builder.set_timeout(5)
|
||||||
)
|
)
|
||||||
process = open_curl(commands)
|
process = open_curl(commands)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ def get_available_execution_providers() -> List[ExecutionProvider]:
|
|||||||
return available_execution_providers
|
return available_execution_providers
|
||||||
|
|
||||||
|
|
||||||
def create_inference_session_providers(execution_device_id : str, execution_providers : List[ExecutionProvider]) -> List[InferenceSessionProvider]:
|
def create_inference_session_providers(execution_device_id : int, execution_providers : List[ExecutionProvider]) -> List[InferenceSessionProvider]:
|
||||||
inference_session_providers : List[InferenceSessionProvider] = []
|
inference_session_providers : List[InferenceSessionProvider] = []
|
||||||
|
|
||||||
for execution_provider in execution_providers:
|
for execution_provider in execution_providers:
|
||||||
@@ -89,10 +89,10 @@ def resolve_cudnn_conv_algo_search() -> str:
|
|||||||
return 'EXHAUSTIVE'
|
return 'EXHAUSTIVE'
|
||||||
|
|
||||||
|
|
||||||
def resolve_openvino_device_type(execution_device_id : str) -> str:
|
def resolve_openvino_device_type(execution_device_id : int) -> str:
|
||||||
if execution_device_id == '0':
|
if execution_device_id == 0:
|
||||||
return 'GPU'
|
return 'GPU'
|
||||||
return 'GPU.' + execution_device_id
|
return 'GPU.' + str(execution_device_id)
|
||||||
|
|
||||||
|
|
||||||
def run_nvidia_smi() -> subprocess.Popen[bytes]:
|
def run_nvidia_smi() -> subprocess.Popen[bytes]:
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ def get_inference_pool(module_name : str, model_names : List[str], model_source_
|
|||||||
return INFERENCE_POOL_SET.get(app_context).get(current_inference_context)
|
return INFERENCE_POOL_SET.get(app_context).get(current_inference_context)
|
||||||
|
|
||||||
|
|
||||||
def create_inference_pool(model_source_set : DownloadSet, execution_device_id : str, execution_providers : List[ExecutionProvider]) -> InferencePool:
|
def create_inference_pool(model_source_set : DownloadSet, execution_device_id : int, execution_providers : List[ExecutionProvider]) -> InferencePool:
|
||||||
inference_pool : InferencePool = {}
|
inference_pool : InferencePool = {}
|
||||||
|
|
||||||
for model_name in model_source_set.keys():
|
for model_name in model_source_set.keys():
|
||||||
@@ -67,7 +67,7 @@ def clear_inference_pool(module_name : str, model_names : List[str]) -> None:
|
|||||||
del INFERENCE_POOL_SET[app_context][inference_context]
|
del INFERENCE_POOL_SET[app_context][inference_context]
|
||||||
|
|
||||||
|
|
||||||
def create_inference_session(model_path : str, execution_device_id : str, execution_providers : List[ExecutionProvider]) -> InferenceSession:
|
def create_inference_session(model_path : str, execution_device_id : int, execution_providers : List[ExecutionProvider]) -> InferenceSession:
|
||||||
model_file_name = get_file_name(model_path)
|
model_file_name = get_file_name(model_path)
|
||||||
start_time = time()
|
start_time = time()
|
||||||
|
|
||||||
@@ -82,8 +82,8 @@ def create_inference_session(model_path : str, execution_device_id : str, execut
|
|||||||
fatal_exit(1)
|
fatal_exit(1)
|
||||||
|
|
||||||
|
|
||||||
def get_inference_context(module_name : str, model_names : List[str], execution_device_id : str, execution_providers : List[ExecutionProvider]) -> str:
|
def get_inference_context(module_name : str, model_names : List[str], execution_device_id : int, execution_providers : List[ExecutionProvider]) -> str:
|
||||||
inference_context = '.'.join([ module_name ] + model_names + [ execution_device_id ] + list(execution_providers))
|
inference_context = '.'.join([ module_name ] + model_names + [ str(execution_device_id) ] + list(execution_providers))
|
||||||
return inference_context
|
return inference_context
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+17
-8
@@ -13,6 +13,7 @@ from facefusion.common_helper import is_linux, is_windows
|
|||||||
LOCALS =\
|
LOCALS =\
|
||||||
{
|
{
|
||||||
'install_dependency': 'install the {dependency} package',
|
'install_dependency': 'install the {dependency} package',
|
||||||
|
'force_reinstall': 'force reinstall of packages',
|
||||||
'skip_conda': 'skip the conda environment check',
|
'skip_conda': 'skip the conda environment check',
|
||||||
'conda_not_activated': 'conda is not activated'
|
'conda_not_activated': 'conda is not activated'
|
||||||
}
|
}
|
||||||
@@ -26,13 +27,15 @@ if is_windows() or is_linux():
|
|||||||
if is_windows():
|
if is_windows():
|
||||||
ONNXRUNTIME_SET['directml'] = ('onnxruntime-directml', '1.23.0')
|
ONNXRUNTIME_SET['directml'] = ('onnxruntime-directml', '1.23.0')
|
||||||
if is_linux():
|
if is_linux():
|
||||||
ONNXRUNTIME_SET['rocm'] = ('onnxruntime-rocm', '1.21.0')
|
ONNXRUNTIME_SET['migraphx'] = ('onnxruntime-migraphx', '1.23.0')
|
||||||
|
ONNXRUNTIME_SET['rocm'] = ('onnxruntime_rocm', '1.22.1', '7.0.2') #type:ignore[assignment]
|
||||||
|
|
||||||
|
|
||||||
def cli() -> None:
|
def cli() -> None:
|
||||||
signal.signal(signal.SIGINT, signal_exit)
|
signal.signal(signal.SIGINT, signal_exit)
|
||||||
program = ArgumentParser(formatter_class = partial(HelpFormatter, max_help_position = 50))
|
program = ArgumentParser(formatter_class = partial(HelpFormatter, max_help_position = 50))
|
||||||
program.add_argument('--onnxruntime', help = LOCALS.get('install_dependency').format(dependency = 'onnxruntime'), choices = ONNXRUNTIME_SET.keys(), required = True)
|
program.add_argument('--onnxruntime', help = LOCALS.get('install_dependency').format(dependency = 'onnxruntime'), choices = ONNXRUNTIME_SET.keys(), required = True)
|
||||||
|
program.add_argument('--force-reinstall', help = LOCALS.get('force_reinstall'), action = 'store_true')
|
||||||
program.add_argument('--skip-conda', help = LOCALS.get('skip_conda'), action = 'store_true')
|
program.add_argument('--skip-conda', help = LOCALS.get('skip_conda'), action = 'store_true')
|
||||||
program.add_argument('-v', '--version', version = metadata.get('name') + ' ' + metadata.get('version'), action = 'version')
|
program.add_argument('-v', '--version', version = metadata.get('name') + ' ' + metadata.get('version'), action = 'version')
|
||||||
run(program)
|
run(program)
|
||||||
@@ -45,7 +48,10 @@ def signal_exit(signum : int, frame : FrameType) -> None:
|
|||||||
def run(program : ArgumentParser) -> None:
|
def run(program : ArgumentParser) -> None:
|
||||||
args = program.parse_args()
|
args = program.parse_args()
|
||||||
has_conda = 'CONDA_PREFIX' in os.environ
|
has_conda = 'CONDA_PREFIX' in os.environ
|
||||||
onnxruntime_name, onnxruntime_version = ONNXRUNTIME_SET.get(args.onnxruntime)
|
commands = [ shutil.which('pip'), 'install' ]
|
||||||
|
|
||||||
|
if args.force_reinstall:
|
||||||
|
commands.append('--force-reinstall')
|
||||||
|
|
||||||
if not args.skip_conda and not has_conda:
|
if not args.skip_conda and not has_conda:
|
||||||
sys.stdout.write(LOCALS.get('conda_not_activated') + os.linesep)
|
sys.stdout.write(LOCALS.get('conda_not_activated') + os.linesep)
|
||||||
@@ -56,17 +62,21 @@ def run(program : ArgumentParser) -> None:
|
|||||||
for line in file.readlines():
|
for line in file.readlines():
|
||||||
__line__ = line.strip()
|
__line__ = line.strip()
|
||||||
if not __line__.startswith('onnxruntime'):
|
if not __line__.startswith('onnxruntime'):
|
||||||
subprocess.call([ shutil.which('pip'), 'install', line, '--force-reinstall' ])
|
commands.append(__line__)
|
||||||
|
|
||||||
if args.onnxruntime == 'rocm':
|
if args.onnxruntime == 'rocm':
|
||||||
|
onnxruntime_name, onnxruntime_version, rocm_version = ONNXRUNTIME_SET.get(args.onnxruntime) #type:ignore[misc]
|
||||||
python_id = 'cp' + str(sys.version_info.major) + str(sys.version_info.minor)
|
python_id = 'cp' + str(sys.version_info.major) + str(sys.version_info.minor)
|
||||||
|
|
||||||
if python_id in [ 'cp310', 'cp312' ]:
|
if python_id in [ 'cp310', 'cp312' ]:
|
||||||
wheel_name = 'onnxruntime_rocm-' + onnxruntime_version + '-' + python_id + '-' + python_id + '-linux_x86_64.whl'
|
wheel_name = onnxruntime_name + '-' + onnxruntime_version + '-' + python_id + '-' + python_id + '-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl'
|
||||||
wheel_url = 'https://repo.radeon.com/rocm/manylinux/rocm-rel-6.4/' + wheel_name
|
wheel_url = 'https://repo.radeon.com/rocm/manylinux/rocm-rel-' + rocm_version + '/' + wheel_name
|
||||||
subprocess.call([ shutil.which('pip'), 'install', wheel_url, '--force-reinstall' ])
|
commands.append(wheel_url)
|
||||||
else:
|
else:
|
||||||
subprocess.call([ shutil.which('pip'), 'install', onnxruntime_name + '==' + onnxruntime_version, '--force-reinstall' ])
|
onnxruntime_name, onnxruntime_version = ONNXRUNTIME_SET.get(args.onnxruntime)
|
||||||
|
commands.append(onnxruntime_name + '==' + onnxruntime_version)
|
||||||
|
|
||||||
|
subprocess.call(commands)
|
||||||
|
|
||||||
if args.onnxruntime == 'cuda' and has_conda:
|
if args.onnxruntime == 'cuda' and has_conda:
|
||||||
library_paths = []
|
library_paths = []
|
||||||
@@ -97,4 +107,3 @@ def run(program : ArgumentParser) -> None:
|
|||||||
library_paths = list(dict.fromkeys([ library_path for library_path in library_paths if os.path.exists(library_path) ]))
|
library_paths = list(dict.fromkeys([ library_path for library_path in library_paths if os.path.exists(library_path) ]))
|
||||||
|
|
||||||
subprocess.call([ shutil.which('conda'), 'env', 'config', 'vars', 'set', 'PATH=' + os.pathsep.join(library_paths) ])
|
subprocess.call([ shutil.which('conda'), 'env', 'config', 'vars', 'set', 'PATH=' + os.pathsep.join(library_paths) ])
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ METADATA =\
|
|||||||
{
|
{
|
||||||
'name': 'FaceFusion',
|
'name': 'FaceFusion',
|
||||||
'description': 'Industry leading face manipulation platform',
|
'description': 'Industry leading face manipulation platform',
|
||||||
'version': '3.5.0',
|
'version': '3.5.2',
|
||||||
'license': 'OpenRAIL-AS',
|
'license': 'OpenRAIL-AS',
|
||||||
'author': 'Henry Ruhs',
|
'author': 'Henry Ruhs',
|
||||||
'url': 'https://facefusion.io'
|
'url': 'https://facefusion.io'
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
from facefusion.processors.modules.age_modifier.choices import age_modifier_direction_range, age_modifier_models # noqa: F401
|
|
||||||
from facefusion.processors.modules.background_remover.choices import background_remover_color_range, background_remover_models # noqa: F401
|
|
||||||
from facefusion.processors.modules.deep_swapper.choices import deep_swapper_models, deep_swapper_morph_range # noqa: F401
|
|
||||||
from facefusion.processors.modules.expression_restorer.choices import expression_restorer_areas, expression_restorer_factor_range, expression_restorer_models # noqa: F401
|
|
||||||
from facefusion.processors.modules.face_debugger.choices import face_debugger_items # noqa: F401
|
|
||||||
from facefusion.processors.modules.face_editor.choices import ( # noqa: F401
|
|
||||||
face_editor_eye_gaze_horizontal_range,
|
|
||||||
face_editor_eye_gaze_vertical_range,
|
|
||||||
face_editor_eye_open_ratio_range,
|
|
||||||
face_editor_eyebrow_direction_range,
|
|
||||||
face_editor_head_pitch_range,
|
|
||||||
face_editor_head_roll_range,
|
|
||||||
face_editor_head_yaw_range,
|
|
||||||
face_editor_lip_open_ratio_range,
|
|
||||||
face_editor_models,
|
|
||||||
face_editor_mouth_grim_range,
|
|
||||||
face_editor_mouth_position_horizontal_range,
|
|
||||||
face_editor_mouth_position_vertical_range,
|
|
||||||
face_editor_mouth_pout_range,
|
|
||||||
face_editor_mouth_purse_range,
|
|
||||||
face_editor_mouth_smile_range,
|
|
||||||
)
|
|
||||||
from facefusion.processors.modules.face_enhancer.choices import face_enhancer_blend_range, face_enhancer_models, face_enhancer_weight_range # noqa: F401
|
|
||||||
from facefusion.processors.modules.face_swapper.choices import face_swapper_models, face_swapper_set, face_swapper_weight_range # noqa: F401
|
|
||||||
from facefusion.processors.modules.frame_colorizer.choices import frame_colorizer_blend_range, frame_colorizer_models, frame_colorizer_sizes # noqa: F401
|
|
||||||
from facefusion.processors.modules.frame_enhancer.choices import frame_enhancer_blend_range, frame_enhancer_models # noqa: F401
|
|
||||||
from facefusion.processors.modules.lip_syncer.choices import lip_syncer_models, lip_syncer_weight_range # noqa: F401
|
|
||||||
@@ -234,7 +234,7 @@ def create_execution_program() -> ArgumentParser:
|
|||||||
program = ArgumentParser(add_help = False)
|
program = ArgumentParser(add_help = False)
|
||||||
available_execution_providers = get_available_execution_providers()
|
available_execution_providers = get_available_execution_providers()
|
||||||
group_execution = program.add_argument_group('execution')
|
group_execution = program.add_argument_group('execution')
|
||||||
group_execution.add_argument('--execution-device-ids', help = translator.get('help.execution_device_ids'), type = int, default = config.get_str_list('execution', 'execution_device_ids', '0'), nargs = '+', metavar = 'EXECUTION_DEVICE_IDS')
|
group_execution.add_argument('--execution-device-ids', help = translator.get('help.execution_device_ids'), type = int, default = config.get_int_list('execution', 'execution_device_ids', '0'), nargs = '+', metavar = 'EXECUTION_DEVICE_IDS')
|
||||||
group_execution.add_argument('--execution-providers', help = translator.get('help.execution_providers').format(choices = ', '.join(available_execution_providers)), default = config.get_str_list('execution', 'execution_providers', get_first(available_execution_providers)), choices = available_execution_providers, nargs = '+', metavar = 'EXECUTION_PROVIDERS')
|
group_execution.add_argument('--execution-providers', help = translator.get('help.execution_providers').format(choices = ', '.join(available_execution_providers)), default = config.get_str_list('execution', 'execution_providers', get_first(available_execution_providers)), choices = available_execution_providers, nargs = '+', metavar = 'EXECUTION_PROVIDERS')
|
||||||
group_execution.add_argument('--execution-thread-count', help = translator.get('help.execution_thread_count'), type = int, default = config.get_int_value('execution', 'execution_thread_count', '8'), choices = facefusion.choices.execution_thread_count_range, metavar = create_int_metavar(facefusion.choices.execution_thread_count_range))
|
group_execution.add_argument('--execution-thread-count', help = translator.get('help.execution_thread_count'), type = int, default = config.get_int_value('execution', 'execution_thread_count', '8'), choices = facefusion.choices.execution_thread_count_range, metavar = create_int_metavar(facefusion.choices.execution_thread_count_range))
|
||||||
job_store.register_job_keys([ 'execution_device_ids', 'execution_providers', 'execution_thread_count' ])
|
job_store.register_job_keys([ 'execution_device_ids', 'execution_providers', 'execution_thread_count' ])
|
||||||
@@ -269,7 +269,6 @@ def create_halt_on_error_program() -> ArgumentParser:
|
|||||||
def create_job_id_program() -> ArgumentParser:
|
def create_job_id_program() -> ArgumentParser:
|
||||||
program = ArgumentParser(add_help = False)
|
program = ArgumentParser(add_help = False)
|
||||||
program.add_argument('job_id', help = translator.get('help.job_id'))
|
program.add_argument('job_id', help = translator.get('help.job_id'))
|
||||||
job_store.register_job_keys([ 'job_id' ])
|
|
||||||
return program
|
return program
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from typing import Deque, Generator
|
from typing import Deque, Iterator
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import numpy
|
import numpy
|
||||||
@@ -18,7 +18,7 @@ from facefusion.types import Fps, StreamMode, VisionFrame
|
|||||||
from facefusion.vision import extract_vision_mask, read_static_images
|
from facefusion.vision import extract_vision_mask, read_static_images
|
||||||
|
|
||||||
|
|
||||||
def multi_process_capture(camera_capture : cv2.VideoCapture, camera_fps : Fps) -> Generator[VisionFrame, None, None]:
|
def multi_process_capture(camera_capture : cv2.VideoCapture, camera_fps : Fps) -> Iterator[VisionFrame]:
|
||||||
capture_deque : Deque[VisionFrame] = deque()
|
capture_deque : Deque[VisionFrame] = deque()
|
||||||
|
|
||||||
with tqdm(desc = translator.get('streaming'), unit = 'frame', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
with tqdm(desc = translator.get('streaming'), unit = 'frame', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||||
|
|||||||
+1
-1
@@ -385,7 +385,7 @@ State = TypedDict('State',
|
|||||||
'open_browser' : bool,
|
'open_browser' : bool,
|
||||||
'ui_layouts' : List[str],
|
'ui_layouts' : List[str],
|
||||||
'ui_workflow' : UiWorkflow,
|
'ui_workflow' : UiWorkflow,
|
||||||
'execution_device_ids' : List[str],
|
'execution_device_ids' : List[int],
|
||||||
'execution_providers' : List[ExecutionProvider],
|
'execution_providers' : List[ExecutionProvider],
|
||||||
'execution_thread_count' : int,
|
'execution_thread_count' : int,
|
||||||
'video_memory_strategy' : VideoMemoryStrategy,
|
'video_memory_strategy' : VideoMemoryStrategy,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Any, Generator, List, Optional
|
from typing import Any, Iterator, List, Optional
|
||||||
|
|
||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ def listen() -> None:
|
|||||||
BENCHMARK_START_BUTTON.click(start, outputs = BENCHMARK_BENCHMARKS_DATAFRAME)
|
BENCHMARK_START_BUTTON.click(start, outputs = BENCHMARK_BENCHMARKS_DATAFRAME)
|
||||||
|
|
||||||
|
|
||||||
def start() -> Generator[List[Any], None, None]:
|
def start() -> Iterator[List[Any]]:
|
||||||
state_manager.sync_state()
|
state_manager.sync_state()
|
||||||
|
|
||||||
for benchmark in benchmarker.run():
|
for benchmark in benchmarker.run():
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from facefusion.types import AudioFrame, Face, Mask, VisionFrame
|
|||||||
from facefusion.uis import choices as uis_choices
|
from facefusion.uis import choices as uis_choices
|
||||||
from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
|
from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
|
||||||
from facefusion.uis.types import ComponentOptions, PreviewMode
|
from facefusion.uis.types import ComponentOptions, PreviewMode
|
||||||
from facefusion.vision import conditional_merge_vision_mask, detect_frame_orientation, extract_vision_mask, fit_cover_frame, obscure_frame, read_static_image, read_static_images, read_video_frame, restrict_frame, unpack_resolution
|
from facefusion.vision import detect_frame_orientation, extract_vision_mask, fit_cover_frame, merge_vision_mask, obscure_frame, read_static_image, read_static_images, read_video_frame, restrict_frame, unpack_resolution
|
||||||
|
|
||||||
PREVIEW_IMAGE : Optional[gradio.Image] = None
|
PREVIEW_IMAGE : Optional[gradio.Image] = None
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ def update_preview_image(preview_mode : PreviewMode, preview_resolution : str, f
|
|||||||
reference_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
reference_vision_frame = read_static_image(state_manager.get_item('target_path'))
|
||||||
target_vision_frame = read_static_image(state_manager.get_item('target_path'), 'rgba')
|
target_vision_frame = read_static_image(state_manager.get_item('target_path'), 'rgba')
|
||||||
target_vision_mask = extract_vision_mask(target_vision_frame)
|
target_vision_mask = extract_vision_mask(target_vision_frame)
|
||||||
target_vision_frame = conditional_merge_vision_mask(target_vision_frame, target_vision_mask)
|
target_vision_frame = merge_vision_mask(target_vision_frame, target_vision_mask)
|
||||||
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)
|
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)
|
||||||
preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
|
preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
|
||||||
return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
|
return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
|
||||||
@@ -206,7 +206,7 @@ def update_preview_image(preview_mode : PreviewMode, preview_resolution : str, f
|
|||||||
reference_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
reference_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
||||||
temp_vision_frame = read_video_frame(state_manager.get_item('target_path'), frame_number)
|
temp_vision_frame = read_video_frame(state_manager.get_item('target_path'), frame_number)
|
||||||
temp_vision_mask = extract_vision_mask(temp_vision_frame)
|
temp_vision_mask = extract_vision_mask(temp_vision_frame)
|
||||||
temp_vision_frame = conditional_merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
temp_vision_frame = merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
||||||
preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, temp_vision_frame, preview_mode, preview_resolution)
|
preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, temp_vision_frame, preview_mode, preview_resolution)
|
||||||
preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
|
preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
|
||||||
return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
|
return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
|
||||||
@@ -297,6 +297,6 @@ def extract_crop_frame(vision_frame : VisionFrame, face : Face) -> Optional[Visi
|
|||||||
|
|
||||||
def prepare_output_frame(target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame, temp_vision_mask : Mask) -> VisionFrame:
|
def prepare_output_frame(target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame, temp_vision_mask : Mask) -> VisionFrame:
|
||||||
temp_vision_mask = temp_vision_mask.clip(state_manager.get_item('background_remover_color')[-1], 255)
|
temp_vision_mask = temp_vision_mask.clip(state_manager.get_item('background_remover_color')[-1], 255)
|
||||||
temp_vision_frame = conditional_merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
temp_vision_frame = merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
||||||
temp_vision_frame = cv2.resize(temp_vision_frame, target_vision_frame.shape[1::-1])
|
temp_vision_frame = cv2.resize(temp_vision_frame, target_vision_frame.shape[1::-1])
|
||||||
return temp_vision_frame
|
return temp_vision_frame
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Generator, List, Optional, Tuple
|
from typing import Iterator, List, Optional, Tuple
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import gradio
|
import gradio
|
||||||
@@ -82,7 +82,7 @@ def pre_stop() -> Tuple[gradio.File, gradio.Image, gradio.Button, gradio.Button]
|
|||||||
return gradio.File(visible = True), gradio.Image(visible = False), gradio.Button(visible = True), gradio.Button(visible = False)
|
return gradio.File(visible = True), gradio.Image(visible = False), gradio.Button(visible = True), gradio.Button(visible = False)
|
||||||
|
|
||||||
|
|
||||||
def start(webcam_device_id : int, webcam_mode : WebcamMode, webcam_resolution : str, webcam_fps : Fps) -> Generator[VisionFrame, None, None]:
|
def start(webcam_device_id : int, webcam_mode : WebcamMode, webcam_resolution : str, webcam_fps : Fps) -> Iterator[VisionFrame]:
|
||||||
state_manager.init_item('face_selector_mode', 'one')
|
state_manager.init_item('face_selector_mode', 'one')
|
||||||
state_manager.sync_state()
|
state_manager.sync_state()
|
||||||
|
|
||||||
|
|||||||
@@ -355,7 +355,11 @@ def extract_vision_mask(vision_frame : VisionFrame) -> Mask:
|
|||||||
return numpy.full(vision_frame.shape[:2], 255, dtype = numpy.uint8)
|
return numpy.full(vision_frame.shape[:2], 255, dtype = numpy.uint8)
|
||||||
|
|
||||||
|
|
||||||
|
def merge_vision_mask(vision_frame : VisionFrame, vision_mask : Mask) -> VisionFrame:
|
||||||
|
return numpy.dstack((vision_frame[:, :, :3], vision_mask))
|
||||||
|
|
||||||
|
|
||||||
def conditional_merge_vision_mask(vision_frame : VisionFrame, vision_mask : Mask) -> VisionFrame:
|
def conditional_merge_vision_mask(vision_frame : VisionFrame, vision_mask : Mask) -> VisionFrame:
|
||||||
if numpy.any(vision_mask < 255):
|
if numpy.any(vision_mask < 255):
|
||||||
return numpy.dstack((vision_frame[:, :, :3], vision_mask))
|
return merge_vision_mask(vision_frame, vision_mask)
|
||||||
return vision_frame
|
return vision_frame
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ def process(start_time : float) -> ErrorCode:
|
|||||||
setup,
|
setup,
|
||||||
prepare_image,
|
prepare_image,
|
||||||
process_image,
|
process_image,
|
||||||
partial(finalize_image, start_time),
|
partial(finalize_image, start_time)
|
||||||
]
|
]
|
||||||
process_manager.start()
|
process_manager.start()
|
||||||
|
|
||||||
|
|||||||
@@ -152,18 +152,6 @@ def restore_audio() -> ErrorCode:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def finalize_video(start_time : float) -> ErrorCode:
|
|
||||||
logger.debug(translator.get('clearing_temp'), __name__)
|
|
||||||
clear_temp_directory(state_manager.get_item('target_path'))
|
|
||||||
|
|
||||||
if is_video(state_manager.get_item('output_path')):
|
|
||||||
logger.info(translator.get('processing_video_succeeded').format(seconds = calculate_end_time(start_time)), __name__)
|
|
||||||
else:
|
|
||||||
logger.error(translator.get('processing_video_failed'), __name__)
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def process_temp_frame(temp_frame_path : str, frame_number : int) -> bool:
|
def process_temp_frame(temp_frame_path : str, frame_number : int) -> bool:
|
||||||
reference_vision_frame = read_static_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
reference_vision_frame = read_static_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
||||||
source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
|
source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
|
||||||
@@ -195,3 +183,15 @@ def process_temp_frame(temp_frame_path : str, frame_number : int) -> bool:
|
|||||||
|
|
||||||
temp_vision_frame = conditional_merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
temp_vision_frame = conditional_merge_vision_mask(temp_vision_frame, temp_vision_mask)
|
||||||
return write_image(temp_frame_path, temp_vision_frame)
|
return write_image(temp_frame_path, temp_vision_frame)
|
||||||
|
|
||||||
|
|
||||||
|
def finalize_video(start_time : float) -> ErrorCode:
|
||||||
|
logger.debug(translator.get('clearing_temp'), __name__)
|
||||||
|
clear_temp_directory(state_manager.get_item('target_path'))
|
||||||
|
|
||||||
|
if is_video(state_manager.get_item('output_path')):
|
||||||
|
logger.info(translator.get('processing_video_succeeded').format(seconds = calculate_end_time(start_time)), __name__)
|
||||||
|
else:
|
||||||
|
logger.error(translator.get('processing_video_failed'), __name__)
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
gradio-rangeslider==0.0.8
|
gradio-rangeslider==0.0.8
|
||||||
gradio==5.44.1
|
gradio==5.44.1
|
||||||
numpy==2.3.4
|
numpy==2.2.6
|
||||||
onnx==1.19.1
|
onnx==1.19.1
|
||||||
onnxruntime==1.23.2
|
onnxruntime==1.23.2
|
||||||
opencv-python==4.12.0.88
|
opencv-python==4.12.0.88
|
||||||
psutil==7.1.2
|
psutil==7.1.3
|
||||||
tqdm==4.67.1
|
tqdm==4.67.1
|
||||||
scipy==1.16.3
|
scipy==1.16.3
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from shutil import which
|
from shutil import which
|
||||||
|
|
||||||
from facefusion import metadata
|
from facefusion import metadata
|
||||||
from facefusion.curl_builder import chain, head, run
|
from facefusion.curl_builder import chain, ping, run, set_timeout
|
||||||
|
|
||||||
|
|
||||||
def test_run() -> None:
|
def test_run() -> None:
|
||||||
@@ -11,4 +11,7 @@ def test_run() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_chain() -> None:
|
def test_chain() -> None:
|
||||||
assert chain(head(metadata.get('url'))) == [ '-I', metadata.get('url') ]
|
assert chain(
|
||||||
|
ping(metadata.get('url')),
|
||||||
|
set_timeout(5)
|
||||||
|
) == [ '-I', metadata.get('url'), '--connect-timeout', '5' ]
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ def test_create_inference_session_providers() -> None:
|
|||||||
[
|
[
|
||||||
('CUDAExecutionProvider',
|
('CUDAExecutionProvider',
|
||||||
{
|
{
|
||||||
'device_id': '1',
|
'device_id': 1,
|
||||||
'cudnn_conv_algo_search': 'EXHAUSTIVE'
|
'cudnn_conv_algo_search': 'EXHAUSTIVE'
|
||||||
}),
|
}),
|
||||||
'CPUExecutionProvider'
|
'CPUExecutionProvider'
|
||||||
]
|
]
|
||||||
|
|
||||||
assert create_inference_session_providers('1', [ 'cpu', 'cuda' ]) == inference_session_providers
|
assert create_inference_session_providers(1, [ 'cpu', 'cuda' ]) == inference_session_providers
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ def before_all() -> None:
|
|||||||
subprocess.run([ 'ffmpeg', '-i', get_test_example_file('source.jpg'), '-vf', 'crop=iw*0.8:ih*0.8', get_test_example_file('source-80crop.jpg') ])
|
subprocess.run([ 'ffmpeg', '-i', get_test_example_file('source.jpg'), '-vf', 'crop=iw*0.8:ih*0.8', get_test_example_file('source-80crop.jpg') ])
|
||||||
subprocess.run([ 'ffmpeg', '-i', get_test_example_file('source.jpg'), '-vf', 'crop=iw*0.7:ih*0.7', get_test_example_file('source-70crop.jpg') ])
|
subprocess.run([ 'ffmpeg', '-i', get_test_example_file('source.jpg'), '-vf', 'crop=iw*0.7:ih*0.7', get_test_example_file('source-70crop.jpg') ])
|
||||||
subprocess.run([ 'ffmpeg', '-i', get_test_example_file('source.jpg'), '-vf', 'crop=iw*0.6:ih*0.6', get_test_example_file('source-60crop.jpg') ])
|
subprocess.run([ 'ffmpeg', '-i', get_test_example_file('source.jpg'), '-vf', 'crop=iw*0.6:ih*0.6', get_test_example_file('source-60crop.jpg') ])
|
||||||
state_manager.init_item('execution_device_ids', [ '0' ])
|
state_manager.init_item('execution_device_ids', [ 0 ])
|
||||||
state_manager.init_item('execution_providers', [ 'cpu' ])
|
state_manager.init_item('execution_providers', [ 'cpu' ])
|
||||||
state_manager.init_item('download_providers', [ 'github' ])
|
state_manager.init_item('download_providers', [ 'github' ])
|
||||||
state_manager.init_item('face_detector_angles', [ 0 ])
|
state_manager.init_item('face_detector_angles', [ 0 ])
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from facefusion.inference_manager import INFERENCE_POOL_SET, get_inference_pool
|
|||||||
|
|
||||||
@pytest.fixture(scope = 'module', autouse = True)
|
@pytest.fixture(scope = 'module', autouse = True)
|
||||||
def before_all() -> None:
|
def before_all() -> None:
|
||||||
state_manager.init_item('execution_device_ids', [ '0' ])
|
state_manager.init_item('execution_device_ids', [ 0 ])
|
||||||
state_manager.init_item('execution_providers', [ 'cpu' ])
|
state_manager.init_item('execution_providers', [ 'cpu' ])
|
||||||
state_manager.init_item('download_providers', [ 'github' ])
|
state_manager.init_item('download_providers', [ 'github' ])
|
||||||
content_analyser.pre_check()
|
content_analyser.pre_check()
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
import pytest
|
from facefusion.program_helper import find_argument_group, validate_actions, validate_args
|
||||||
|
|
||||||
from facefusion.program_helper import find_argument_group, validate_actions
|
|
||||||
|
|
||||||
|
|
||||||
def test_find_argument_group() -> None:
|
def test_find_argument_group() -> None:
|
||||||
@@ -12,12 +10,26 @@ def test_find_argument_group() -> None:
|
|||||||
|
|
||||||
assert find_argument_group(program, 'test-1')
|
assert find_argument_group(program, 'test-1')
|
||||||
assert find_argument_group(program, 'test-2')
|
assert find_argument_group(program, 'test-2')
|
||||||
assert find_argument_group(program, 'invalid') is None
|
assert find_argument_group(program, 'test-3') is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip()
|
|
||||||
def test_validate_args() -> None:
|
def test_validate_args() -> None:
|
||||||
pass
|
program = ArgumentParser()
|
||||||
|
program.add_argument('--test-1', default = 'test_1', choices = [ 'test_1', 'test_2' ])
|
||||||
|
|
||||||
|
assert validate_args(program) is True
|
||||||
|
|
||||||
|
subparsers = program.add_subparsers()
|
||||||
|
sub_program = subparsers.add_parser('sub-command')
|
||||||
|
sub_program.add_argument('--test-2', default = 'test_2', choices = [ 'test_1', 'test_2' ])
|
||||||
|
|
||||||
|
assert validate_args(program) is True
|
||||||
|
|
||||||
|
for action in sub_program._actions:
|
||||||
|
if action.dest == 'test_2':
|
||||||
|
action.default = 'test_3'
|
||||||
|
|
||||||
|
assert validate_args(program) is False
|
||||||
|
|
||||||
|
|
||||||
def test_validate_actions() -> None:
|
def test_validate_actions() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user