* 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:
Henry Ruhs
2024-04-19 13:35:36 +02:00
committed by GitHub
parent 092dfbb796
commit 4efa5b2c6e
30 changed files with 350 additions and 191 deletions
+1
View File
@@ -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' ]
+1
View File
@@ -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)