2.4.1 (#442)
* Update official url for cuda 12-2 wheels * Fix preview for audio to image * Prevent download loop when remote is unreachable * Prevent download loop when remote is unreachable * changes (#444) * Tidy up monkey patch * Use cpu core count for concurrency count * Dynamic concurrency_count for ideal Gradio performance * Conditional download face analyser models * Fix testing via pre_check() * Introduce checking to process manager for blocking the UI * Introduce checking to process manager for blocking the UI * Introduce checking to process manager for blocking the UI * Introduce checking to process manager for blocking the UI * Move the blocking while model download to the correct position * Remove unused imports --------- Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com>
This commit is contained in:
parent
1e2031e149
commit
6e67d7bff6
@ -1,5 +1,6 @@
|
|||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
import cv2
|
import cv2
|
||||||
import numpy
|
import numpy
|
||||||
@ -7,7 +8,7 @@ import onnxruntime
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
from facefusion import wording
|
from facefusion import process_manager, wording
|
||||||
from facefusion.typing import VisionFrame, ModelValue, Fps
|
from facefusion.typing import VisionFrame, ModelValue, Fps
|
||||||
from facefusion.execution import apply_execution_provider_options
|
from facefusion.execution import apply_execution_provider_options
|
||||||
from facefusion.vision import get_video_frame, count_video_frame_total, read_image, detect_video_fps
|
from facefusion.vision import get_video_frame, count_video_frame_total, read_image, detect_video_fps
|
||||||
@ -33,6 +34,8 @@ def get_content_analyser() -> Any:
|
|||||||
global CONTENT_ANALYSER
|
global CONTENT_ANALYSER
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if CONTENT_ANALYSER is None:
|
if CONTENT_ANALYSER is None:
|
||||||
model_path = MODELS.get('open_nsfw').get('path')
|
model_path = MODELS.get('open_nsfw').get('path')
|
||||||
CONTENT_ANALYSER = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
CONTENT_ANALYSER = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -49,7 +52,9 @@ def pre_check() -> bool:
|
|||||||
if not facefusion.globals.skip_download:
|
if not facefusion.globals.skip_download:
|
||||||
download_directory_path = resolve_relative_path('../.assets/models')
|
download_directory_path = resolve_relative_path('../.assets/models')
|
||||||
model_url = MODELS.get('open_nsfw').get('url')
|
model_url = MODELS.get('open_nsfw').get('url')
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, [ model_url ])
|
conditional_download(download_directory_path, [ model_url ])
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,19 +22,19 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
|
|||||||
executor.submit(get_download_size, url)
|
executor.submit(get_download_size, url)
|
||||||
for url in urls:
|
for url in urls:
|
||||||
download_file_path = os.path.join(download_directory_path, os.path.basename(url))
|
download_file_path = os.path.join(download_directory_path, os.path.basename(url))
|
||||||
initial = os.path.getsize(download_file_path) if is_file(download_file_path) else 0
|
initial_size = os.path.getsize(download_file_path) if is_file(download_file_path) else 0
|
||||||
total = get_download_size(url)
|
download_size = get_download_size(url)
|
||||||
if initial < total:
|
if initial_size < download_size:
|
||||||
with tqdm(total = total, initial = initial, desc = wording.get('downloading'), unit = 'B', unit_scale = True, unit_divisor = 1024, ascii = ' =', disable = facefusion.globals.log_level in [ 'warn', 'error' ]) as progress:
|
with tqdm(total = download_size, initial = initial_size, desc = wording.get('downloading'), unit = 'B', unit_scale = True, unit_divisor = 1024, ascii = ' =', disable = facefusion.globals.log_level in [ 'warn', 'error' ]) as progress:
|
||||||
subprocess.Popen([ 'curl', '--create-dirs', '--silent', '--insecure', '--location', '--continue-at', '-', '--output', download_file_path, url ])
|
subprocess.Popen([ 'curl', '--create-dirs', '--silent', '--insecure', '--location', '--continue-at', '-', '--output', download_file_path, url ])
|
||||||
current = initial
|
current_size = initial_size
|
||||||
while current < total:
|
while current_size < download_size:
|
||||||
if is_file(download_file_path):
|
if is_file(download_file_path):
|
||||||
current = os.path.getsize(download_file_path)
|
current_size = os.path.getsize(download_file_path)
|
||||||
progress.update(current - progress.n)
|
progress.update(current_size - progress.n)
|
||||||
if not is_download_done(url, download_file_path):
|
if download_size and not is_download_done(url, download_file_path):
|
||||||
os.remove(download_file_path)
|
os.remove(download_file_path)
|
||||||
conditional_download(download_directory_path, [ url] )
|
conditional_download(download_directory_path, [ url ])
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(maxsize = None)
|
@lru_cache(maxsize = None)
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
from typing import Any, Optional, List, Tuple
|
from typing import Any, Optional, List, Tuple
|
||||||
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
import cv2
|
import cv2
|
||||||
import numpy
|
import numpy
|
||||||
import onnxruntime
|
import onnxruntime
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
|
from facefusion import process_manager
|
||||||
from facefusion.common_helper import get_first
|
from facefusion.common_helper import get_first
|
||||||
from facefusion.face_helper import warp_face_by_face_landmark_5, warp_face_by_translation, create_static_anchors, distance_to_face_landmark_5, distance_to_bounding_box, convert_face_landmark_68_to_5, apply_nms, categorize_age, categorize_gender
|
from facefusion.face_helper import warp_face_by_face_landmark_5, warp_face_by_translation, create_static_anchors, distance_to_face_landmark_5, distance_to_bounding_box, convert_face_landmark_68_to_5, apply_nms, categorize_age, categorize_gender
|
||||||
from facefusion.face_store import get_static_faces, set_static_faces
|
from facefusion.face_store import get_static_faces, set_static_faces
|
||||||
@ -77,6 +79,8 @@ def get_face_analyser() -> Any:
|
|||||||
|
|
||||||
face_detectors = {}
|
face_detectors = {}
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if FACE_ANALYSER is None:
|
if FACE_ANALYSER is None:
|
||||||
if facefusion.globals.face_detector_model in [ 'many', 'retinaface' ]:
|
if facefusion.globals.face_detector_model in [ 'many', 'retinaface' ]:
|
||||||
face_detector = onnxruntime.InferenceSession(MODELS.get('face_detector_retinaface').get('path'), providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
face_detector = onnxruntime.InferenceSession(MODELS.get('face_detector_retinaface').get('path'), providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -121,18 +125,29 @@ def pre_check() -> bool:
|
|||||||
download_directory_path = resolve_relative_path('../.assets/models')
|
download_directory_path = resolve_relative_path('../.assets/models')
|
||||||
model_urls =\
|
model_urls =\
|
||||||
[
|
[
|
||||||
MODELS.get('face_detector_retinaface').get('url'),
|
|
||||||
MODELS.get('face_detector_scrfd').get('url'),
|
|
||||||
MODELS.get('face_detector_yoloface').get('url'),
|
|
||||||
MODELS.get('face_detector_yunet').get('url'),
|
|
||||||
MODELS.get('face_recognizer_arcface_blendswap').get('url'),
|
|
||||||
MODELS.get('face_recognizer_arcface_inswapper').get('url'),
|
|
||||||
MODELS.get('face_recognizer_arcface_simswap').get('url'),
|
|
||||||
MODELS.get('face_recognizer_arcface_uniface').get('url'),
|
|
||||||
MODELS.get('face_landmarker').get('url'),
|
MODELS.get('face_landmarker').get('url'),
|
||||||
MODELS.get('gender_age').get('url'),
|
MODELS.get('gender_age').get('url')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if facefusion.globals.face_detector_model in [ 'many', 'retinaface' ]:
|
||||||
|
model_urls.append(MODELS.get('face_detector_retinaface').get('url'))
|
||||||
|
if facefusion.globals.face_detector_model in [ 'many', 'scrfd' ]:
|
||||||
|
model_urls.append(MODELS.get('face_detector_scrfd').get('url'))
|
||||||
|
if facefusion.globals.face_detector_model in [ 'many', 'yoloface' ]:
|
||||||
|
model_urls.append(MODELS.get('face_detector_yoloface').get('url'))
|
||||||
|
if facefusion.globals.face_detector_model in [ 'yunet' ]:
|
||||||
|
model_urls.append(MODELS.get('face_detector_yunet').get('url'))
|
||||||
|
if facefusion.globals.face_recognizer_model == 'arcface_blendswap':
|
||||||
|
model_urls.append(MODELS.get('face_recognizer_arcface_blendswap').get('url'))
|
||||||
|
if facefusion.globals.face_recognizer_model == 'arcface_inswapper':
|
||||||
|
model_urls.append(MODELS.get('face_recognizer_arcface_inswapper').get('url'))
|
||||||
|
if facefusion.globals.face_recognizer_model == 'arcface_simswap':
|
||||||
|
model_urls.append(MODELS.get('face_recognizer_arcface_simswap').get('url'))
|
||||||
|
if facefusion.globals.face_recognizer_model == 'arcface_uniface':
|
||||||
|
model_urls.append(MODELS.get('face_recognizer_arcface_uniface').get('url'))
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, model_urls)
|
conditional_download(download_directory_path, model_urls)
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
from cv2.typing import Size
|
from cv2.typing import Size
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
import cv2
|
import cv2
|
||||||
import numpy
|
import numpy
|
||||||
import onnxruntime
|
import onnxruntime
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
|
from facefusion import process_manager
|
||||||
from facefusion.typing import FaceLandmark68, VisionFrame, Mask, Padding, FaceMaskRegion, ModelSet
|
from facefusion.typing import FaceLandmark68, VisionFrame, Mask, Padding, FaceMaskRegion, ModelSet
|
||||||
from facefusion.execution import apply_execution_provider_options
|
from facefusion.execution import apply_execution_provider_options
|
||||||
from facefusion.filesystem import resolve_relative_path
|
from facefusion.filesystem import resolve_relative_path
|
||||||
@ -57,6 +59,8 @@ def get_face_parser() -> Any:
|
|||||||
global FACE_PARSER
|
global FACE_PARSER
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if FACE_PARSER is None:
|
if FACE_PARSER is None:
|
||||||
model_path = MODELS.get('face_parser').get('path')
|
model_path = MODELS.get('face_parser').get('path')
|
||||||
FACE_PARSER = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
FACE_PARSER = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -83,7 +87,9 @@ def pre_check() -> bool:
|
|||||||
MODELS.get('face_occluder').get('url'),
|
MODELS.get('face_occluder').get('url'),
|
||||||
MODELS.get('face_parser').get('url'),
|
MODELS.get('face_parser').get('url'),
|
||||||
]
|
]
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, model_urls)
|
conditional_download(download_directory_path, model_urls)
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ if platform.system().lower() == 'darwin':
|
|||||||
ONNXRUNTIMES['default'] = ('onnxruntime', '1.17.1')
|
ONNXRUNTIMES['default'] = ('onnxruntime', '1.17.1')
|
||||||
else:
|
else:
|
||||||
ONNXRUNTIMES['default'] = ('onnxruntime', '1.16.3')
|
ONNXRUNTIMES['default'] = ('onnxruntime', '1.16.3')
|
||||||
if platform.system().lower() == 'linux' or platform.system().lower() == 'windows':
|
|
||||||
ONNXRUNTIMES['cuda-12.2'] = ('onnxruntime-gpu', '1.17.1')
|
ONNXRUNTIMES['cuda-12.2'] = ('onnxruntime-gpu', '1.17.1')
|
||||||
ONNXRUNTIMES['cuda-11.8'] = ('onnxruntime-gpu', '1.16.3')
|
ONNXRUNTIMES['cuda-11.8'] = ('onnxruntime-gpu', '1.16.3')
|
||||||
ONNXRUNTIMES['openvino'] = ('onnxruntime-openvino', '1.16.0')
|
ONNXRUNTIMES['openvino'] = ('onnxruntime-openvino', '1.16.0')
|
||||||
@ -71,6 +70,6 @@ def run(program : ArgumentParser) -> None:
|
|||||||
else:
|
else:
|
||||||
subprocess.call([ 'pip', 'uninstall', 'onnxruntime', onnxruntime_name, '-y', '-q' ])
|
subprocess.call([ 'pip', 'uninstall', 'onnxruntime', onnxruntime_name, '-y', '-q' ])
|
||||||
if onnxruntime == 'cuda-12.2':
|
if onnxruntime == 'cuda-12.2':
|
||||||
subprocess.call([ 'pip', 'install', onnxruntime_name + '==' + onnxruntime_version, '--extra-index-url', 'https://pkgs.dev.azure.com/onnxruntime/onnxruntime/_packaging/onnxruntime-cuda-12/pypi/simple', '--force-reinstall' ])
|
subprocess.call([ 'pip', 'install', onnxruntime_name + '==' + onnxruntime_version, '--extra-index-url', 'https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/onnxruntime-cuda-12/pypi/simple', '--force-reinstall' ])
|
||||||
else:
|
else:
|
||||||
subprocess.call([ 'pip', 'install', onnxruntime_name + '==' + onnxruntime_version, '--force-reinstall' ])
|
subprocess.call([ 'pip', 'install', onnxruntime_name + '==' + onnxruntime_version, '--force-reinstall' ])
|
||||||
|
@ -2,7 +2,7 @@ METADATA =\
|
|||||||
{
|
{
|
||||||
'name': 'FaceFusion',
|
'name': 'FaceFusion',
|
||||||
'description': 'Next generation face swapper and enhancer',
|
'description': 'Next generation face swapper and enhancer',
|
||||||
'version': '2.4.0',
|
'version': '2.4.1',
|
||||||
'license': 'MIT',
|
'license': 'MIT',
|
||||||
'author': 'Henry Ruhs',
|
'author': 'Henry Ruhs',
|
||||||
'url': 'https://facefusion.io'
|
'url': 'https://facefusion.io'
|
||||||
|
@ -15,6 +15,10 @@ def set_process_state(process_state : ProcessState) -> None:
|
|||||||
PROCESS_STATE = process_state
|
PROCESS_STATE = process_state
|
||||||
|
|
||||||
|
|
||||||
|
def is_checking() -> bool:
|
||||||
|
return get_process_state() == 'checking'
|
||||||
|
|
||||||
|
|
||||||
def is_processing() -> bool:
|
def is_processing() -> bool:
|
||||||
return get_process_state() == 'processing'
|
return get_process_state() == 'processing'
|
||||||
|
|
||||||
@ -27,6 +31,10 @@ def is_pending() -> bool:
|
|||||||
return get_process_state() == 'pending'
|
return get_process_state() == 'pending'
|
||||||
|
|
||||||
|
|
||||||
|
def check() -> None:
|
||||||
|
set_process_state('checking')
|
||||||
|
|
||||||
|
|
||||||
def start() -> None:
|
def start() -> None:
|
||||||
set_process_state('processing')
|
set_process_state('processing')
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Any, List, Literal, Optional
|
from typing import Any, List, Literal, Optional
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
from time import sleep
|
||||||
import cv2
|
import cv2
|
||||||
import threading
|
import threading
|
||||||
import numpy
|
import numpy
|
||||||
@ -87,6 +88,8 @@ def get_frame_processor() -> Any:
|
|||||||
global FRAME_PROCESSOR
|
global FRAME_PROCESSOR
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if FRAME_PROCESSOR is None:
|
if FRAME_PROCESSOR is None:
|
||||||
model_path = get_options('model').get('path')
|
model_path = get_options('model').get('path')
|
||||||
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -131,7 +134,9 @@ def pre_check() -> bool:
|
|||||||
if not facefusion.globals.skip_download:
|
if not facefusion.globals.skip_download:
|
||||||
download_directory_path = resolve_relative_path('../.assets/models')
|
download_directory_path = resolve_relative_path('../.assets/models')
|
||||||
model_url = get_options('model').get('url')
|
model_url = get_options('model').get('url')
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, [ model_url ])
|
conditional_download(download_directory_path, [ model_url ])
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Any, List, Literal, Optional
|
from typing import Any, List, Literal, Optional
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
import numpy
|
import numpy
|
||||||
import onnx
|
import onnx
|
||||||
@ -99,6 +100,8 @@ def get_frame_processor() -> Any:
|
|||||||
global FRAME_PROCESSOR
|
global FRAME_PROCESSOR
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if FRAME_PROCESSOR is None:
|
if FRAME_PROCESSOR is None:
|
||||||
model_path = get_options('model').get('path')
|
model_path = get_options('model').get('path')
|
||||||
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -115,6 +118,8 @@ def get_model_matrix() -> Any:
|
|||||||
global MODEL_MATRIX
|
global MODEL_MATRIX
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if MODEL_MATRIX is None:
|
if MODEL_MATRIX is None:
|
||||||
model_path = get_options('model').get('path')
|
model_path = get_options('model').get('path')
|
||||||
model = onnx.load(model_path)
|
model = onnx.load(model_path)
|
||||||
@ -171,7 +176,9 @@ def pre_check() -> bool:
|
|||||||
if not facefusion.globals.skip_download:
|
if not facefusion.globals.skip_download:
|
||||||
download_directory_path = resolve_relative_path('../.assets/models')
|
download_directory_path = resolve_relative_path('../.assets/models')
|
||||||
model_url = get_options('model').get('url')
|
model_url = get_options('model').get('url')
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, [ model_url ])
|
conditional_download(download_directory_path, [ model_url ])
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Any, List, Literal, Optional
|
from typing import Any, List, Literal, Optional
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
import cv2
|
import cv2
|
||||||
import numpy
|
import numpy
|
||||||
@ -69,6 +70,8 @@ def get_frame_processor() -> Any:
|
|||||||
global FRAME_PROCESSOR
|
global FRAME_PROCESSOR
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if FRAME_PROCESSOR is None:
|
if FRAME_PROCESSOR is None:
|
||||||
model_path = get_options('model').get('path')
|
model_path = get_options('model').get('path')
|
||||||
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -113,7 +116,9 @@ def pre_check() -> bool:
|
|||||||
if not facefusion.globals.skip_download:
|
if not facefusion.globals.skip_download:
|
||||||
download_directory_path = resolve_relative_path('../.assets/models')
|
download_directory_path = resolve_relative_path('../.assets/models')
|
||||||
model_url = get_options('model').get('url')
|
model_url = get_options('model').get('url')
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, [ model_url ])
|
conditional_download(download_directory_path, [ model_url ])
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Any, List, Literal, Optional
|
from typing import Any, List, Literal, Optional
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
import cv2
|
import cv2
|
||||||
import numpy
|
import numpy
|
||||||
@ -45,6 +46,8 @@ def get_frame_processor() -> Any:
|
|||||||
global FRAME_PROCESSOR
|
global FRAME_PROCESSOR
|
||||||
|
|
||||||
with THREAD_LOCK:
|
with THREAD_LOCK:
|
||||||
|
while process_manager.is_checking():
|
||||||
|
sleep(0.5)
|
||||||
if FRAME_PROCESSOR is None:
|
if FRAME_PROCESSOR is None:
|
||||||
model_path = get_options('model').get('path')
|
model_path = get_options('model').get('path')
|
||||||
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
FRAME_PROCESSOR = onnxruntime.InferenceSession(model_path, providers = apply_execution_provider_options(facefusion.globals.execution_providers))
|
||||||
@ -87,7 +90,9 @@ def pre_check() -> bool:
|
|||||||
if not facefusion.globals.skip_download:
|
if not facefusion.globals.skip_download:
|
||||||
download_directory_path = resolve_relative_path('../.assets/models')
|
download_directory_path = resolve_relative_path('../.assets/models')
|
||||||
model_url = get_options('model').get('url')
|
model_url = get_options('model').get('url')
|
||||||
|
process_manager.check()
|
||||||
conditional_download(download_directory_path, [ model_url ])
|
conditional_download(download_directory_path, [ model_url ])
|
||||||
|
process_manager.end()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ Fps = float
|
|||||||
Padding = Tuple[int, int, int, int]
|
Padding = Tuple[int, int, int, int]
|
||||||
Resolution = Tuple[int, int]
|
Resolution = Tuple[int, int]
|
||||||
|
|
||||||
ProcessState = Literal['processing', 'stopping', 'pending']
|
ProcessState = Literal['checking', 'processing', 'stopping', 'pending']
|
||||||
QueuePayload = TypedDict('QueuePayload',
|
QueuePayload = TypedDict('QueuePayload',
|
||||||
{
|
{
|
||||||
'frame_number' : int,
|
'frame_number' : int,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
from typing import Optional, Dict, Any
|
from typing import Optional, Dict, Any, Tuple
|
||||||
|
|
||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
import facefusion.choices
|
import facefusion.choices
|
||||||
from facefusion import wording
|
from facefusion import face_analyser, wording
|
||||||
from facefusion.typing import FaceAnalyserOrder, FaceAnalyserAge, FaceAnalyserGender, FaceDetectorModel
|
from facefusion.typing import FaceAnalyserOrder, FaceAnalyserAge, FaceAnalyserGender, FaceDetectorModel
|
||||||
from facefusion.uis.core import register_ui_component
|
from facefusion.uis.core import register_ui_component
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ def listen() -> None:
|
|||||||
FACE_ANALYSER_ORDER_DROPDOWN.change(update_face_analyser_order, inputs = FACE_ANALYSER_ORDER_DROPDOWN)
|
FACE_ANALYSER_ORDER_DROPDOWN.change(update_face_analyser_order, inputs = FACE_ANALYSER_ORDER_DROPDOWN)
|
||||||
FACE_ANALYSER_AGE_DROPDOWN.change(update_face_analyser_age, inputs = FACE_ANALYSER_AGE_DROPDOWN)
|
FACE_ANALYSER_AGE_DROPDOWN.change(update_face_analyser_age, inputs = FACE_ANALYSER_AGE_DROPDOWN)
|
||||||
FACE_ANALYSER_GENDER_DROPDOWN.change(update_face_analyser_gender, inputs = FACE_ANALYSER_GENDER_DROPDOWN)
|
FACE_ANALYSER_GENDER_DROPDOWN.change(update_face_analyser_gender, inputs = FACE_ANALYSER_GENDER_DROPDOWN)
|
||||||
FACE_DETECTOR_MODEL_DROPDOWN.change(update_face_detector_model, inputs = FACE_DETECTOR_MODEL_DROPDOWN, outputs = FACE_DETECTOR_SIZE_DROPDOWN)
|
FACE_DETECTOR_MODEL_DROPDOWN.change(update_face_detector_model, inputs = FACE_DETECTOR_MODEL_DROPDOWN, outputs = [ FACE_DETECTOR_MODEL_DROPDOWN, FACE_DETECTOR_SIZE_DROPDOWN ])
|
||||||
FACE_DETECTOR_SIZE_DROPDOWN.change(update_face_detector_size, inputs = FACE_DETECTOR_SIZE_DROPDOWN)
|
FACE_DETECTOR_SIZE_DROPDOWN.change(update_face_detector_size, inputs = FACE_DETECTOR_SIZE_DROPDOWN)
|
||||||
FACE_DETECTOR_SCORE_SLIDER.release(update_face_detector_score, inputs = FACE_DETECTOR_SCORE_SLIDER)
|
FACE_DETECTOR_SCORE_SLIDER.release(update_face_detector_score, inputs = FACE_DETECTOR_SCORE_SLIDER)
|
||||||
FACE_LANDMARKER_SCORE_SLIDER.release(update_face_landmarker_score, inputs = FACE_LANDMARKER_SCORE_SLIDER)
|
FACE_LANDMARKER_SCORE_SLIDER.release(update_face_landmarker_score, inputs = FACE_LANDMARKER_SCORE_SLIDER)
|
||||||
@ -101,12 +101,14 @@ def update_face_analyser_gender(face_analyser_gender : FaceAnalyserGender) -> No
|
|||||||
facefusion.globals.face_analyser_gender = face_analyser_gender if face_analyser_gender != 'none' else None
|
facefusion.globals.face_analyser_gender = face_analyser_gender if face_analyser_gender != 'none' else None
|
||||||
|
|
||||||
|
|
||||||
def update_face_detector_model(face_detector_model : FaceDetectorModel) -> gradio.Dropdown:
|
def update_face_detector_model(face_detector_model : FaceDetectorModel) -> Tuple[gradio.Dropdown, gradio.Dropdown]:
|
||||||
facefusion.globals.face_detector_model = face_detector_model
|
facefusion.globals.face_detector_model = face_detector_model
|
||||||
facefusion.globals.face_detector_size = '640x640'
|
update_face_detector_size('640x640')
|
||||||
if facefusion.globals.face_detector_size in facefusion.choices.face_detector_set[face_detector_model]:
|
if face_analyser.pre_check():
|
||||||
return gradio.Dropdown(value = facefusion.globals.face_detector_size, choices = facefusion.choices.face_detector_set[face_detector_model])
|
if facefusion.globals.face_detector_size in facefusion.choices.face_detector_set[face_detector_model]:
|
||||||
return gradio.Dropdown(value = facefusion.globals.face_detector_size, choices = [ facefusion.globals.face_detector_size ])
|
return gradio.Dropdown(value = facefusion.globals.face_detector_model), gradio.Dropdown(value = facefusion.globals.face_detector_size, choices = facefusion.choices.face_detector_set[face_detector_model])
|
||||||
|
return gradio.Dropdown(value = facefusion.globals.face_detector_model), gradio.Dropdown(value = facefusion.globals.face_detector_size, choices = [ facefusion.globals.face_detector_size ])
|
||||||
|
return gradio.Dropdown(), gradio.Dropdown()
|
||||||
|
|
||||||
|
|
||||||
def update_face_detector_size(face_detector_size : str) -> None:
|
def update_face_detector_size(face_detector_size : str) -> None:
|
||||||
|
@ -2,7 +2,7 @@ from typing import List, Optional, Tuple
|
|||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
from facefusion import wording
|
from facefusion import face_analyser, wording
|
||||||
from facefusion.processors.frame.core import load_frame_processor_module
|
from facefusion.processors.frame.core import load_frame_processor_module
|
||||||
from facefusion.processors.frame import globals as frame_processors_globals, choices as frame_processors_choices
|
from facefusion.processors.frame import globals as frame_processors_globals, choices as frame_processors_choices
|
||||||
from facefusion.processors.frame.typings import FaceDebuggerItem, FaceEnhancerModel, FaceSwapperModel, FrameEnhancerModel, LipSyncerModel
|
from facefusion.processors.frame.typings import FaceDebuggerItem, FaceEnhancerModel, FaceSwapperModel, FrameEnhancerModel, LipSyncerModel
|
||||||
@ -134,7 +134,7 @@ def update_face_swapper_model(face_swapper_model : FaceSwapperModel) -> gradio.D
|
|||||||
face_swapper_module = load_frame_processor_module('face_swapper')
|
face_swapper_module = load_frame_processor_module('face_swapper')
|
||||||
face_swapper_module.clear_frame_processor()
|
face_swapper_module.clear_frame_processor()
|
||||||
face_swapper_module.set_options('model', face_swapper_module.MODELS[face_swapper_model])
|
face_swapper_module.set_options('model', face_swapper_module.MODELS[face_swapper_model])
|
||||||
if face_swapper_module.pre_check():
|
if face_analyser.pre_check() and face_swapper_module.pre_check():
|
||||||
return gradio.Dropdown(value = frame_processors_globals.face_swapper_model)
|
return gradio.Dropdown(value = frame_processors_globals.face_swapper_model)
|
||||||
return gradio.Dropdown()
|
return gradio.Dropdown()
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import gradio
|
|||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
from facefusion import wording, logger
|
from facefusion import logger, wording
|
||||||
from facefusion.audio import get_audio_frame, create_empty_audio_frame
|
from facefusion.audio import get_audio_frame, create_empty_audio_frame
|
||||||
from facefusion.common_helper import get_first
|
from facefusion.common_helper import get_first
|
||||||
from facefusion.core import conditional_append_reference_faces
|
from facefusion.core import conditional_append_reference_faces
|
||||||
@ -45,12 +45,11 @@ def render() -> None:
|
|||||||
source_frames = read_static_images(facefusion.globals.source_paths)
|
source_frames = read_static_images(facefusion.globals.source_paths)
|
||||||
source_face = get_average_face(source_frames)
|
source_face = get_average_face(source_frames)
|
||||||
source_audio_path = get_first(filter_audio_paths(facefusion.globals.source_paths))
|
source_audio_path = get_first(filter_audio_paths(facefusion.globals.source_paths))
|
||||||
if source_audio_path and facefusion.globals.output_video_fps:
|
source_audio_frame = create_empty_audio_frame()
|
||||||
source_audio_frame = get_audio_frame(source_audio_path, facefusion.globals.output_video_fps, facefusion.globals.reference_frame_number)
|
if source_audio_path and facefusion.globals.output_video_fps and facefusion.globals.reference_frame_number:
|
||||||
if not numpy.any(source_audio_frame):
|
temp_audio_frame = get_audio_frame(source_audio_path, facefusion.globals.output_video_fps, facefusion.globals.reference_frame_number)
|
||||||
source_audio_frame = create_empty_audio_frame()
|
if numpy.any(temp_audio_frame):
|
||||||
else:
|
source_audio_frame = temp_audio_frame
|
||||||
source_audio_frame = None
|
|
||||||
if is_image(facefusion.globals.target_path):
|
if is_image(facefusion.globals.target_path):
|
||||||
target_vision_frame = read_static_image(facefusion.globals.target_path)
|
target_vision_frame = read_static_image(facefusion.globals.target_path)
|
||||||
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame)
|
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame)
|
||||||
@ -142,7 +141,6 @@ def clear_and_update_preview_image(frame_number : int = 0) -> gradio.Image:
|
|||||||
clear_face_analyser()
|
clear_face_analyser()
|
||||||
clear_reference_faces()
|
clear_reference_faces()
|
||||||
clear_static_faces()
|
clear_static_faces()
|
||||||
sleep(0.5)
|
|
||||||
return update_preview_image(frame_number)
|
return update_preview_image(frame_number)
|
||||||
|
|
||||||
|
|
||||||
@ -158,15 +156,14 @@ def update_preview_image(frame_number : int = 0) -> gradio.Image:
|
|||||||
source_frames = read_static_images(facefusion.globals.source_paths)
|
source_frames = read_static_images(facefusion.globals.source_paths)
|
||||||
source_face = get_average_face(source_frames)
|
source_face = get_average_face(source_frames)
|
||||||
source_audio_path = get_first(filter_audio_paths(facefusion.globals.source_paths))
|
source_audio_path = get_first(filter_audio_paths(facefusion.globals.source_paths))
|
||||||
if source_audio_path and facefusion.globals.output_video_fps:
|
source_audio_frame = create_empty_audio_frame()
|
||||||
|
if source_audio_path and facefusion.globals.output_video_fps and facefusion.globals.reference_frame_number:
|
||||||
reference_audio_frame_number = facefusion.globals.reference_frame_number
|
reference_audio_frame_number = facefusion.globals.reference_frame_number
|
||||||
if facefusion.globals.trim_frame_start:
|
if facefusion.globals.trim_frame_start:
|
||||||
reference_audio_frame_number -= facefusion.globals.trim_frame_start
|
reference_audio_frame_number -= facefusion.globals.trim_frame_start
|
||||||
source_audio_frame = get_audio_frame(source_audio_path, facefusion.globals.output_video_fps, reference_audio_frame_number)
|
temp_audio_frame = get_audio_frame(source_audio_path, facefusion.globals.output_video_fps, reference_audio_frame_number)
|
||||||
if not numpy.any(source_audio_frame):
|
if numpy.any(temp_audio_frame):
|
||||||
source_audio_frame = create_empty_audio_frame()
|
source_audio_frame = temp_audio_frame
|
||||||
else:
|
|
||||||
source_audio_frame = None
|
|
||||||
if is_image(facefusion.globals.target_path):
|
if is_image(facefusion.globals.target_path):
|
||||||
target_vision_frame = read_static_image(facefusion.globals.target_path)
|
target_vision_frame = read_static_image(facefusion.globals.target_path)
|
||||||
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame)
|
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame)
|
||||||
|
@ -5,10 +5,14 @@ import sys
|
|||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
|
from facefusion.uis import overrides
|
||||||
from facefusion import metadata, logger, wording
|
from facefusion import metadata, logger, wording
|
||||||
from facefusion.uis.typing import Component, ComponentName
|
from facefusion.uis.typing import Component, ComponentName
|
||||||
from facefusion.filesystem import resolve_relative_path
|
from facefusion.filesystem import resolve_relative_path
|
||||||
|
|
||||||
|
gradio.processing_utils.encode_array_to_base64 = overrides.encode_array_to_base64
|
||||||
|
gradio.processing_utils.encode_pil_to_base64 = overrides.encode_pil_to_base64
|
||||||
|
|
||||||
UI_COMPONENTS: Dict[ComponentName, Component] = {}
|
UI_COMPONENTS: Dict[ComponentName, Component] = {}
|
||||||
UI_LAYOUT_MODULES : List[ModuleType] = []
|
UI_LAYOUT_MODULES : List[ModuleType] = []
|
||||||
UI_LAYOUT_METHODS =\
|
UI_LAYOUT_METHODS =\
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import multiprocessing
|
||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
@ -61,4 +62,5 @@ def listen() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def run(ui : gradio.Blocks) -> None:
|
def run(ui : gradio.Blocks) -> None:
|
||||||
ui.queue(concurrency_count = 2).launch(show_api = False, quiet = True)
|
concurrency_count = min(2, multiprocessing.cpu_count())
|
||||||
|
ui.queue(concurrency_count = concurrency_count).launch(show_api = False, quiet = True)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import multiprocessing
|
||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
from facefusion.uis.components import about, frame_processors, frame_processors_options, execution, execution_thread_count, execution_queue_count, memory, temp_frame, output_options, common_options, source, target, output, preview, trim_frame, face_analyser, face_selector, face_masker
|
from facefusion.uis.components import about, frame_processors, frame_processors_options, execution, execution_thread_count, execution_queue_count, memory, temp_frame, output_options, common_options, source, target, output, preview, trim_frame, face_analyser, face_selector, face_masker
|
||||||
@ -75,4 +76,5 @@ def listen() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def run(ui : gradio.Blocks) -> None:
|
def run(ui : gradio.Blocks) -> None:
|
||||||
ui.queue(concurrency_count = 4).launch(show_api = False, quiet = True)
|
concurrency_count = min(8, multiprocessing.cpu_count())
|
||||||
|
ui.queue(concurrency_count = concurrency_count).launch(show_api = False, quiet = True)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import multiprocessing
|
||||||
import gradio
|
import gradio
|
||||||
|
|
||||||
from facefusion.uis.components import about, frame_processors, frame_processors_options, execution, execution_thread_count, webcam_options, source, webcam
|
from facefusion.uis.components import about, frame_processors, frame_processors_options, execution, execution_thread_count, webcam_options, source, webcam
|
||||||
@ -44,4 +45,5 @@ def listen() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def run(ui : gradio.Blocks) -> None:
|
def run(ui : gradio.Blocks) -> None:
|
||||||
ui.queue(concurrency_count = 2).launch(show_api = False, quiet = True)
|
concurrency_count = min(2, multiprocessing.cpu_count())
|
||||||
|
ui.queue(concurrency_count = concurrency_count).launch(show_api = False, quiet = True)
|
||||||
|
13
facefusion/uis/overrides.py
Normal file
13
facefusion/uis/overrides.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from typing import Any
|
||||||
|
import cv2
|
||||||
|
import numpy
|
||||||
|
import base64
|
||||||
|
|
||||||
|
|
||||||
|
def encode_array_to_base64(array : numpy.ndarray[Any, Any]) -> str:
|
||||||
|
buffer = cv2.imencode('.jpg', array[:, :, ::-1])[1]
|
||||||
|
return 'data:image/jpg;base64,' + base64.b64encode(buffer.tobytes()).decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def encode_pil_to_base64(image : Any) -> str:
|
||||||
|
return encode_array_to_base64(numpy.asarray(image)[:, :, ::-1])
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
import facefusion.globals
|
import facefusion.globals
|
||||||
from facefusion.download import conditional_download
|
from facefusion.download import conditional_download
|
||||||
from facefusion.face_analyser import clear_face_analyser, get_one_face
|
from facefusion.face_analyser import pre_check, clear_face_analyser, get_one_face
|
||||||
from facefusion.typing import Face
|
from facefusion.typing import Face
|
||||||
from facefusion.vision import read_static_image
|
from facefusion.vision import read_static_image
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ def test_get_one_face_with_retinaface() -> None:
|
|||||||
facefusion.globals.face_detector_model = 'retinaface'
|
facefusion.globals.face_detector_model = 'retinaface'
|
||||||
facefusion.globals.face_detector_size = '320x320'
|
facefusion.globals.face_detector_size = '320x320'
|
||||||
|
|
||||||
|
pre_check()
|
||||||
source_paths =\
|
source_paths =\
|
||||||
[
|
[
|
||||||
'.assets/examples/source.jpg',
|
'.assets/examples/source.jpg',
|
||||||
@ -49,6 +50,7 @@ def test_get_one_face_with_scrfd() -> None:
|
|||||||
facefusion.globals.face_detector_model = 'scrfd'
|
facefusion.globals.face_detector_model = 'scrfd'
|
||||||
facefusion.globals.face_detector_size = '640x640'
|
facefusion.globals.face_detector_size = '640x640'
|
||||||
|
|
||||||
|
pre_check()
|
||||||
source_paths =\
|
source_paths =\
|
||||||
[
|
[
|
||||||
'.assets/examples/source.jpg',
|
'.assets/examples/source.jpg',
|
||||||
@ -67,6 +69,7 @@ def test_get_one_face_with_yoloface() -> None:
|
|||||||
facefusion.globals.face_detector_model = 'yoloface'
|
facefusion.globals.face_detector_model = 'yoloface'
|
||||||
facefusion.globals.face_detector_size = '640x640'
|
facefusion.globals.face_detector_size = '640x640'
|
||||||
|
|
||||||
|
pre_check()
|
||||||
source_paths =\
|
source_paths =\
|
||||||
[
|
[
|
||||||
'.assets/examples/source.jpg',
|
'.assets/examples/source.jpg',
|
||||||
@ -85,6 +88,7 @@ def test_get_one_face_with_yunet() -> None:
|
|||||||
facefusion.globals.face_detector_model = 'yunet'
|
facefusion.globals.face_detector_model = 'yunet'
|
||||||
facefusion.globals.face_detector_size = '640x640'
|
facefusion.globals.face_detector_size = '640x640'
|
||||||
|
|
||||||
|
pre_check()
|
||||||
source_paths =\
|
source_paths =\
|
||||||
[
|
[
|
||||||
'.assets/examples/source.jpg',
|
'.assets/examples/source.jpg',
|
||||||
|
Loading…
Reference in New Issue
Block a user