2.1.0 (#253)
* Operating system specific installer options * Update dependencies * Sorting before NMS according to the standard * Minor typing fix * Change the wording * Update preview.py (#222) Added a release listener to the preview frame slider, this will update the frame preview with the latest frame * Combine preview slider listener * Remove change listener * Introduce multi source (#223) * Implement multi source * Adjust face enhancer and face debugger to multi source * Implement multi source to UI * Implement multi source to UI part2 * Implement multi source to UI part3 * Implement multi source to UI part4 * Some cleanup * Add face occluder (#225) (#226) * Add face occluder (#225) * add face-occluder (commandline only) * review 1 * Update face_masker.py * Update face_masker.py * Add gui & fix typing * Minor naming cleanup * Minor naming cleanup part2 --------- Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com> * Update usage information * Fix averaged normed_embedding * Remove blur from face occluder, enable accelerators * Switch to RANSAC with 100 threshold * Update face_enhancer.py (#229) * Update face_debugger.py (#230) * Split utilities (#232) * Split utilities * Split utilities part2 * Split utilities part3 * Split utilities part4 * Some cleanup * Implement log level support (#233) * Implement log level support * Fix testing * Implement debug logger * Implement debug logger * Fix alignment offset (#235) * Update face_helper.py * fix 2 * Enforce virtual environment via installer * Enforce virtual environment via installer * Enforce virtual environment via installer * Enforce virtual environment via installer * Feat/multi process reference faces (#239) * Multi processing aware reference faces * First clean up and joining of files * Finalize the face store * Reduce similar face detection to one set, use __name__ for scopes in logger * Rename to face_occluder * Introduce ModelSet type * Improve webcam error handling * Prevent null pointer on is_image() and is_video() * Prevent null pointer on is_image() and is_video() * Fix find similar faces * Fix find similar faces * Fix process_images for face enhancer * Bunch of minor improvements * onnxruntime for ROCM under linux * Improve mask related naming * Fix falsy import * Fix typo * Feat/face parser refactoring (#247) * Face parser update (#244) * face-parser * Update face_masker.py * update debugger * Update globals.py * Update face_masker.py * Refactor code to split occlusion from region * fix (#246) * fix * fix debugger resolution * flip input to horizontal * Clean up UI * Reduce the regions to inside face only * Reduce the regions to inside face only --------- Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com> * Fix enhancer, remove useless dest in add_argument() * Prevent unselect of the face_mask_regions via UI * Prepare next release * Shorten arguments that have choices and nargs * Add missing clear to face debugger --------- Co-authored-by: Mathias <github@feroc.de> Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com>
This commit is contained in:
@@ -7,11 +7,12 @@ import gradio
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.face_analyser import get_face_analyser
|
||||
from facefusion.face_cache import clear_faces_cache
|
||||
from facefusion.face_store import clear_static_faces
|
||||
from facefusion.processors.frame.core import get_frame_processors_modules
|
||||
from facefusion.vision import count_video_frame_total
|
||||
from facefusion.core import limit_resources, conditional_process
|
||||
from facefusion.utilities import normalize_output_path, clear_temp
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.filesystem import clear_temp
|
||||
from facefusion.uis.core import get_ui_component
|
||||
|
||||
BENCHMARK_RESULTS_DATAFRAME : Optional[gradio.Dataframe] = None
|
||||
@@ -75,7 +76,7 @@ def listen() -> None:
|
||||
|
||||
|
||||
def start(benchmark_runs : List[str], benchmark_cycles : int) -> Generator[List[Any], None, None]:
|
||||
facefusion.globals.source_path = '.assets/examples/source.jpg'
|
||||
facefusion.globals.source_paths = [ '.assets/examples/source.jpg' ]
|
||||
target_paths = [ BENCHMARKS[benchmark_run] for benchmark_run in benchmark_runs if benchmark_run in BENCHMARKS ]
|
||||
benchmark_results = []
|
||||
if target_paths:
|
||||
@@ -94,7 +95,7 @@ def pre_process() -> None:
|
||||
|
||||
|
||||
def post_process() -> None:
|
||||
clear_faces_cache()
|
||||
clear_static_faces()
|
||||
|
||||
|
||||
def benchmark(target_path : str, benchmark_cycles : int) -> List[Any]:
|
||||
@@ -102,7 +103,7 @@ def benchmark(target_path : str, benchmark_cycles : int) -> List[Any]:
|
||||
total_fps = 0.0
|
||||
for i in range(benchmark_cycles):
|
||||
facefusion.globals.target_path = target_path
|
||||
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_path, facefusion.globals.target_path, tempfile.gettempdir())
|
||||
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_paths, facefusion.globals.target_path, tempfile.gettempdir())
|
||||
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
|
||||
start_time = time.perf_counter()
|
||||
conditional_process()
|
||||
|
||||
@@ -6,7 +6,7 @@ import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.face_analyser import clear_face_analyser
|
||||
from facefusion.processors.frame.core import clear_frame_processors_modules
|
||||
from facefusion.utilities import encode_execution_providers, decode_execution_providers
|
||||
from facefusion.execution_helper import encode_execution_providers, decode_execution_providers
|
||||
|
||||
EXECUTION_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ def render() -> None:
|
||||
FACE_DETECTOR_SCORE_SLIDER = gradio.Slider(
|
||||
label = wording.get('face_detector_score_slider_label'),
|
||||
value = facefusion.globals.face_detector_score,
|
||||
step =facefusion.choices.face_detector_score_range[1] - facefusion.choices.face_detector_score_range[0],
|
||||
step = facefusion.choices.face_detector_score_range[1] - facefusion.choices.face_detector_score_range[0],
|
||||
minimum = facefusion.choices.face_detector_score_range[0],
|
||||
maximum = facefusion.choices.face_detector_score_range[-1]
|
||||
)
|
||||
|
||||
@@ -1,33 +1,49 @@
|
||||
from typing import Optional
|
||||
from typing import Optional, Tuple, List
|
||||
import gradio
|
||||
|
||||
import facefusion.globals
|
||||
import facefusion.choices
|
||||
from facefusion import wording
|
||||
from facefusion.typing import FaceMaskType, FaceMaskRegion
|
||||
from facefusion.uis.core import register_ui_component
|
||||
|
||||
FACE_MASK_TYPES_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
FACE_MASK_BLUR_SLIDER : Optional[gradio.Slider] = None
|
||||
FACE_MASK_BOX_GROUP : Optional[gradio.Group] = None
|
||||
FACE_MASK_REGION_GROUP : Optional[gradio.Group] = None
|
||||
FACE_MASK_PADDING_TOP_SLIDER : Optional[gradio.Slider] = None
|
||||
FACE_MASK_PADDING_RIGHT_SLIDER : Optional[gradio.Slider] = None
|
||||
FACE_MASK_PADDING_BOTTOM_SLIDER : Optional[gradio.Slider] = None
|
||||
FACE_MASK_PADDING_LEFT_SLIDER : Optional[gradio.Slider] = None
|
||||
FACE_MASK_REGION_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
|
||||
|
||||
def render() -> None:
|
||||
global FACE_MASK_TYPES_CHECKBOX_GROUP
|
||||
global FACE_MASK_BLUR_SLIDER
|
||||
global FACE_MASK_BOX_GROUP
|
||||
global FACE_MASK_REGION_GROUP
|
||||
global FACE_MASK_PADDING_TOP_SLIDER
|
||||
global FACE_MASK_PADDING_RIGHT_SLIDER
|
||||
global FACE_MASK_PADDING_BOTTOM_SLIDER
|
||||
global FACE_MASK_PADDING_LEFT_SLIDER
|
||||
global FACE_MASK_REGION_CHECKBOX_GROUP
|
||||
|
||||
FACE_MASK_BLUR_SLIDER = gradio.Slider(
|
||||
label = wording.get('face_mask_blur_slider_label'),
|
||||
step = facefusion.choices.face_mask_blur_range[1] - facefusion.choices.face_mask_blur_range[0],
|
||||
minimum = facefusion.choices.face_mask_blur_range[0],
|
||||
maximum = facefusion.choices.face_mask_blur_range[-1],
|
||||
value = facefusion.globals.face_mask_blur
|
||||
has_box_mask = 'box' in facefusion.globals.face_mask_types
|
||||
has_region_mask = 'region' in facefusion.globals.face_mask_types
|
||||
FACE_MASK_TYPES_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('face_mask_types_checkbox_group_label'),
|
||||
choices = facefusion.choices.face_mask_types,
|
||||
value = facefusion.globals.face_mask_types
|
||||
)
|
||||
with gradio.Group():
|
||||
with gradio.Group(visible = has_box_mask) as FACE_MASK_BOX_GROUP:
|
||||
FACE_MASK_BLUR_SLIDER = gradio.Slider(
|
||||
label = wording.get('face_mask_blur_slider_label'),
|
||||
step = facefusion.choices.face_mask_blur_range[1] - facefusion.choices.face_mask_blur_range[0],
|
||||
minimum = facefusion.choices.face_mask_blur_range[0],
|
||||
maximum = facefusion.choices.face_mask_blur_range[-1],
|
||||
value = facefusion.globals.face_mask_blur
|
||||
)
|
||||
with gradio.Row():
|
||||
FACE_MASK_PADDING_TOP_SLIDER = gradio.Slider(
|
||||
label = wording.get('face_mask_padding_top_slider_label'),
|
||||
@@ -58,23 +74,50 @@ def render() -> None:
|
||||
maximum = facefusion.choices.face_mask_padding_range[-1],
|
||||
value = facefusion.globals.face_mask_padding[3]
|
||||
)
|
||||
with gradio.Row():
|
||||
FACE_MASK_REGION_CHECKBOX_GROUP = gradio.CheckboxGroup(
|
||||
label = wording.get('face_mask_region_checkbox_group_label'),
|
||||
choices = facefusion.choices.face_mask_regions,
|
||||
value = facefusion.globals.face_mask_regions,
|
||||
visible = has_region_mask
|
||||
)
|
||||
register_ui_component('face_mask_types_checkbox_group', FACE_MASK_TYPES_CHECKBOX_GROUP)
|
||||
register_ui_component('face_mask_blur_slider', FACE_MASK_BLUR_SLIDER)
|
||||
register_ui_component('face_mask_padding_top_slider', FACE_MASK_PADDING_TOP_SLIDER)
|
||||
register_ui_component('face_mask_padding_right_slider', FACE_MASK_PADDING_RIGHT_SLIDER)
|
||||
register_ui_component('face_mask_padding_bottom_slider', FACE_MASK_PADDING_BOTTOM_SLIDER)
|
||||
register_ui_component('face_mask_padding_left_slider', FACE_MASK_PADDING_LEFT_SLIDER)
|
||||
register_ui_component('face_mask_region_checkbox_group', FACE_MASK_REGION_CHECKBOX_GROUP)
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
FACE_MASK_TYPES_CHECKBOX_GROUP.change(update_face_mask_type, inputs = FACE_MASK_TYPES_CHECKBOX_GROUP, outputs = [ FACE_MASK_TYPES_CHECKBOX_GROUP, FACE_MASK_BOX_GROUP, FACE_MASK_REGION_CHECKBOX_GROUP ])
|
||||
FACE_MASK_BLUR_SLIDER.change(update_face_mask_blur, inputs = FACE_MASK_BLUR_SLIDER)
|
||||
FACE_MASK_REGION_CHECKBOX_GROUP.change(update_face_mask_regions, inputs = FACE_MASK_REGION_CHECKBOX_GROUP, outputs = FACE_MASK_REGION_CHECKBOX_GROUP)
|
||||
face_mask_padding_sliders = [ FACE_MASK_PADDING_TOP_SLIDER, FACE_MASK_PADDING_RIGHT_SLIDER, FACE_MASK_PADDING_BOTTOM_SLIDER, FACE_MASK_PADDING_LEFT_SLIDER ]
|
||||
for face_mask_padding_slider in face_mask_padding_sliders:
|
||||
face_mask_padding_slider.change(update_face_mask_padding, inputs = face_mask_padding_sliders)
|
||||
|
||||
|
||||
def update_face_mask_type(face_mask_types : List[FaceMaskType]) -> Tuple[gradio.CheckboxGroup, gradio.Group, gradio.CheckboxGroup]:
|
||||
if not face_mask_types:
|
||||
face_mask_types = facefusion.choices.face_mask_types
|
||||
facefusion.globals.face_mask_types = face_mask_types
|
||||
has_box_mask = 'box' in face_mask_types
|
||||
has_region_mask = 'region' in face_mask_types
|
||||
return gradio.CheckboxGroup(value = face_mask_types), gradio.Group(visible = has_box_mask), gradio.CheckboxGroup(visible = has_region_mask)
|
||||
|
||||
|
||||
def update_face_mask_blur(face_mask_blur : float) -> None:
|
||||
facefusion.globals.face_mask_blur = face_mask_blur
|
||||
|
||||
|
||||
def update_face_mask_padding(face_mask_padding_top : int, face_mask_padding_right : int, face_mask_padding_bottom : int, face_mask_padding_left : int) -> None:
|
||||
facefusion.globals.face_mask_padding = (face_mask_padding_top, face_mask_padding_right, face_mask_padding_bottom, face_mask_padding_left)
|
||||
|
||||
|
||||
def update_face_mask_regions(face_mask_regions : List[FaceMaskRegion]) -> gradio.CheckboxGroup:
|
||||
if not face_mask_regions:
|
||||
face_mask_regions = facefusion.choices.face_mask_regions
|
||||
facefusion.globals.face_mask_regions = face_mask_regions
|
||||
return gradio.CheckboxGroup(value = face_mask_regions)
|
||||
@@ -5,12 +5,11 @@ import gradio
|
||||
import facefusion.globals
|
||||
import facefusion.choices
|
||||
from facefusion import wording
|
||||
from facefusion.face_cache import clear_faces_cache
|
||||
from facefusion.face_store import clear_static_faces, clear_reference_faces
|
||||
from facefusion.vision import get_video_frame, read_static_image, normalize_frame_color
|
||||
from facefusion.face_analyser import get_many_faces
|
||||
from facefusion.face_reference import clear_face_reference
|
||||
from facefusion.typing import Frame, FaceSelectorMode
|
||||
from facefusion.utilities import is_image, is_video
|
||||
from facefusion.filesystem import is_image, is_video
|
||||
from facefusion.uis.core import get_ui_component, register_ui_component
|
||||
from facefusion.uis.typing import ComponentName
|
||||
|
||||
@@ -111,8 +110,8 @@ def update_face_selector_mode(face_selector_mode : FaceSelectorMode) -> Tuple[gr
|
||||
|
||||
|
||||
def clear_and_update_reference_face_position(event : gradio.SelectData) -> gradio.Gallery:
|
||||
clear_face_reference()
|
||||
clear_faces_cache()
|
||||
clear_reference_faces()
|
||||
clear_static_faces()
|
||||
update_reference_face_position(event.index)
|
||||
return update_reference_position_gallery()
|
||||
|
||||
@@ -130,8 +129,8 @@ def update_reference_frame_number(reference_frame_number : int) -> None:
|
||||
|
||||
|
||||
def clear_and_update_reference_position_gallery() -> gradio.Gallery:
|
||||
clear_face_reference()
|
||||
clear_faces_cache()
|
||||
clear_reference_faces()
|
||||
clear_static_faces()
|
||||
return update_reference_position_gallery()
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import gradio
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.processors.frame.core import load_frame_processor_module, clear_frame_processors_modules
|
||||
from facefusion.utilities import list_module_names
|
||||
from facefusion.filesystem import list_module_names
|
||||
from facefusion.uis.core import register_ui_component
|
||||
|
||||
FRAME_PROCESSORS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
|
||||
|
||||
@@ -5,7 +5,8 @@ import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.core import limit_resources, conditional_process
|
||||
from facefusion.uis.core import get_ui_component
|
||||
from facefusion.utilities import is_image, is_video, normalize_output_path, clear_temp
|
||||
from facefusion.normalizer import normalize_output_path
|
||||
from facefusion.filesystem import is_image, is_video, clear_temp
|
||||
|
||||
OUTPUT_IMAGE : Optional[gradio.Image] = None
|
||||
OUTPUT_VIDEO : Optional[gradio.Video] = None
|
||||
@@ -45,7 +46,7 @@ def listen() -> None:
|
||||
|
||||
|
||||
def start(output_path : str) -> Tuple[gradio.Image, gradio.Video]:
|
||||
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_path, facefusion.globals.target_path, output_path)
|
||||
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_paths, facefusion.globals.target_path, output_path)
|
||||
limit_resources()
|
||||
conditional_process()
|
||||
if is_image(facefusion.globals.output_path):
|
||||
|
||||
@@ -6,7 +6,7 @@ import facefusion.globals
|
||||
import facefusion.choices
|
||||
from facefusion import wording
|
||||
from facefusion.typing import OutputVideoEncoder
|
||||
from facefusion.utilities import is_image, is_video
|
||||
from facefusion.filesystem import is_image, is_video
|
||||
from facefusion.uis.typing import ComponentName
|
||||
from facefusion.uis.core import get_ui_component, register_ui_component
|
||||
|
||||
|
||||
@@ -4,15 +4,14 @@ import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.core import conditional_set_face_reference
|
||||
from facefusion.face_cache import clear_faces_cache
|
||||
from facefusion.typing import Frame, Face
|
||||
from facefusion.vision import get_video_frame, count_video_frame_total, normalize_frame_color, resize_frame_dimension, read_static_image
|
||||
from facefusion.face_analyser import get_one_face, clear_face_analyser
|
||||
from facefusion.face_reference import get_face_reference, clear_face_reference
|
||||
from facefusion.core import conditional_append_reference_faces
|
||||
from facefusion.face_store import clear_static_faces, get_reference_faces, clear_reference_faces
|
||||
from facefusion.typing import Frame, Face, FaceSet
|
||||
from facefusion.vision import get_video_frame, count_video_frame_total, normalize_frame_color, resize_frame_dimension, read_static_image, read_static_images
|
||||
from facefusion.face_analyser import get_average_face, clear_face_analyser
|
||||
from facefusion.content_analyser import analyse_frame
|
||||
from facefusion.processors.frame.core import load_frame_processor_module
|
||||
from facefusion.utilities import is_video, is_image
|
||||
from facefusion.filesystem import is_image, is_video
|
||||
from facefusion.uis.typing import ComponentName
|
||||
from facefusion.uis.core import get_ui_component, register_ui_component
|
||||
|
||||
@@ -37,16 +36,17 @@ def render() -> None:
|
||||
'maximum': 100,
|
||||
'visible': False
|
||||
}
|
||||
conditional_set_face_reference()
|
||||
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
|
||||
reference_face = get_face_reference() if 'reference' in facefusion.globals.face_selector_mode else None
|
||||
conditional_append_reference_faces()
|
||||
source_frames = read_static_images(facefusion.globals.source_paths)
|
||||
source_face = get_average_face(source_frames)
|
||||
reference_faces = get_reference_faces() if 'reference' in facefusion.globals.face_selector_mode else None
|
||||
if is_image(facefusion.globals.target_path):
|
||||
target_frame = read_static_image(facefusion.globals.target_path)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, target_frame)
|
||||
preview_frame = process_preview_frame(source_face, reference_faces, target_frame)
|
||||
preview_image_args['value'] = normalize_frame_color(preview_frame)
|
||||
if is_video(facefusion.globals.target_path):
|
||||
temp_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, temp_frame)
|
||||
preview_frame = process_preview_frame(source_face, reference_faces, temp_frame)
|
||||
preview_image_args['value'] = normalize_frame_color(preview_frame)
|
||||
preview_image_args['visible'] = True
|
||||
preview_frame_slider_args['value'] = facefusion.globals.reference_frame_number
|
||||
@@ -58,7 +58,7 @@ def render() -> None:
|
||||
|
||||
|
||||
def listen() -> None:
|
||||
PREVIEW_FRAME_SLIDER.change(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
|
||||
PREVIEW_FRAME_SLIDER.release(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
|
||||
multi_one_component_names : List[ComponentName] =\
|
||||
[
|
||||
'source_image',
|
||||
@@ -101,11 +101,13 @@ def listen() -> None:
|
||||
'frame_enhancer_blend_slider',
|
||||
'face_selector_mode_dropdown',
|
||||
'reference_face_distance_slider',
|
||||
'face_mask_types_checkbox_group',
|
||||
'face_mask_blur_slider',
|
||||
'face_mask_padding_top_slider',
|
||||
'face_mask_padding_bottom_slider',
|
||||
'face_mask_padding_left_slider',
|
||||
'face_mask_padding_right_slider'
|
||||
'face_mask_padding_right_slider',
|
||||
'face_mask_region_checkbox_group'
|
||||
]
|
||||
for component_name in change_one_component_names:
|
||||
component = get_ui_component(component_name)
|
||||
@@ -126,15 +128,17 @@ def listen() -> None:
|
||||
|
||||
def clear_and_update_preview_image(frame_number : int = 0) -> gradio.Image:
|
||||
clear_face_analyser()
|
||||
clear_face_reference()
|
||||
clear_faces_cache()
|
||||
clear_reference_faces()
|
||||
clear_static_faces()
|
||||
return update_preview_image(frame_number)
|
||||
|
||||
|
||||
def update_preview_image(frame_number : int = 0) -> gradio.Image:
|
||||
conditional_set_face_reference()
|
||||
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
|
||||
reference_face = get_face_reference() if 'reference' in facefusion.globals.face_selector_mode else None
|
||||
clear_reference_faces()
|
||||
conditional_append_reference_faces()
|
||||
source_frames = read_static_images(facefusion.globals.source_paths)
|
||||
source_face = get_average_face(source_frames)
|
||||
reference_face = get_reference_faces() if 'reference' in facefusion.globals.face_selector_mode else None
|
||||
if is_image(facefusion.globals.target_path):
|
||||
target_frame = read_static_image(facefusion.globals.target_path)
|
||||
preview_frame = process_preview_frame(source_face, reference_face, target_frame)
|
||||
@@ -155,7 +159,7 @@ def update_preview_frame_slider() -> gradio.Slider:
|
||||
return gradio.Slider(value = None, maximum = None, visible = False)
|
||||
|
||||
|
||||
def process_preview_frame(source_face : Face, reference_face : Face, temp_frame : Frame) -> Frame:
|
||||
def process_preview_frame(source_face : Face, reference_faces : FaceSet, temp_frame : Frame) -> Frame:
|
||||
temp_frame = resize_frame_dimension(temp_frame, 640, 640)
|
||||
if analyse_frame(temp_frame):
|
||||
return cv2.GaussianBlur(temp_frame, (99, 99), 0)
|
||||
@@ -164,7 +168,7 @@ def process_preview_frame(source_face : Face, reference_face : Face, temp_frame
|
||||
if frame_processor_module.pre_process('preview'):
|
||||
temp_frame = frame_processor_module.process_frame(
|
||||
source_face,
|
||||
reference_face,
|
||||
reference_faces,
|
||||
temp_frame
|
||||
)
|
||||
return temp_frame
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from typing import Any, IO, Optional
|
||||
from typing import Optional, List
|
||||
import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.utilities import is_image
|
||||
from facefusion.uis.typing import File
|
||||
from facefusion.filesystem import are_images
|
||||
from facefusion.uis.core import register_ui_component
|
||||
|
||||
SOURCE_FILE : Optional[gradio.File] = None
|
||||
@@ -14,9 +15,9 @@ def render() -> None:
|
||||
global SOURCE_FILE
|
||||
global SOURCE_IMAGE
|
||||
|
||||
is_source_image = is_image(facefusion.globals.source_path)
|
||||
are_source_images = are_images(facefusion.globals.source_paths)
|
||||
SOURCE_FILE = gradio.File(
|
||||
file_count = 'single',
|
||||
file_count = 'multiple',
|
||||
file_types =
|
||||
[
|
||||
'.png',
|
||||
@@ -24,11 +25,12 @@ def render() -> None:
|
||||
'.webp'
|
||||
],
|
||||
label = wording.get('source_file_label'),
|
||||
value = facefusion.globals.source_path if is_source_image else None
|
||||
value = facefusion.globals.source_paths if are_source_images else None
|
||||
)
|
||||
source_file_names = [ source_file_value['name'] for source_file_value in SOURCE_FILE.value ] if SOURCE_FILE.value else None
|
||||
SOURCE_IMAGE = gradio.Image(
|
||||
value = SOURCE_FILE.value['name'] if is_source_image else None,
|
||||
visible = is_source_image,
|
||||
value = source_file_names[0] if are_source_images else None,
|
||||
visible = are_source_images,
|
||||
show_label = False
|
||||
)
|
||||
register_ui_component('source_image', SOURCE_IMAGE)
|
||||
@@ -38,9 +40,10 @@ def listen() -> None:
|
||||
SOURCE_FILE.change(update, inputs = SOURCE_FILE, outputs = SOURCE_IMAGE)
|
||||
|
||||
|
||||
def update(file: IO[Any]) -> gradio.Image:
|
||||
if file and is_image(file.name):
|
||||
facefusion.globals.source_path = file.name
|
||||
return gradio.Image(value = file.name, visible = True)
|
||||
facefusion.globals.source_path = None
|
||||
def update(files : List[File]) -> gradio.Image:
|
||||
file_names = [ file.name for file in files ] if files else None
|
||||
if are_images(file_names):
|
||||
facefusion.globals.source_paths = file_names
|
||||
return gradio.Image(value = file_names[0], visible = True)
|
||||
facefusion.globals.source_paths = None
|
||||
return gradio.Image(value = None, visible = False)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from typing import Any, IO, Tuple, Optional
|
||||
from typing import Tuple, Optional
|
||||
import gradio
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.face_cache import clear_faces_cache
|
||||
from facefusion.face_reference import clear_face_reference
|
||||
from facefusion.utilities import is_image, is_video
|
||||
from facefusion.face_store import clear_static_faces, clear_reference_faces
|
||||
from facefusion.uis.typing import File
|
||||
from facefusion.filesystem import is_image, is_video
|
||||
from facefusion.uis.core import register_ui_component
|
||||
|
||||
TARGET_FILE : Optional[gradio.File] = None
|
||||
@@ -50,9 +50,9 @@ def listen() -> None:
|
||||
TARGET_FILE.change(update, inputs = TARGET_FILE, outputs = [ TARGET_IMAGE, TARGET_VIDEO ])
|
||||
|
||||
|
||||
def update(file : IO[Any]) -> Tuple[gradio.Image, gradio.Video]:
|
||||
clear_face_reference()
|
||||
clear_faces_cache()
|
||||
def update(file : File) -> Tuple[gradio.Image, gradio.Video]:
|
||||
clear_reference_faces()
|
||||
clear_static_faces()
|
||||
if file and is_image(file.name):
|
||||
facefusion.globals.target_path = file.name
|
||||
return gradio.Image(value = file.name, visible = True), gradio.Video(value = None, visible = False)
|
||||
|
||||
@@ -5,7 +5,7 @@ import facefusion.globals
|
||||
import facefusion.choices
|
||||
from facefusion import wording
|
||||
from facefusion.typing import TempFrameFormat
|
||||
from facefusion.utilities import is_video
|
||||
from facefusion.filesystem import is_video
|
||||
from facefusion.uis.core import get_ui_component
|
||||
|
||||
TEMP_FRAME_FORMAT_DROPDOWN : Optional[gradio.Dropdown] = None
|
||||
|
||||
@@ -4,7 +4,7 @@ import gradio
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion.vision import count_video_frame_total
|
||||
from facefusion.utilities import is_video
|
||||
from facefusion.filesystem import is_video
|
||||
from facefusion.uis.core import get_ui_component
|
||||
|
||||
TRIM_FRAME_START_SLIDER : Optional[gradio.Slider] = None
|
||||
|
||||
@@ -9,13 +9,13 @@ import gradio
|
||||
from tqdm import tqdm
|
||||
|
||||
import facefusion.globals
|
||||
from facefusion import wording
|
||||
from facefusion import logger, wording
|
||||
from facefusion.content_analyser import analyse_stream
|
||||
from facefusion.typing import Frame, Face
|
||||
from facefusion.face_analyser import get_one_face
|
||||
from facefusion.face_analyser import get_average_face
|
||||
from facefusion.processors.frame.core import get_frame_processors_modules
|
||||
from facefusion.utilities import open_ffmpeg
|
||||
from facefusion.vision import normalize_frame_color, read_static_image
|
||||
from facefusion.ffmpeg import open_ffmpeg
|
||||
from facefusion.vision import normalize_frame_color, read_static_images
|
||||
from facefusion.uis.typing import StreamMode, WebcamMode
|
||||
from facefusion.uis.core import get_ui_component
|
||||
|
||||
@@ -79,30 +79,34 @@ def listen() -> None:
|
||||
getattr(source_image, method)(stop, cancels = start_event)
|
||||
|
||||
|
||||
def start(mode : WebcamMode, resolution : str, fps : float) -> Generator[Frame, None, None]:
|
||||
def start(webcam_mode : WebcamMode, resolution : str, fps : float) -> Generator[Frame, None, None]:
|
||||
facefusion.globals.face_selector_mode = 'one'
|
||||
facefusion.globals.face_analyser_order = 'large-small'
|
||||
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
|
||||
source_frames = read_static_images(facefusion.globals.source_paths)
|
||||
source_face = get_average_face(source_frames)
|
||||
stream = None
|
||||
if mode in [ 'udp', 'v4l2' ]:
|
||||
stream = open_stream(mode, resolution, fps) # type: ignore[arg-type]
|
||||
if webcam_mode in [ 'udp', 'v4l2' ]:
|
||||
stream = open_stream(webcam_mode, resolution, fps) # type: ignore[arg-type]
|
||||
webcam_width, webcam_height = map(int, resolution.split('x'))
|
||||
webcam_capture = get_webcam_capture()
|
||||
if webcam_capture and webcam_capture.isOpened():
|
||||
webcam_capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) # type: ignore[attr-defined]
|
||||
webcam_capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) # type: ignore[attr-defined]
|
||||
webcam_capture.set(cv2.CAP_PROP_FRAME_WIDTH, webcam_width)
|
||||
webcam_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, webcam_height)
|
||||
webcam_capture.set(cv2.CAP_PROP_FPS, fps)
|
||||
for capture_frame in multi_process_capture(source_face, webcam_capture, fps):
|
||||
if mode == 'inline':
|
||||
if webcam_mode == 'inline':
|
||||
yield normalize_frame_color(capture_frame)
|
||||
else:
|
||||
stream.stdin.write(capture_frame.tobytes())
|
||||
try:
|
||||
stream.stdin.write(capture_frame.tobytes())
|
||||
except Exception:
|
||||
clear_webcam_capture()
|
||||
yield None
|
||||
|
||||
|
||||
def multi_process_capture(source_face : Face, webcam_capture : cv2.VideoCapture, fps : float) -> Generator[Frame, None, None]:
|
||||
with tqdm(desc = wording.get('processing'), unit = 'frame', ascii = ' =') as progress:
|
||||
with tqdm(desc = wording.get('processing'), unit = 'frame', ascii = ' =', disable = facefusion.globals.log_level in [ 'warn', 'error' ]) as progress:
|
||||
with ThreadPoolExecutor(max_workers = facefusion.globals.execution_thread_count) as executor:
|
||||
futures = []
|
||||
deque_capture_frames : Deque[Frame] = deque()
|
||||
@@ -137,11 +141,15 @@ def process_stream_frame(source_face : Face, temp_frame : Frame) -> Frame:
|
||||
return temp_frame
|
||||
|
||||
|
||||
def open_stream(mode : StreamMode, resolution : str, fps : float) -> subprocess.Popen[bytes]:
|
||||
def open_stream(stream_mode : StreamMode, resolution : str, fps : float) -> subprocess.Popen[bytes]:
|
||||
commands = [ '-f', 'rawvideo', '-pix_fmt', 'bgr24', '-s', resolution, '-r', str(fps), '-i', '-' ]
|
||||
if mode == 'udp':
|
||||
if stream_mode == 'udp':
|
||||
commands.extend([ '-b:v', '2000k', '-f', 'mpegts', 'udp://localhost:27000?pkt_size=1316' ])
|
||||
if mode == 'v4l2':
|
||||
device_name = os.listdir('/sys/devices/virtual/video4linux')[0]
|
||||
commands.extend([ '-f', 'v4l2', '/dev/' + device_name ])
|
||||
if stream_mode == 'v4l2':
|
||||
try:
|
||||
device_name = os.listdir('/sys/devices/virtual/video4linux')[0]
|
||||
if device_name:
|
||||
commands.extend([ '-f', 'v4l2', '/dev/' + device_name ])
|
||||
except FileNotFoundError:
|
||||
logger.error(wording.get('stream_not_loaded').format(stream_mode = stream_mode), __name__.upper())
|
||||
return open_ffmpeg(commands)
|
||||
|
||||
Reference in New Issue
Block a user