mirror of
https://github.com/facefusion/facefusion.git
synced 2026-07-31 06:17:27 +02:00
Next (#945)
* Rename calcXXX to calculateXXX * Add migraphx support * Add migraphx support * Add migraphx support * Add migraphx support * Add migraphx support * Add migraphx support * Use True for the flags * Add migraphx support * add face-swapper-weight * add face-swapper-weight to facefusion.ini * changes * change choice * Fix typing for xxxWeight * Feat/log inference session (#906) * Log inference session, Introduce time helper * Log inference session, Introduce time helper * Log inference session, Introduce time helper * Log inference session, Introduce time helper * Mark as NEXT * Follow industry standard x1, x2, y1 and y2 * Follow industry standard x1, x2, y1 and y2 * Follow industry standard in terms of naming (#908) * Follow industry standard in terms of naming * Improve xxx_embedding naming * Fix norm vs. norms * Reduce timeout to 5 * Sort out voice_extractor once again * changes * Introduce many to the occlusion mask (#910) * Introduce many to the occlusion mask * Then we use minimum * Add support for wmv * Run platform tests before has_execution_provider (#911) * Add support for wmv * Introduce benchmark mode (#912) * Honestly makes no difference to me * Honestly makes no difference to me * Fix wording * Bring back YuNet (#922) * Reintroduce YuNet without cv2 dependency * Fix variable naming * Avoid RGB to YUV colorshift using libx264rgb * Avoid RGB to YUV colorshift using libx264rgb * Make libx264 the default again * Make libx264 the default again * Fix types in ffmpeg builder * Fix quality stuff in ffmpeg builder * Fix quality stuff in ffmpeg builder * Add libx264rgb to test * Revamp Processors (#923) * Introduce new concept of pure target frames * Radical refactoring of process flow * Introduce new concept of pure target frames * Fix webcam * Minor improvements * Minor improvements * Use deque for video processing * Use deque for video processing * Extend the video manager * Polish deque * Polish deque * Deque is not even used * Improve speed with multiple futures * Fix temp frame mutation and * Fix RAM usage * Remove old types and manage method * Remove execution_queue_count * Use init_state for benchmarker to avoid issues * add voice extractor option * Change the order of voice extractor in code * Use official download urls * Use official download urls * add gui * fix preview * Add remote updates for voice extractor * fix crash on headless-run * update test_job_helper.py * Fix it for good * Remove pointless method * Fix types and unused imports * Revamp reference (#925) * Initial revamp of face references * Initial revamp of face references * Initial revamp of face references * Terminate find_similar_faces * Improve find mutant faces * Improve find mutant faces * Move sort where it belongs * Forward reference vision frame * Forward reference vision frame also in preview * Fix reference selection * Use static video frame * Fix CI * Remove reference type from frame processors * Improve some naming * Fix types and unused imports * Fix find mutant faces * Fix find mutant faces * Fix imports * Correct naming * Correct naming * simplify pad * Improve webcam performance on highres * Camera manager (#932) * Introduce webcam manager * Fix order * Rename to camera manager, improve video manager * Fix CI * Remove optional * Fix naming in webcam options * Avoid using temp faces (#933) * output video scale * Fix imports * output image scale * upscale fix (not limiter) * add unit test scale_resolution & remove unused methods * fix and add test * fix * change pack_resolution * fix tests * Simplify output scale testing * Fix benchmark UI * Fix benchmark UI * Update dependencies * Introduce REAL multi gpu support using multi dimensional inference pool (#935) * Introduce REAL multi gpu support using multi dimensional inference pool * Remove the MULTI:GPU flag * Restore "processing stop" * Restore "processing stop" * Remove old templates * Go fill in with caching * add expression restorer areas * re-arrange * rename method * Fix stop for extract frames and merge video * Replace arcface_converter models with latest crossface models * Replace arcface_converter models with latest crossface models * Move module logs to debug mode * Refactor/streamer (#938) * Introduce webcam manager * Fix order * Rename to camera manager, improve video manager * Fix CI * Fix naming in webcam options * Move logic over to streamer * Fix streamer, improve webcam experience * Improve webcam experience * Revert method * Revert method * Improve webcam again * Use release on capture instead * Only forward valid frames * Fix resolution logging * Add AVIF support * Add AVIF support * Limit avif to unix systems * Drop avif * Drop avif * Drop avif * Default to Documents in the UI if output path is not set * Update wording.py (#939) "succeed" is grammatically incorrect in the given context. To succeed is the infinitive form of the verb. Correct would be either "succeeded" or alternatively a form involving the noun "success". * Fix more grammar issue * Fix more grammar issue * Sort out caching * Move webcam choices back to UI * Move preview options to own file (#940) * Fix Migraphx execution provider * Fix benchmark * Reuse blend frame method * Fix CI * Fix CI * Fix CI * Hotfix missing check in face debugger, Enable logger for preview * Fix reference selection (#942) * Fix reference selection * Fix reference selection * Fix reference selection * Fix reference selection * Side by side preview (#941) * Initial side by side preview * More work on preview, remove UI only stuff from vision.py * Improve more * Use fit frame * Add different fit methods for vision * Improve preview part2 * Improve preview part3 * Improve preview part4 * Remove none as choice * Remove useless methods * Fix CI * Fix naming * use 1024 as preview resolution default * Fix fit_cover_frame * Uniform fit_xxx_frame methods * Add back disabled logger * Use ui choices alias * Extract select face logic from processors (#943) * Extract select face logic from processors to use it for face by face in preview * Fix order * Remove old code * Merge methods * Refactor face debugger (#944) * Refactor huge method of face debugger * Remove text metrics from face debugger * Remove useless copy of temp frame * Resort methods * Fix spacing * Remove old method * Fix hard exit to work without signals * Prevent upscaling for face-by-face * Switch to version * Improve exiting --------- Co-authored-by: harisreedhar <h4harisreedhar.s.s@gmail.com> Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com> Co-authored-by: Rafael Tappe Maestro <rafael@tappemaestro.com>
This commit is contained in:
co-authored by
harisreedhar
Harisreedhar
Rafael Tappe Maestro
parent
7b8bea4e0a
commit
da0da3a4b4
+54
-55
@@ -6,26 +6,25 @@ import cv2
|
||||
import numpy
|
||||
from cv2.typing import Size
|
||||
|
||||
import facefusion.choices
|
||||
from facefusion.common_helper import is_windows
|
||||
from facefusion.filesystem import get_file_extension, is_image, is_video
|
||||
from facefusion.thread_helper import thread_semaphore
|
||||
from facefusion.types import Duration, Fps, Orientation, Resolution, VisionFrame
|
||||
from facefusion.types import Duration, Fps, Orientation, Resolution, Scale, VisionFrame
|
||||
from facefusion.video_manager import get_video_capture
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def read_static_image(image_path : str) -> Optional[VisionFrame]:
|
||||
return read_image(image_path)
|
||||
|
||||
|
||||
def read_static_images(image_paths : List[str]) -> List[VisionFrame]:
|
||||
frames = []
|
||||
vision_frames = []
|
||||
|
||||
if image_paths:
|
||||
for image_path in image_paths:
|
||||
frames.append(read_static_image(image_path))
|
||||
return frames
|
||||
vision_frames.append(read_static_image(image_path))
|
||||
return vision_frames
|
||||
|
||||
|
||||
@lru_cache(maxsize = 1024)
|
||||
def read_static_image(image_path : str) -> Optional[VisionFrame]:
|
||||
return read_image(image_path)
|
||||
|
||||
|
||||
def read_image(image_path : str) -> Optional[VisionFrame]:
|
||||
@@ -66,19 +65,9 @@ def restrict_image_resolution(image_path : str, resolution : Resolution) -> Reso
|
||||
return resolution
|
||||
|
||||
|
||||
def create_image_resolutions(resolution : Resolution) -> List[str]:
|
||||
resolutions = []
|
||||
temp_resolutions = []
|
||||
|
||||
if resolution:
|
||||
width, height = resolution
|
||||
temp_resolutions.append(normalize_resolution(resolution))
|
||||
for image_template_size in facefusion.choices.image_template_sizes:
|
||||
temp_resolutions.append(normalize_resolution((width * image_template_size, height * image_template_size)))
|
||||
temp_resolutions = sorted(set(temp_resolutions))
|
||||
for temp_resolution in temp_resolutions:
|
||||
resolutions.append(pack_resolution(temp_resolution))
|
||||
return resolutions
|
||||
@lru_cache(maxsize = 1024)
|
||||
def read_static_video_frame(video_path : str, frame_number : int = 0) -> Optional[VisionFrame]:
|
||||
return read_video_frame(video_path, frame_number)
|
||||
|
||||
|
||||
def read_video_frame(video_path : str, frame_number : int = 0) -> Optional[VisionFrame]:
|
||||
@@ -192,22 +181,10 @@ def restrict_video_resolution(video_path : str, resolution : Resolution) -> Reso
|
||||
return resolution
|
||||
|
||||
|
||||
def create_video_resolutions(resolution : Resolution) -> List[str]:
|
||||
resolutions = []
|
||||
temp_resolutions = []
|
||||
|
||||
if resolution:
|
||||
width, height = resolution
|
||||
temp_resolutions.append(normalize_resolution(resolution))
|
||||
for video_template_size in facefusion.choices.video_template_sizes:
|
||||
if width > height:
|
||||
temp_resolutions.append(normalize_resolution((video_template_size * width / height, video_template_size)))
|
||||
else:
|
||||
temp_resolutions.append(normalize_resolution((video_template_size, video_template_size * height / width)))
|
||||
temp_resolutions = sorted(set(temp_resolutions))
|
||||
for temp_resolution in temp_resolutions:
|
||||
resolutions.append(pack_resolution(temp_resolution))
|
||||
return resolutions
|
||||
def scale_resolution(resolution : Resolution, scale : Scale) -> Resolution:
|
||||
resolution = (int(resolution[0] * scale), int(resolution[1] * scale))
|
||||
resolution = normalize_resolution(resolution)
|
||||
return resolution
|
||||
|
||||
|
||||
def normalize_resolution(resolution : Tuple[float, float]) -> Resolution:
|
||||
@@ -250,26 +227,48 @@ def restrict_frame(vision_frame : VisionFrame, resolution : Resolution) -> Visio
|
||||
return vision_frame
|
||||
|
||||
|
||||
def fit_frame(vision_frame : VisionFrame, resolution: Resolution) -> VisionFrame:
|
||||
fit_width, fit_height = resolution
|
||||
def fit_contain_frame(vision_frame : VisionFrame, resolution : Resolution) -> VisionFrame:
|
||||
contain_width, contain_height = resolution
|
||||
height, width = vision_frame.shape[:2]
|
||||
scale = min(fit_height / height, fit_width / width)
|
||||
scale = min(contain_height / height, contain_width / width)
|
||||
new_width = int(width * scale)
|
||||
new_height = int(height * scale)
|
||||
paste_vision_frame = cv2.resize(vision_frame, (new_width, new_height))
|
||||
x_pad = (fit_width - new_width) // 2
|
||||
y_pad = (fit_height - new_height) // 2
|
||||
temp_vision_frame = numpy.pad(paste_vision_frame, ((y_pad, fit_height - new_height - y_pad), (x_pad, fit_width - new_width - x_pad), (0, 0)))
|
||||
start_x = max(0, (contain_width - new_width) // 2)
|
||||
start_y = max(0, (contain_height - new_height) // 2)
|
||||
end_x = max(0, contain_width - new_width - start_x)
|
||||
end_y = max(0, contain_height - new_height - start_y)
|
||||
temp_vision_frame = cv2.resize(vision_frame, (new_width, new_height))
|
||||
temp_vision_frame = numpy.pad(temp_vision_frame, ((start_y, end_y), (start_x, end_x), (0, 0)))
|
||||
return temp_vision_frame
|
||||
|
||||
|
||||
def normalize_frame_color(vision_frame : VisionFrame) -> VisionFrame:
|
||||
return cv2.cvtColor(vision_frame, cv2.COLOR_BGR2RGB)
|
||||
def fit_cover_frame(vision_frame : VisionFrame, resolution : Resolution) -> VisionFrame:
|
||||
cover_width, cover_height = resolution
|
||||
height, width = vision_frame.shape[:2]
|
||||
scale = max(cover_width / width, cover_height / height)
|
||||
new_width = int(width * scale)
|
||||
new_height = int(height * scale)
|
||||
start_x = max(0, (new_width - cover_width) // 2)
|
||||
start_y = max(0, (new_height - cover_height) // 2)
|
||||
end_x = min(new_width, start_x + cover_width)
|
||||
end_y = min(new_height, start_y + cover_height)
|
||||
temp_vision_frame = cv2.resize(vision_frame, (new_width, new_height))
|
||||
temp_vision_frame = temp_vision_frame[start_y:end_y, start_x:end_x]
|
||||
return temp_vision_frame
|
||||
|
||||
|
||||
def obscure_frame(vision_frame : VisionFrame) -> VisionFrame:
|
||||
return cv2.GaussianBlur(vision_frame, (99, 99), 0)
|
||||
|
||||
|
||||
def blend_frame(source_vision_frame : VisionFrame, target_vision_frame : VisionFrame, blend_factor : float) -> VisionFrame:
|
||||
blend_vision_frame = cv2.addWeighted(source_vision_frame, 1 - blend_factor, target_vision_frame, blend_factor, 0)
|
||||
return blend_vision_frame
|
||||
|
||||
|
||||
def conditional_match_frame_color(source_vision_frame : VisionFrame, target_vision_frame : VisionFrame) -> VisionFrame:
|
||||
histogram_factor = calc_histogram_difference(source_vision_frame, target_vision_frame)
|
||||
target_vision_frame = blend_vision_frames(target_vision_frame, match_frame_color(source_vision_frame, target_vision_frame), histogram_factor)
|
||||
histogram_factor = calculate_histogram_difference(source_vision_frame, target_vision_frame)
|
||||
target_vision_frame = blend_frame(target_vision_frame, match_frame_color(source_vision_frame, target_vision_frame), histogram_factor)
|
||||
return target_vision_frame
|
||||
|
||||
|
||||
@@ -291,7 +290,7 @@ def equalize_frame_color(source_vision_frame : VisionFrame, target_vision_frame
|
||||
return target_vision_frame
|
||||
|
||||
|
||||
def calc_histogram_difference(source_vision_frame : VisionFrame, target_vision_frame : VisionFrame) -> float:
|
||||
def calculate_histogram_difference(source_vision_frame : VisionFrame, target_vision_frame : VisionFrame) -> float:
|
||||
histogram_source = cv2.calcHist([cv2.cvtColor(source_vision_frame, cv2.COLOR_BGR2HSV)], [ 0, 1 ], None, [ 50, 60 ], [ 0, 180, 0, 256 ])
|
||||
histogram_target = cv2.calcHist([cv2.cvtColor(target_vision_frame, cv2.COLOR_BGR2HSV)], [ 0, 1 ], None, [ 50, 60 ], [ 0, 180, 0, 256 ])
|
||||
histogram_difference = float(numpy.interp(cv2.compareHist(histogram_source, histogram_target, cv2.HISTCMP_CORREL), [ -1, 1 ], [ 0, 1 ]))
|
||||
@@ -304,11 +303,11 @@ def blend_vision_frames(source_vision_frame : VisionFrame, target_vision_frame :
|
||||
|
||||
|
||||
def create_tile_frames(vision_frame : VisionFrame, size : Size) -> Tuple[List[VisionFrame], int, int]:
|
||||
vision_frame = numpy.pad(vision_frame, ((size[1], size[1]), (size[1], size[1]), (0, 0)))
|
||||
tile_width = size[0] - 2 * size[2]
|
||||
pad_size_bottom = size[2] + tile_width - vision_frame.shape[0] % tile_width
|
||||
pad_size_right = size[2] + tile_width - vision_frame.shape[1] % tile_width
|
||||
pad_vision_frame = numpy.pad(vision_frame, ((size[2], pad_size_bottom), (size[2], pad_size_right), (0, 0)))
|
||||
pad_size_top = size[1] + size[2]
|
||||
pad_size_bottom = pad_size_top + tile_width - (vision_frame.shape[0] + 2 * size[1]) % tile_width
|
||||
pad_size_right = pad_size_top + tile_width - (vision_frame.shape[1] + 2 * size[1]) % tile_width
|
||||
pad_vision_frame = numpy.pad(vision_frame, ((pad_size_top, pad_size_bottom), (pad_size_top, pad_size_right), (0, 0)))
|
||||
pad_height, pad_width = pad_vision_frame.shape[:2]
|
||||
row_range = range(size[2], pad_height - size[2], tile_width)
|
||||
col_range = range(size[2], pad_width - size[2], tile_width)
|
||||
|
||||
Reference in New Issue
Block a user