diff --git a/facefusion/workflows/image_to_video.py b/facefusion/workflows/image_to_video.py index 19e6538e..a71661f7 100644 --- a/facefusion/workflows/image_to_video.py +++ b/facefusion/workflows/image_to_video.py @@ -7,13 +7,13 @@ from tqdm import tqdm from facefusion import ffmpeg from facefusion import logger, process_manager, state_manager, translator, video_manager from facefusion.audio import create_empty_audio_frame, get_audio_frame, get_voice_frame -from facefusion.common_helper import get_first +from facefusion.common_helper import get_first, get_middle from facefusion.content_analyser import analyse_video from facefusion.filesystem import filter_audio_paths, is_video from facefusion.processors.core import get_processors_modules from facefusion.temp_helper import clear_temp_directory, create_temp_directory, move_temp_file, resolve_temp_frame_set from facefusion.time_helper import calculate_end_time -from facefusion.types import ErrorCode +from facefusion.types import ErrorCode, Resolution from facefusion.vision import conditional_merge_vision_mask, detect_video_resolution, extract_vision_mask, pack_resolution, read_static_image, read_static_images, read_static_video_frame, restrict_trim_frame, restrict_video_fps, restrict_video_resolution, scale_resolution, select_video_frames, write_image from facefusion.workflows.core import is_process_stopping @@ -75,6 +75,8 @@ def extract_frames() -> ErrorCode: def process_video() -> ErrorCode: temp_frame_set = resolve_temp_frame_set(state_manager.get_item('target_path')) + output_video_resolution = scale_resolution(detect_video_resolution(state_manager.get_item('target_path')), state_manager.get_item('output_video_scale')) + temp_video_resolution = restrict_video_resolution(state_manager.get_item('target_path'), output_video_resolution) if temp_frame_set: with tqdm(total = len(temp_frame_set), desc = translator.get('processing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress: @@ -84,7 +86,7 @@ def process_video() -> ErrorCode: futures = [] for frame_number, temp_frame_path in temp_frame_set.items(): - future = executor.submit(process_temp_frame, temp_frame_path, frame_number) + future = executor.submit(process_temp_frame, temp_frame_path, frame_number, temp_video_resolution) futures.append(future) for future in as_completed(futures): @@ -154,14 +156,18 @@ def restore_audio() -> ErrorCode: return 0 -def process_temp_frame(temp_frame_path : str, frame_number : int) -> bool: +def process_temp_frame(temp_frame_path : str, frame_number : int, temp_video_resolution : Resolution) -> bool: trim_frame_start, _ = restrict_trim_frame(state_manager.get_item('target_path'), state_manager.get_item('trim_frame_start'), state_manager.get_item('trim_frame_end')) reference_vision_frame = read_static_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number')) source_vision_frames = read_static_images(state_manager.get_item('source_paths')) source_audio_path = get_first(filter_audio_paths(state_manager.get_item('source_paths'))) target_vision_frames = select_video_frames(state_manager.get_item('target_path'), frame_number, state_manager.get_item('target_frame_amount')) + target_vision_frame = get_middle(target_vision_frames) temp_video_fps = restrict_video_fps(state_manager.get_item('target_path'), state_manager.get_item('output_video_fps')) - temp_vision_frame = read_static_image(temp_frame_path, 'rgba') + + if not (target_vision_frame.shape[1], target_vision_frame.shape[0]) == temp_video_resolution: + target_vision_frame = read_static_image(temp_frame_path, 'rgba') + temp_vision_frame = target_vision_frame.copy() temp_vision_mask = extract_vision_mask(temp_vision_frame) source_audio_frame = get_audio_frame(source_audio_path, temp_video_fps, frame_number - trim_frame_start)