Feat/face masker models (#834)
* Introduce face masker models * Introduce face masker models * Introduce face masker models * Register needed step keys * Provide different XSeg models
This commit is contained in:
parent
f42117ba61
commit
cf642e4e9d
@ -32,6 +32,8 @@ reference_face_distance =
|
||||
reference_frame_number =
|
||||
|
||||
[face_masker]
|
||||
face_occluder_model =
|
||||
face_parser_model =
|
||||
face_mask_types =
|
||||
face_mask_blur =
|
||||
face_mask_padding =
|
||||
|
@ -71,6 +71,8 @@ def apply_args(args : Args, apply_state_item : ApplyStateItem) -> None:
|
||||
apply_state_item('reference_face_distance', args.get('reference_face_distance'))
|
||||
apply_state_item('reference_frame_number', args.get('reference_frame_number'))
|
||||
# face masker
|
||||
apply_state_item('face_occluder_model', args.get('face_occluder_model'))
|
||||
apply_state_item('face_parser_model', args.get('face_parser_model'))
|
||||
apply_state_item('face_mask_types', args.get('face_mask_types'))
|
||||
apply_state_item('face_mask_blur', args.get('face_mask_blur'))
|
||||
apply_state_item('face_mask_padding', normalize_padding(args.get('face_mask_padding')))
|
||||
|
@ -2,7 +2,7 @@ import logging
|
||||
from typing import List, Sequence
|
||||
|
||||
from facefusion.common_helper import create_float_range, create_int_range
|
||||
from facefusion.typing import Angle, DownloadProvider, DownloadProviderSet, DownloadScope, ExecutionProvider, ExecutionProviderSet, FaceDetectorModel, FaceDetectorSet, FaceLandmarkerModel, FaceMaskRegion, FaceMaskType, FaceSelectorMode, FaceSelectorOrder, Gender, JobStatus, LogLevel, LogLevelSet, OutputAudioEncoder, OutputVideoEncoder, OutputVideoPreset, Race, Score, TempFrameFormat, UiWorkflow, VideoMemoryStrategy
|
||||
from facefusion.typing import Angle, DownloadProvider, DownloadProviderSet, DownloadScope, ExecutionProvider, ExecutionProviderSet, FaceDetectorModel, FaceDetectorSet, FaceLandmarkerModel, FaceMaskRegion, FaceMaskType, FaceOccluderModel, FaceParserModel, FaceSelectorMode, FaceSelectorOrder, Gender, JobStatus, LogLevel, LogLevelSet, OutputAudioEncoder, OutputVideoEncoder, OutputVideoPreset, Race, Score, TempFrameFormat, UiWorkflow, VideoMemoryStrategy
|
||||
|
||||
face_detector_set : FaceDetectorSet =\
|
||||
{
|
||||
@ -15,8 +15,10 @@ face_detector_models : List[FaceDetectorModel] = list(face_detector_set.keys())
|
||||
face_landmarker_models : List[FaceLandmarkerModel] = [ 'many', '2dfan4', 'peppa_wutz' ]
|
||||
face_selector_modes : List[FaceSelectorMode] = [ 'many', 'one', 'reference' ]
|
||||
face_selector_orders : List[FaceSelectorOrder] = [ 'left-right', 'right-left', 'top-bottom', 'bottom-top', 'small-large', 'large-small', 'best-worst', 'worst-best' ]
|
||||
face_selector_genders : List[Gender] = ['female', 'male']
|
||||
face_selector_races : List[Race] = ['white', 'black', 'latino', 'asian', 'indian', 'arabic']
|
||||
face_selector_genders : List[Gender] = [ 'female', 'male' ]
|
||||
face_selector_races : List[Race] = [ 'white', 'black', 'latino', 'asian', 'indian', 'arabic' ]
|
||||
face_occluder_models : List[FaceOccluderModel] = [ 'xseg_1', 'xseg_2' ]
|
||||
face_parser_models : List[FaceParserModel] = [ 'bisenet_resnet_18', 'bisenet_resnet_34' ]
|
||||
face_mask_types : List[FaceMaskType] = [ 'box', 'occlusion', 'region' ]
|
||||
face_mask_regions : List[FaceMaskRegion] = [ 'skin', 'left-eyebrow', 'right-eyebrow', 'left-eye', 'right-eye', 'glasses', 'nose', 'mouth', 'upper-lip', 'lower-lip' ]
|
||||
temp_frame_formats : List[TempFrameFormat] = [ 'bmp', 'jpg', 'png' ]
|
||||
|
@ -96,12 +96,15 @@ def collect_model_downloads() -> Tuple[DownloadSet, DownloadSet]:
|
||||
if state_manager.get_item('face_detector_model') in [ 'many', 'retinaface' ]:
|
||||
model_hashes['retinaface'] = model_set.get('retinaface').get('hashes').get('retinaface')
|
||||
model_sources['retinaface'] = model_set.get('retinaface').get('sources').get('retinaface')
|
||||
|
||||
if state_manager.get_item('face_detector_model') in [ 'many', 'scrfd' ]:
|
||||
model_hashes['scrfd'] = model_set.get('scrfd').get('hashes').get('scrfd')
|
||||
model_sources['scrfd'] = model_set.get('scrfd').get('sources').get('scrfd')
|
||||
|
||||
if state_manager.get_item('face_detector_model') in [ 'many', 'yoloface' ]:
|
||||
model_hashes['yoloface'] = model_set.get('yoloface').get('hashes').get('yoloface')
|
||||
model_sources['yoloface'] = model_set.get('yoloface').get('sources').get('yoloface')
|
||||
|
||||
return model_hashes, model_sources
|
||||
|
||||
|
||||
|
@ -103,9 +103,11 @@ def collect_model_downloads() -> Tuple[DownloadSet, DownloadSet]:
|
||||
if state_manager.get_item('face_landmarker_model') in [ 'many', '2dfan4' ]:
|
||||
model_hashes['2dfan4'] = model_set.get('2dfan4').get('hashes').get('2dfan4')
|
||||
model_sources['2dfan4'] = model_set.get('2dfan4').get('sources').get('2dfan4')
|
||||
|
||||
if state_manager.get_item('face_landmarker_model') in [ 'many', 'peppa_wutz' ]:
|
||||
model_hashes['peppa_wutz'] = model_set.get('peppa_wutz').get('hashes').get('peppa_wutz')
|
||||
model_sources['peppa_wutz'] = model_set.get('peppa_wutz').get('sources').get('peppa_wutz')
|
||||
|
||||
return model_hashes, model_sources
|
||||
|
||||
|
||||
@ -123,6 +125,7 @@ def detect_face_landmarks(vision_frame : VisionFrame, bounding_box : BoundingBox
|
||||
|
||||
if state_manager.get_item('face_landmarker_model') in [ 'many', '2dfan4' ]:
|
||||
face_landmark_2dfan4, face_landmark_score_2dfan4 = detect_with_2dfan4(vision_frame, bounding_box, face_angle)
|
||||
|
||||
if state_manager.get_item('face_landmarker_model') in [ 'many', 'peppa_wutz' ]:
|
||||
face_landmark_peppa_wutz, face_landmark_score_peppa_wutz = detect_with_peppa_wutz(vision_frame, bounding_box, face_angle)
|
||||
|
||||
|
@ -5,7 +5,7 @@ import cv2
|
||||
import numpy
|
||||
from cv2.typing import Size
|
||||
|
||||
from facefusion import inference_manager
|
||||
from facefusion import inference_manager, state_manager
|
||||
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
|
||||
from facefusion.filesystem import resolve_relative_path
|
||||
from facefusion.thread_helper import conditional_thread_semaphore
|
||||
@ -30,27 +30,67 @@ FACE_MASK_REGIONS : Dict[FaceMaskRegion, int] =\
|
||||
def create_static_model_set(download_scope : DownloadScope) -> ModelSet:
|
||||
return\
|
||||
{
|
||||
'face_occluder':
|
||||
'xseg_1':
|
||||
{
|
||||
'hashes':
|
||||
{
|
||||
'face_occluder':
|
||||
{
|
||||
'url': resolve_download_url('models-3.1.0', 'xseg_groggy_5.hash'),
|
||||
'path': resolve_relative_path('../.assets/models/xseg_groggy_5.hash')
|
||||
'url': resolve_download_url('models-3.1.0', 'xseg_1.hash'),
|
||||
'path': resolve_relative_path('../.assets/models/xseg_1.hash')
|
||||
}
|
||||
},
|
||||
'sources':
|
||||
{
|
||||
'face_occluder':
|
||||
{
|
||||
'url': resolve_download_url('models-3.1.0', 'xseg_groggy_5.onnx'),
|
||||
'path': resolve_relative_path('../.assets/models/xseg_groggy_5.onnx')
|
||||
'url': resolve_download_url('models-3.1.0', 'xseg_1.onnx'),
|
||||
'path': resolve_relative_path('../.assets/models/xseg_1.onnx')
|
||||
}
|
||||
},
|
||||
'size': (256, 256)
|
||||
},
|
||||
'face_parser':
|
||||
'xseg_2':
|
||||
{
|
||||
'hashes':
|
||||
{
|
||||
'face_occluder':
|
||||
{
|
||||
'url': resolve_download_url('models-3.1.0', 'xseg_2.hash'),
|
||||
'path': resolve_relative_path('../.assets/models/xseg_2.hash')
|
||||
}
|
||||
},
|
||||
'sources':
|
||||
{
|
||||
'face_occluder':
|
||||
{
|
||||
'url': resolve_download_url('models-3.1.0', 'xseg_2.onnx'),
|
||||
'path': resolve_relative_path('../.assets/models/xseg_2.onnx')
|
||||
}
|
||||
},
|
||||
'size': (256, 256)
|
||||
},
|
||||
'bisenet_resnet_18':
|
||||
{
|
||||
'hashes':
|
||||
{
|
||||
'face_parser':
|
||||
{
|
||||
'url': resolve_download_url('models-3.1.0', 'bisenet_resnet_18.hash'),
|
||||
'path': resolve_relative_path('../.assets/models/bisenet_resnet_18.hash')
|
||||
}
|
||||
},
|
||||
'sources':
|
||||
{
|
||||
'face_parser':
|
||||
{
|
||||
'url': resolve_download_url('models-3.1.0', 'bisenet_resnet_18.onnx'),
|
||||
'path': resolve_relative_path('../.assets/models/bisenet_resnet_18.onnx')
|
||||
}
|
||||
},
|
||||
'size': (512, 512)
|
||||
},
|
||||
'bisenet_resnet_34':
|
||||
{
|
||||
'hashes':
|
||||
{
|
||||
@ -83,17 +123,26 @@ def clear_inference_pool() -> None:
|
||||
|
||||
|
||||
def collect_model_downloads() -> Tuple[DownloadSet, DownloadSet]:
|
||||
model_hashes = {}
|
||||
model_sources = {}
|
||||
model_set = create_static_model_set('full')
|
||||
model_hashes =\
|
||||
{
|
||||
'face_occluder': model_set.get('face_occluder').get('hashes').get('face_occluder'),
|
||||
'face_parser': model_set.get('face_parser').get('hashes').get('face_parser')
|
||||
}
|
||||
model_sources =\
|
||||
{
|
||||
'face_occluder': model_set.get('face_occluder').get('sources').get('face_occluder'),
|
||||
'face_parser': model_set.get('face_parser').get('sources').get('face_parser')
|
||||
}
|
||||
|
||||
if state_manager.get_item('face_occluder_model') == 'xseg_1':
|
||||
model_hashes['xseg_1'] = model_set.get('xseg_1').get('hashes').get('face_occluder')
|
||||
model_sources['xseg_1'] = model_set.get('xseg_1').get('sources').get('face_occluder')
|
||||
|
||||
if state_manager.get_item('face_occluder_model') == 'xseg_2':
|
||||
model_hashes['xseg_2'] = model_set.get('xseg_2').get('hashes').get('face_occluder')
|
||||
model_sources['xseg_2'] = model_set.get('xseg_2').get('sources').get('face_occluder')
|
||||
|
||||
if state_manager.get_item('face_parser_model') == 'bisenet_resnet_18':
|
||||
model_hashes['bisenet_resnet_18'] = model_set.get('bisenet_resnet_18').get('hashes').get('face_parser')
|
||||
model_sources['bisenet_resnet_18'] = model_set.get('bisenet_resnet_18').get('sources').get('face_parser')
|
||||
|
||||
if state_manager.get_item('face_parser_model') == 'bisenet_resnet_34':
|
||||
model_hashes['bisenet_resnet_34'] = model_set.get('bisenet_resnet_34').get('hashes').get('face_parser')
|
||||
model_sources['bisenet_resnet_34'] = model_set.get('bisenet_resnet_34').get('sources').get('face_parser')
|
||||
|
||||
return model_hashes, model_sources
|
||||
|
||||
|
||||
@ -118,7 +167,8 @@ def create_static_box_mask(crop_size : Size, face_mask_blur : float, face_mask_p
|
||||
|
||||
|
||||
def create_occlusion_mask(crop_vision_frame : VisionFrame) -> Mask:
|
||||
model_size = create_static_model_set('full').get('face_occluder').get('size')
|
||||
face_occluder_model = state_manager.get_item('face_occluder_model')
|
||||
model_size = create_static_model_set('full').get(face_occluder_model).get('size')
|
||||
prepare_vision_frame = cv2.resize(crop_vision_frame, model_size)
|
||||
prepare_vision_frame = numpy.expand_dims(prepare_vision_frame, axis = 0).astype(numpy.float32) / 255
|
||||
prepare_vision_frame = prepare_vision_frame.transpose(0, 1, 2, 3)
|
||||
@ -130,7 +180,8 @@ def create_occlusion_mask(crop_vision_frame : VisionFrame) -> Mask:
|
||||
|
||||
|
||||
def create_region_mask(crop_vision_frame : VisionFrame, face_mask_regions : List[FaceMaskRegion]) -> Mask:
|
||||
model_size = create_static_model_set('full').get('face_parser').get('size')
|
||||
face_parser_model = state_manager.get_item('face_parser_model')
|
||||
model_size = create_static_model_set('full').get(face_parser_model).get('size')
|
||||
prepare_vision_frame = cv2.resize(crop_vision_frame, model_size)
|
||||
prepare_vision_frame = prepare_vision_frame[:, :, ::-1].astype(numpy.float32) / 255
|
||||
prepare_vision_frame = numpy.subtract(prepare_vision_frame, numpy.array([ 0.485, 0.456, 0.406 ]).astype(numpy.float32))
|
||||
@ -154,7 +205,8 @@ def create_mouth_mask(face_landmark_68 : FaceLandmark68) -> Mask:
|
||||
|
||||
|
||||
def forward_occlude_face(prepare_vision_frame : VisionFrame) -> Mask:
|
||||
face_occluder = get_inference_pool().get('face_occluder')
|
||||
face_occluder_model = state_manager.get_item('face_occluder_model')
|
||||
face_occluder = get_inference_pool().get(face_occluder_model)
|
||||
|
||||
with conditional_thread_semaphore():
|
||||
occlusion_mask : Mask = face_occluder.run(None,
|
||||
@ -166,7 +218,8 @@ def forward_occlude_face(prepare_vision_frame : VisionFrame) -> Mask:
|
||||
|
||||
|
||||
def forward_parse_face(prepare_vision_frame : VisionFrame) -> Mask:
|
||||
face_parser = get_inference_pool().get('face_parser')
|
||||
face_parser_model = state_manager.get_item('face_parser_model')
|
||||
face_parser = get_inference_pool().get(face_parser_model)
|
||||
|
||||
with conditional_thread_semaphore():
|
||||
region_mask : Mask = face_parser.run(None,
|
||||
|
@ -132,11 +132,13 @@ def create_face_selector_program() -> ArgumentParser:
|
||||
def create_face_masker_program() -> ArgumentParser:
|
||||
program = ArgumentParser(add_help = False)
|
||||
group_face_masker = program.add_argument_group('face masker')
|
||||
group_face_masker.add_argument('--face-occluder-model', help = wording.get('help.face_occluder_model'), default = config.get_str_value('face_detector.face_occluder_model', 'xseg_1'), choices = facefusion.choices.face_occluder_models)
|
||||
group_face_masker.add_argument('--face-parser-model', help = wording.get('help.face_parser_model'), default = config.get_str_value('face_detector.face_parser_model', 'bisenet_resnet_34'), choices = facefusion.choices.face_parser_models)
|
||||
group_face_masker.add_argument('--face-mask-types', help = wording.get('help.face_mask_types').format(choices = ', '.join(facefusion.choices.face_mask_types)), default = config.get_str_list('face_masker.face_mask_types', 'box'), choices = facefusion.choices.face_mask_types, nargs = '+', metavar = 'FACE_MASK_TYPES')
|
||||
group_face_masker.add_argument('--face-mask-blur', help = wording.get('help.face_mask_blur'), type = float, default = config.get_float_value('face_masker.face_mask_blur', '0.3'), choices = facefusion.choices.face_mask_blur_range, metavar = create_float_metavar(facefusion.choices.face_mask_blur_range))
|
||||
group_face_masker.add_argument('--face-mask-padding', help = wording.get('help.face_mask_padding'), type = int, default = config.get_int_list('face_masker.face_mask_padding', '0 0 0 0'), nargs = '+')
|
||||
group_face_masker.add_argument('--face-mask-regions', help = wording.get('help.face_mask_regions').format(choices = ', '.join(facefusion.choices.face_mask_regions)), default = config.get_str_list('face_masker.face_mask_regions', ' '.join(facefusion.choices.face_mask_regions)), choices = facefusion.choices.face_mask_regions, nargs = '+', metavar = 'FACE_MASK_REGIONS')
|
||||
job_store.register_step_keys([ 'face_mask_types', 'face_mask_blur', 'face_mask_padding', 'face_mask_regions' ])
|
||||
job_store.register_step_keys([ 'face_occluder_model', 'face_parser_model', 'face_mask_types', 'face_mask_blur', 'face_mask_padding', 'face_mask_regions' ])
|
||||
return program
|
||||
|
||||
|
||||
|
@ -101,6 +101,8 @@ FaceLandmarkerModel = Literal['many', '2dfan4', 'peppa_wutz']
|
||||
FaceDetectorSet = Dict[FaceDetectorModel, List[str]]
|
||||
FaceSelectorMode = Literal['many', 'one', 'reference']
|
||||
FaceSelectorOrder = Literal['left-right', 'right-left', 'top-bottom', 'bottom-top', 'small-large', 'large-small', 'best-worst', 'worst-best']
|
||||
FaceOccluderModel = Literal['xseg_1', 'xseg_2']
|
||||
FaceParserModel = Literal['bisenet_resnet_18', 'bisenet_resnet_34']
|
||||
FaceMaskType = Literal['box', 'occlusion', 'region']
|
||||
FaceMaskRegion = Literal['skin', 'left-eyebrow', 'right-eyebrow', 'left-eye', 'right-eye', 'glasses', 'nose', 'mouth', 'upper-lip', 'lower-lip']
|
||||
TempFrameFormat = Literal['bmp', 'jpg', 'png']
|
||||
@ -231,6 +233,8 @@ StateKey = Literal\
|
||||
'reference_face_position',
|
||||
'reference_face_distance',
|
||||
'reference_frame_number',
|
||||
'face_occluder_model',
|
||||
'face_parser_model',
|
||||
'face_mask_types',
|
||||
'face_mask_blur',
|
||||
'face_mask_padding',
|
||||
@ -292,6 +296,8 @@ State = TypedDict('State',
|
||||
'reference_face_position' : int,
|
||||
'reference_face_distance' : float,
|
||||
'reference_frame_number' : int,
|
||||
'face_occluder_model' : FaceOccluderModel,
|
||||
'face_parser_model' : FaceParserModel,
|
||||
'face_mask_types' : List[FaceMaskType],
|
||||
'face_mask_blur' : float,
|
||||
'face_mask_padding' : Padding,
|
||||
|
@ -3,11 +3,13 @@ from typing import List, Optional, Tuple
|
||||
import gradio
|
||||
|
||||
import facefusion.choices
|
||||
from facefusion import state_manager, wording
|
||||
from facefusion import face_masker, state_manager, wording
|
||||
from facefusion.common_helper import calc_float_step, calc_int_step
|
||||
from facefusion.typing import FaceMaskRegion, FaceMaskType
|
||||
from facefusion.typing import FaceMaskRegion, FaceMaskType, FaceOccluderModel, FaceParserModel
|
||||
from facefusion.uis.core import register_ui_component
|
||||
|
||||
FACE_OCCLUDER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
||||
FACE_PARSER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
|
||||
FACE_MASK_TYPES_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
FACE_MASK_REGIONS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
FACE_MASK_BLUR_SLIDER : Optional[gradio.Slider] = None
|
||||
@ -18,6 +20,8 @@ FACE_MASK_PADDING_LEFT_SLIDER : Optional[gradio.Slider] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global FACE_OCCLUDER_MODEL_DROPDOWN
|
||||
global FACE_PARSER_MODEL_DROPDOWN
|
||||
global FACE_MASK_TYPES_CHECKBOX_GROUP
|
||||
global FACE_MASK_REGIONS_CHECKBOX_GROUP
|
||||
global FACE_MASK_BLUR_SLIDER
|
||||
@ -28,6 +32,17 @@ def render() -> None:
|
||||
|
||||
has_box_mask = 'box' in state_manager.get_item('face_mask_types')
|
||||
has_region_mask = 'region' in state_manager.get_item('face_mask_types')
|
||||
with gradio.Row():
|
||||
FACE_OCCLUDER_MODEL_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('uis.face_occluder_model_dropdown'),
|
||||
choices = facefusion.choices.face_occluder_models,
|
||||
value = state_manager.get_item('face_occluder_model')
|
||||
)
|
||||
FACE_PARSER_MODEL_DROPDOWN = gradio.Dropdown(
|
||||
label = wording.get('uis.face_parser_model_dropdown'),
|
||||
choices = facefusion.choices.face_parser_models,
|
||||
value = state_manager.get_item('face_parser_model')
|
||||
)
|
||||
FACE_MASK_TYPES_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('uis.face_mask_types_checkbox_group'),
|
||||
choices = facefusion.choices.face_mask_types,
|
||||
@ -82,6 +97,8 @@ def render() -> None:
|
||||
value = state_manager.get_item('face_mask_padding')[3],
|
||||
visible = has_box_mask
|
||||
)
|
||||
register_ui_component('face_occluder_model_dropdown', FACE_OCCLUDER_MODEL_DROPDOWN)
|
||||
register_ui_component('face_parser_model_dropdown', FACE_PARSER_MODEL_DROPDOWN)
|
||||
register_ui_component('face_mask_types_checkbox_group', FACE_MASK_TYPES_CHECKBOX_GROUP)
|
||||
register_ui_component('face_mask_regions_checkbox_group', FACE_MASK_REGIONS_CHECKBOX_GROUP)
|
||||
register_ui_component('face_mask_blur_slider', FACE_MASK_BLUR_SLIDER)
|
||||
@ -92,6 +109,8 @@ def render() -> None:
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
FACE_OCCLUDER_MODEL_DROPDOWN.change(update_face_occluder_model, inputs = FACE_OCCLUDER_MODEL_DROPDOWN)
|
||||
FACE_PARSER_MODEL_DROPDOWN.change(update_face_parser_model, inputs = FACE_PARSER_MODEL_DROPDOWN)
|
||||
FACE_MASK_TYPES_CHECKBOX_GROUP.change(update_face_mask_types, inputs = FACE_MASK_TYPES_CHECKBOX_GROUP, outputs = [ FACE_MASK_TYPES_CHECKBOX_GROUP, FACE_MASK_REGIONS_CHECKBOX_GROUP, FACE_MASK_BLUR_SLIDER, FACE_MASK_PADDING_TOP_SLIDER, FACE_MASK_PADDING_RIGHT_SLIDER, FACE_MASK_PADDING_BOTTOM_SLIDER, FACE_MASK_PADDING_LEFT_SLIDER ])
|
||||
FACE_MASK_REGIONS_CHECKBOX_GROUP.change(update_face_mask_regions, inputs = FACE_MASK_REGIONS_CHECKBOX_GROUP, outputs = FACE_MASK_REGIONS_CHECKBOX_GROUP)
|
||||
FACE_MASK_BLUR_SLIDER.release(update_face_mask_blur, inputs = FACE_MASK_BLUR_SLIDER)
|
||||
@ -100,6 +119,24 @@ def listen() -> None:
|
||||
face_mask_padding_slider.release(update_face_mask_padding, inputs = face_mask_padding_sliders)
|
||||
|
||||
|
||||
def update_face_occluder_model(face_occluder_model : FaceOccluderModel) -> gradio.Dropdown:
|
||||
face_masker.clear_inference_pool()
|
||||
state_manager.set_item('face_occluder_model', face_occluder_model)
|
||||
|
||||
if face_masker.pre_check():
|
||||
return gradio.Dropdown(value = state_manager.get_item('face_occluder_model'))
|
||||
return gradio.Dropdown()
|
||||
|
||||
|
||||
def update_face_parser_model(face_parser_model : FaceParserModel) -> gradio.Dropdown:
|
||||
face_masker.clear_inference_pool()
|
||||
state_manager.set_item('face_parser_model', face_parser_model)
|
||||
|
||||
if face_masker.pre_check():
|
||||
return gradio.Dropdown(value = state_manager.get_item('face_parser_model'))
|
||||
return gradio.Dropdown()
|
||||
|
||||
|
||||
def update_face_mask_types(face_mask_types : List[FaceMaskType]) -> Tuple[gradio.CheckboxGroup, gradio.CheckboxGroup, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider]:
|
||||
face_mask_types = face_mask_types or facefusion.choices.face_mask_types
|
||||
state_manager.set_item('face_mask_types', face_mask_types)
|
||||
|
@ -162,7 +162,9 @@ def listen() -> None:
|
||||
'face_detector_model_dropdown',
|
||||
'face_detector_size_dropdown',
|
||||
'face_detector_angles_checkbox_group',
|
||||
'face_landmarker_model_dropdown'
|
||||
'face_landmarker_model_dropdown',
|
||||
'face_occluder_model_dropdown',
|
||||
'face_parser_model_dropdown'
|
||||
]):
|
||||
ui_component.change(clear_and_update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
|
||||
|
||||
|
@ -52,6 +52,8 @@ ComponentName = Literal\
|
||||
'face_selector_race_dropdown',
|
||||
'face_swapper_model_dropdown',
|
||||
'face_swapper_pixel_boost_dropdown',
|
||||
'face_occluder_model_dropdown',
|
||||
'face_parser_model_dropdown',
|
||||
'frame_colorizer_blend_slider',
|
||||
'frame_colorizer_model_dropdown',
|
||||
'frame_colorizer_size_dropdown',
|
||||
|
@ -126,6 +126,8 @@ WORDING : Dict[str, Any] =\
|
||||
'reference_face_distance': 'specify the similarity between the reference face and target face',
|
||||
'reference_frame_number': 'specify the frame used to create the reference face',
|
||||
# face masker
|
||||
'face_occluder_model': 'choose the model responsible for occluding the face',
|
||||
'face_parser_model': 'choose the model responsible for parsing the face',
|
||||
'face_mask_types': 'mix and match different face mask types (choices: {choices})',
|
||||
'face_mask_blur': 'specify the degree of blur applied to the box mask',
|
||||
'face_mask_padding': 'apply top, right, bottom and left padding to the box mask',
|
||||
@ -285,6 +287,8 @@ WORDING : Dict[str, Any] =\
|
||||
'face_selector_race_dropdown': 'FACE SELECTOR RACE',
|
||||
'face_swapper_model_dropdown': 'FACE SWAPPER MODEL',
|
||||
'face_swapper_pixel_boost_dropdown': 'FACE SWAPPER PIXEL BOOST',
|
||||
'face_occluder_model_dropdown': 'FACE OCCLUDER MODEL',
|
||||
'face_parser_model_dropdown': 'FACE PARSER MODEL',
|
||||
'frame_colorizer_blend_slider': 'FRAME COLORIZER BLEND',
|
||||
'frame_colorizer_model_dropdown': 'FRAME COLORIZER MODEL',
|
||||
'frame_colorizer_size_dropdown': 'FRAME COLORIZER SIZE',
|
||||
|
Loading…
Reference in New Issue
Block a user