mirror of
https://github.com/facefusion/facefusion.git
synced 2026-08-23 09:17:38 +02:00
Next (#502)
* Validate the overrides from facefusion.ini * Break down cli testing * Remove architecture lookup to support old driver * Remove architecture lookup to support old driver * Remove hwaccel auto * Respect the output video resolution * Bump next version * Full directml support (#501) * Introduce conditional thread management for DML support * Finish migration to thread helpers * Introduce dynamic frame colorizer sizes * Introduce dynamic frame colorizer sizes * Add 192x192 to frame colorizer * Fix async audio
This commit is contained in:
@@ -7,6 +7,7 @@ face_debugger_items : List[FaceDebuggerItem] = [ 'bounding-box', 'face-landmark-
|
||||
face_enhancer_models : List[FaceEnhancerModel] = [ 'codeformer', 'gfpgan_1.2', 'gfpgan_1.3', 'gfpgan_1.4', 'gpen_bfr_256', 'gpen_bfr_512', 'gpen_bfr_1024', 'gpen_bfr_2048', 'restoreformer_plus_plus' ]
|
||||
face_swapper_models : List[FaceSwapperModel] = [ 'blendswap_256', 'inswapper_128', 'inswapper_128_fp16', 'simswap_256', 'simswap_512_unofficial', 'uniface_256' ]
|
||||
frame_colorizer_models : List[FrameColorizerModel] = [ 'ddcolor', 'ddcolor_artistic', 'deoldify', 'deoldify_artistic', 'deoldify_stable' ]
|
||||
frame_colorizer_sizes : List[str] = [ '192x192', '256x256', '384x384', '512x512' ]
|
||||
frame_enhancer_models : List[FrameEnhancerModel] = [ 'lsdir_x4', 'nomos8k_sc_x4', 'real_esrgan_x2', 'real_esrgan_x2_fp16', 'real_esrgan_x4', 'real_esrgan_x4_fp16', 'real_hatgan_x4', 'span_kendata_x4' ]
|
||||
lip_syncer_models : List[LipSyncerModel] = [ 'wav2lip_gan' ]
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ face_enhancer_blend : Optional[int] = None
|
||||
face_swapper_model : Optional[FaceSwapperModel] = None
|
||||
frame_colorizer_model : Optional[FrameColorizerModel] = None
|
||||
frame_colorizer_blend : Optional[int] = None
|
||||
frame_colorizer_size : Optional[str] = None
|
||||
frame_enhancer_model : Optional[FrameEnhancerModel] = None
|
||||
frame_enhancer_blend : Optional[int] = None
|
||||
lip_syncer_model : Optional[LipSyncerModel] = None
|
||||
|
||||
@@ -2,7 +2,6 @@ from typing import Any, List, Literal, Optional
|
||||
from argparse import ArgumentParser
|
||||
from time import sleep
|
||||
import cv2
|
||||
import threading
|
||||
import numpy
|
||||
import onnxruntime
|
||||
|
||||
@@ -16,6 +15,7 @@ from facefusion.execution import apply_execution_provider_options
|
||||
from facefusion.content_analyser import clear_content_analyser
|
||||
from facefusion.face_store import get_reference_faces
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.thread_helper import thread_lock, thread_semaphore
|
||||
from facefusion.typing import Face, VisionFrame, UpdateProgress, ProcessMode, ModelSet, OptionsWithModel, QueuePayload
|
||||
from facefusion.common_helper import create_metavar
|
||||
from facefusion.filesystem import is_file, is_image, is_video, resolve_relative_path
|
||||
@@ -26,8 +26,6 @@ from facefusion.processors.frame import globals as frame_processors_globals
|
||||
from facefusion.processors.frame import choices as frame_processors_choices
|
||||
|
||||
FRAME_PROCESSOR = None
|
||||
THREAD_SEMAPHORE : threading.Semaphore = threading.Semaphore()
|
||||
THREAD_LOCK : threading.Lock = threading.Lock()
|
||||
NAME = __name__.upper()
|
||||
MODELS : ModelSet =\
|
||||
{
|
||||
@@ -101,7 +99,7 @@ OPTIONS : Optional[OptionsWithModel] = None
|
||||
def get_frame_processor() -> Any:
|
||||
global FRAME_PROCESSOR
|
||||
|
||||
with THREAD_LOCK:
|
||||
with thread_lock():
|
||||
while process_manager.is_checking():
|
||||
sleep(0.5)
|
||||
if FRAME_PROCESSOR is None:
|
||||
@@ -221,7 +219,7 @@ def apply_enhance(crop_vision_frame : VisionFrame) -> VisionFrame:
|
||||
if frame_processor_input.name == 'weight':
|
||||
weight = numpy.array([ 1 ]).astype(numpy.double)
|
||||
frame_processor_inputs[frame_processor_input.name] = weight
|
||||
with THREAD_SEMAPHORE:
|
||||
with thread_semaphore():
|
||||
crop_vision_frame = frame_processor.run(None, frame_processor_inputs)[0][0]
|
||||
return crop_vision_frame
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ from typing import Any, List, Literal, Optional
|
||||
from argparse import ArgumentParser
|
||||
from time import sleep
|
||||
import platform
|
||||
import threading
|
||||
import numpy
|
||||
import onnx
|
||||
import onnxruntime
|
||||
@@ -18,6 +17,7 @@ from facefusion.face_helper import warp_face_by_face_landmark_5, paste_back
|
||||
from facefusion.face_store import get_reference_faces
|
||||
from facefusion.content_analyser import clear_content_analyser
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.thread_helper import thread_lock, conditional_thread_semaphore
|
||||
from facefusion.typing import Face, Embedding, VisionFrame, UpdateProgress, ProcessMode, ModelSet, OptionsWithModel, QueuePayload
|
||||
from facefusion.filesystem import is_file, is_image, has_image, is_video, filter_image_paths, resolve_relative_path
|
||||
from facefusion.download import conditional_download, is_download_done
|
||||
@@ -28,7 +28,6 @@ from facefusion.processors.frame import choices as frame_processors_choices
|
||||
|
||||
FRAME_PROCESSOR = None
|
||||
MODEL_INITIALIZER = None
|
||||
THREAD_LOCK : threading.Lock = threading.Lock()
|
||||
NAME = __name__.upper()
|
||||
MODELS : ModelSet =\
|
||||
{
|
||||
@@ -99,7 +98,7 @@ OPTIONS : Optional[OptionsWithModel] = None
|
||||
def get_frame_processor() -> Any:
|
||||
global FRAME_PROCESSOR
|
||||
|
||||
with THREAD_LOCK:
|
||||
with thread_lock():
|
||||
while process_manager.is_checking():
|
||||
sleep(0.5)
|
||||
if FRAME_PROCESSOR is None:
|
||||
@@ -117,7 +116,7 @@ def clear_frame_processor() -> None:
|
||||
def get_model_initializer() -> Any:
|
||||
global MODEL_INITIALIZER
|
||||
|
||||
with THREAD_LOCK:
|
||||
with thread_lock():
|
||||
while process_manager.is_checking():
|
||||
sleep(0.5)
|
||||
if MODEL_INITIALIZER is None:
|
||||
@@ -263,7 +262,8 @@ def apply_swap(source_face : Face, crop_vision_frame : VisionFrame) -> VisionFra
|
||||
frame_processor_inputs[frame_processor_input.name] = prepare_source_embedding(source_face)
|
||||
if frame_processor_input.name == 'target':
|
||||
frame_processor_inputs[frame_processor_input.name] = crop_vision_frame
|
||||
crop_vision_frame = frame_processor.run(None, frame_processor_inputs)[0][0]
|
||||
with conditional_thread_semaphore(facefusion.globals.execution_providers):
|
||||
crop_vision_frame = frame_processor.run(None, frame_processor_inputs)[0][0]
|
||||
return crop_vision_frame
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Any, List, Literal, Optional
|
||||
from argparse import ArgumentParser
|
||||
from time import sleep
|
||||
import threading
|
||||
import cv2
|
||||
import numpy
|
||||
import onnxruntime
|
||||
@@ -13,18 +12,17 @@ from facefusion.face_analyser import clear_face_analyser
|
||||
from facefusion.content_analyser import clear_content_analyser
|
||||
from facefusion.execution import apply_execution_provider_options
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.thread_helper import thread_lock, thread_semaphore
|
||||
from facefusion.typing import Face, VisionFrame, UpdateProgress, ProcessMode, ModelSet, OptionsWithModel, QueuePayload
|
||||
from facefusion.common_helper import create_metavar
|
||||
from facefusion.filesystem import is_file, resolve_relative_path, is_image, is_video
|
||||
from facefusion.download import conditional_download, is_download_done
|
||||
from facefusion.vision import read_image, read_static_image, write_image
|
||||
from facefusion.vision import read_image, read_static_image, write_image, unpack_resolution
|
||||
from facefusion.processors.frame.typings import FrameColorizerInputs
|
||||
from facefusion.processors.frame import globals as frame_processors_globals
|
||||
from facefusion.processors.frame import choices as frame_processors_choices
|
||||
|
||||
FRAME_PROCESSOR = None
|
||||
THREAD_LOCK : threading.Lock = threading.Lock()
|
||||
THREAD_SEMAPHORE : threading.Semaphore = threading.Semaphore()
|
||||
NAME = __name__.upper()
|
||||
MODELS : ModelSet =\
|
||||
{
|
||||
@@ -32,36 +30,31 @@ MODELS : ModelSet =\
|
||||
{
|
||||
'type': 'ddcolor',
|
||||
'url': 'https://github.com/facefusion/facefusion-assets/releases/download/models/ddcolor.onnx',
|
||||
'path': resolve_relative_path('../.assets/models/ddcolor.onnx'),
|
||||
'size': (512, 512)
|
||||
'path': resolve_relative_path('../.assets/models/ddcolor.onnx')
|
||||
},
|
||||
'ddcolor_artistic':
|
||||
{
|
||||
'type': 'ddcolor',
|
||||
'url': 'https://github.com/facefusion/facefusion-assets/releases/download/models/ddcolor_artistic.onnx',
|
||||
'path': resolve_relative_path('../.assets/models/ddcolor_artistic.onnx'),
|
||||
'size': (512, 512)
|
||||
'path': resolve_relative_path('../.assets/models/ddcolor_artistic.onnx')
|
||||
},
|
||||
'deoldify':
|
||||
{
|
||||
'type': 'deoldify',
|
||||
'url': 'https://github.com/facefusion/facefusion-assets/releases/download/models/deoldify.onnx',
|
||||
'path': resolve_relative_path('../.assets/models/deoldify.onnx'),
|
||||
'size': (256, 256)
|
||||
'path': resolve_relative_path('../.assets/models/deoldify.onnx')
|
||||
},
|
||||
'deoldify_artistic':
|
||||
{
|
||||
'type': 'deoldify',
|
||||
'url': 'https://github.com/facefusion/facefusion-assets/releases/download/models/deoldify_artistic.onnx',
|
||||
'path': resolve_relative_path('../.assets/models/deoldify_artistic.onnx'),
|
||||
'size': (256, 256)
|
||||
'path': resolve_relative_path('../.assets/models/deoldify_artistic.onnx')
|
||||
},
|
||||
'deoldify_stable':
|
||||
{
|
||||
'type': 'deoldify',
|
||||
'url': 'https://github.com/facefusion/facefusion-assets/releases/download/models/deoldify_stable.onnx',
|
||||
'path': resolve_relative_path('../.assets/models/deoldify_stable.onnx'),
|
||||
'size': (256, 256)
|
||||
'path': resolve_relative_path('../.assets/models/deoldify_stable.onnx')
|
||||
}
|
||||
}
|
||||
OPTIONS : Optional[OptionsWithModel] = None
|
||||
@@ -70,7 +63,7 @@ OPTIONS : Optional[OptionsWithModel] = None
|
||||
def get_frame_processor() -> Any:
|
||||
global FRAME_PROCESSOR
|
||||
|
||||
with THREAD_LOCK:
|
||||
with thread_lock():
|
||||
while process_manager.is_checking():
|
||||
sleep(0.5)
|
||||
if FRAME_PROCESSOR is None:
|
||||
@@ -105,12 +98,14 @@ def set_options(key : Literal['model'], value : Any) -> None:
|
||||
def register_args(program : ArgumentParser) -> None:
|
||||
program.add_argument('--frame-colorizer-model', help = wording.get('help.frame_colorizer_model'), default = config.get_str_value('frame_processors.frame_colorizer_model', 'ddcolor'), choices = frame_processors_choices.frame_colorizer_models)
|
||||
program.add_argument('--frame-colorizer-blend', help = wording.get('help.frame_colorizer_blend'), type = int, default = config.get_int_value('frame_processors.frame_colorizer_blend', '100'), choices = frame_processors_choices.frame_colorizer_blend_range, metavar = create_metavar(frame_processors_choices.frame_colorizer_blend_range))
|
||||
program.add_argument('--frame-colorizer-size', help = wording.get('help.frame_colorizer_size'), type = str, default = config.get_str_value('frame_processors.frame_colorizer_size', '256x256'), choices = frame_processors_choices.frame_colorizer_sizes)
|
||||
|
||||
|
||||
def apply_args(program : ArgumentParser) -> None:
|
||||
args = program.parse_args()
|
||||
frame_processors_globals.frame_colorizer_model = args.frame_colorizer_model
|
||||
frame_processors_globals.frame_colorizer_blend = args.frame_colorizer_blend
|
||||
frame_processors_globals.frame_colorizer_size = args.frame_colorizer_size
|
||||
|
||||
|
||||
def pre_check() -> bool:
|
||||
@@ -160,7 +155,7 @@ def post_process() -> None:
|
||||
def colorize_frame(temp_vision_frame : VisionFrame) -> VisionFrame:
|
||||
frame_processor = get_frame_processor()
|
||||
prepare_vision_frame = prepare_temp_frame(temp_vision_frame)
|
||||
with THREAD_SEMAPHORE:
|
||||
with thread_semaphore():
|
||||
color_vision_frame = frame_processor.run(None,
|
||||
{
|
||||
frame_processor.get_inputs()[0].name: prepare_vision_frame
|
||||
@@ -171,7 +166,7 @@ def colorize_frame(temp_vision_frame : VisionFrame) -> VisionFrame:
|
||||
|
||||
|
||||
def prepare_temp_frame(temp_vision_frame : VisionFrame) -> VisionFrame:
|
||||
model_size = get_options('model').get('size')
|
||||
model_size = unpack_resolution(frame_processors_globals.frame_colorizer_size)
|
||||
model_type = get_options('model').get('type')
|
||||
temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_BGR2GRAY)
|
||||
temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_GRAY2RGB)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Any, List, Literal, Optional
|
||||
from argparse import ArgumentParser
|
||||
from time import sleep
|
||||
import threading
|
||||
import cv2
|
||||
import numpy
|
||||
import onnxruntime
|
||||
@@ -13,6 +12,7 @@ from facefusion.face_analyser import clear_face_analyser
|
||||
from facefusion.content_analyser import clear_content_analyser
|
||||
from facefusion.execution import apply_execution_provider_options
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.thread_helper import thread_lock, conditional_thread_semaphore
|
||||
from facefusion.typing import Face, VisionFrame, UpdateProgress, ProcessMode, ModelSet, OptionsWithModel, QueuePayload
|
||||
from facefusion.common_helper import create_metavar
|
||||
from facefusion.filesystem import is_file, resolve_relative_path, is_image, is_video
|
||||
@@ -23,7 +23,6 @@ from facefusion.processors.frame import globals as frame_processors_globals
|
||||
from facefusion.processors.frame import choices as frame_processors_choices
|
||||
|
||||
FRAME_PROCESSOR = None
|
||||
THREAD_LOCK : threading.Lock = threading.Lock()
|
||||
NAME = __name__.upper()
|
||||
MODELS : ModelSet =\
|
||||
{
|
||||
@@ -90,7 +89,7 @@ OPTIONS : Optional[OptionsWithModel] = None
|
||||
def get_frame_processor() -> Any:
|
||||
global FRAME_PROCESSOR
|
||||
|
||||
with THREAD_LOCK:
|
||||
with thread_lock():
|
||||
while process_manager.is_checking():
|
||||
sleep(0.5)
|
||||
if FRAME_PROCESSOR is None:
|
||||
@@ -185,10 +184,11 @@ def enhance_frame(temp_vision_frame : VisionFrame) -> VisionFrame:
|
||||
tile_vision_frames, pad_width, pad_height = create_tile_frames(temp_vision_frame, size)
|
||||
|
||||
for index, tile_vision_frame in enumerate(tile_vision_frames):
|
||||
tile_vision_frame = frame_processor.run(None,
|
||||
{
|
||||
frame_processor.get_inputs()[0].name : prepare_tile_frame(tile_vision_frame)
|
||||
})[0]
|
||||
with conditional_thread_semaphore(facefusion.globals.execution_providers):
|
||||
tile_vision_frame = frame_processor.run(None,
|
||||
{
|
||||
frame_processor.get_inputs()[0].name : prepare_tile_frame(tile_vision_frame)
|
||||
})[0]
|
||||
tile_vision_frames[index] = normalize_tile_frame(tile_vision_frame)
|
||||
merge_vision_frame = merge_tile_frames(tile_vision_frames, temp_width * scale, temp_height * scale, pad_width * scale, pad_height * scale, (size[0] * scale, size[1] * scale, size[2] * scale))
|
||||
temp_vision_frame = blend_frame(temp_vision_frame, merge_vision_frame)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Any, List, Literal, Optional
|
||||
from argparse import ArgumentParser
|
||||
from time import sleep
|
||||
import threading
|
||||
import cv2
|
||||
import numpy
|
||||
import onnxruntime
|
||||
@@ -16,6 +15,7 @@ from facefusion.face_helper import warp_face_by_face_landmark_5, warp_face_by_bo
|
||||
from facefusion.face_store import get_reference_faces
|
||||
from facefusion.content_analyser import clear_content_analyser
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.thread_helper import thread_lock, conditional_thread_semaphore
|
||||
from facefusion.typing import Face, VisionFrame, UpdateProgress, ProcessMode, ModelSet, OptionsWithModel, AudioFrame, QueuePayload
|
||||
from facefusion.filesystem import is_file, has_audio, resolve_relative_path
|
||||
from facefusion.download import conditional_download, is_download_done
|
||||
@@ -29,7 +29,6 @@ from facefusion.processors.frame import globals as frame_processors_globals
|
||||
from facefusion.processors.frame import choices as frame_processors_choices
|
||||
|
||||
FRAME_PROCESSOR = None
|
||||
THREAD_LOCK : threading.Lock = threading.Lock()
|
||||
NAME = __name__.upper()
|
||||
MODELS : ModelSet =\
|
||||
{
|
||||
@@ -45,7 +44,7 @@ OPTIONS : Optional[OptionsWithModel] = None
|
||||
def get_frame_processor() -> Any:
|
||||
global FRAME_PROCESSOR
|
||||
|
||||
with THREAD_LOCK:
|
||||
with thread_lock():
|
||||
while process_manager.is_checking():
|
||||
sleep(0.5)
|
||||
if FRAME_PROCESSOR is None:
|
||||
@@ -155,11 +154,12 @@ def sync_lip(target_face : Face, temp_audio_frame : AudioFrame, temp_vision_fram
|
||||
crop_mask_list.append(occlusion_mask)
|
||||
close_vision_frame, close_matrix = warp_face_by_bounding_box(crop_vision_frame, bounding_box, (96, 96))
|
||||
close_vision_frame = prepare_crop_frame(close_vision_frame)
|
||||
close_vision_frame = frame_processor.run(None,
|
||||
{
|
||||
'source': temp_audio_frame,
|
||||
'target': close_vision_frame
|
||||
})[0]
|
||||
with conditional_thread_semaphore(facefusion.globals.execution_providers):
|
||||
close_vision_frame = frame_processor.run(None,
|
||||
{
|
||||
'source': temp_audio_frame,
|
||||
'target': close_vision_frame
|
||||
})[0]
|
||||
crop_vision_frame = normalize_crop_frame(close_vision_frame)
|
||||
crop_vision_frame = cv2.warpAffine(crop_vision_frame, cv2.invertAffineTransform(close_matrix), (512, 512), borderMode = cv2.BORDER_REPLICATE)
|
||||
crop_mask = numpy.minimum.reduce(crop_mask_list)
|
||||
|
||||
Reference in New Issue
Block a user