Compare commits

...
2 Commits
Author SHA1 Message Date
189d750621 3.4.2 (#975)
* Reduce caching to avoid RAM explosion

* Reduce caching to avoid RAM explosion

* Reduce caching to avoid RAM explosion

* fix bounding_box scale

* Bump to 3.4.2

* More conservative on audio caching

* Fix coverage issue

* Fix coverage issue

---------

Co-authored-by: harisreedhar <h4harisreedhar.s.s@gmail.com>
2025-10-29 11:51:42 +01:00
Henry RuhsandGitHub f3be23d19b Patch (#947)
* Fix preview when using frame enhancer

* Fix version conflict numpy vs. cv2

* Use latest numpy

* Introduce scale_face() to match size of temp frames and target frames

* Remove hardcoded backend for camera under Windows

* Up and downgrade some dependencies

* Up and downgrade some dependencies

* Up and downgrade some dependencies
2025-09-11 16:58:39 +02:00
18 changed files with 50 additions and 16 deletions
+2
View File
@@ -0,0 +1,2 @@
[run]
patch = subprocess
+2 -2
View File
@@ -11,7 +11,7 @@ from facefusion.types import Audio, AudioFrame, Fps, Mel, MelFilterBank, Spectro
from facefusion.voice_extractor import batch_extract_voice
@lru_cache()
@lru_cache(maxsize = 64)
def read_static_audio(audio_path : str, fps : Fps) -> Optional[List[AudioFrame]]:
return read_audio(audio_path, fps)
@@ -31,7 +31,7 @@ def read_audio(audio_path : str, fps : Fps) -> Optional[List[AudioFrame]]:
return None
@lru_cache()
@lru_cache(maxsize = 64)
def read_static_voice(audio_path : str, fps : Fps) -> Optional[List[AudioFrame]]:
return read_voice(audio_path, fps)
+1 -5
View File
@@ -2,7 +2,6 @@ from typing import List
import cv2
from facefusion.common_helper import is_windows
from facefusion.types import CameraPoolSet
CAMERA_POOL_SET : CameraPoolSet =\
@@ -15,10 +14,7 @@ def get_local_camera_capture(camera_id : int) -> cv2.VideoCapture:
camera_key = str(camera_id)
if camera_key not in CAMERA_POOL_SET.get('capture'):
if is_windows():
camera_capture = cv2.VideoCapture(camera_id, cv2.CAP_DSHOW)
else:
camera_capture = cv2.VideoCapture(camera_id)
camera_capture = cv2.VideoCapture(camera_id)
if camera_capture.isOpened():
CAMERA_POOL_SET['capture'][camera_key] = camera_capture
+2 -2
View File
@@ -41,7 +41,7 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
progress.update(current_size - progress.n)
@lru_cache(maxsize = 1024)
@lru_cache(maxsize = 64)
def get_static_download_size(url : str) -> int:
commands = curl_builder.chain(
curl_builder.head(url),
@@ -59,7 +59,7 @@ def get_static_download_size(url : str) -> int:
return 0
@lru_cache(maxsize = 1024)
@lru_cache(maxsize = 64)
def ping_static_url(url : str) -> bool:
commands = curl_builder.chain(
curl_builder.head(url),
+19
View File
@@ -122,3 +122,22 @@ def get_many_faces(vision_frames : List[VisionFrame]) -> List[Face]:
many_faces.extend(faces)
set_static_faces(vision_frame, faces)
return many_faces
def scale_face(target_face : Face, target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame) -> Face:
scale_x = temp_vision_frame.shape[1] / target_vision_frame.shape[1]
scale_y = temp_vision_frame.shape[0] / target_vision_frame.shape[0]
bounding_box = target_face.bounding_box * [ scale_x, scale_y, scale_x, scale_y ]
landmark_set =\
{
'5': target_face.landmark_set.get('5') * numpy.array([ scale_x, scale_y ]),
'5/68': target_face.landmark_set.get('5/68') * numpy.array([ scale_x, scale_y ]),
'68': target_face.landmark_set.get('68') * numpy.array([ scale_x, scale_y ]),
'68/5': target_face.landmark_set.get('68/5') * numpy.array([ scale_x, scale_y ])
}
return target_face._replace(
bounding_box = bounding_box,
landmark_set = landmark_set
)
+1 -1
View File
@@ -12,7 +12,7 @@ from facefusion.common_helper import is_linux, is_windows
ONNXRUNTIME_SET =\
{
'default': ('onnxruntime', '1.22.0')
'default': ('onnxruntime', '1.22.1')
}
if is_windows() or is_linux():
ONNXRUNTIME_SET['cuda'] = ('onnxruntime-gpu', '1.22.0')
+1 -1
View File
@@ -4,7 +4,7 @@ METADATA =\
{
'name': 'FaceFusion',
'description': 'Industry leading face manipulation platform',
'version': '3.4.0',
'version': '3.4.2',
'license': 'OpenRAIL-AS',
'author': 'Henry Ruhs',
'url': 'https://facefusion.io'
@@ -11,6 +11,7 @@ from facefusion import config, content_analyser, face_classifier, face_detector,
from facefusion.common_helper import create_int_metavar, is_macos
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
from facefusion.execution import has_execution_provider
from facefusion.face_analyser import scale_face
from facefusion.face_helper import merge_matrix, paste_back, scale_face_landmark_5, warp_face_by_face_landmark_5
from facefusion.face_masker import create_box_mask, create_occlusion_mask
from facefusion.face_selector import select_faces
@@ -204,6 +205,7 @@ def process_frame(inputs : AgeModifierInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = modify_age(target_face, temp_vision_frame)
return temp_vision_frame
@@ -11,6 +11,7 @@ import facefusion.jobs.job_store
from facefusion import config, content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, inference_manager, logger, state_manager, video_manager, wording
from facefusion.common_helper import create_int_metavar
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url_by_provider
from facefusion.face_analyser import scale_face
from facefusion.face_helper import paste_back, warp_face_by_face_landmark_5
from facefusion.face_masker import create_area_mask, create_box_mask, create_occlusion_mask, create_region_mask
from facefusion.face_selector import select_faces
@@ -415,6 +416,7 @@ def process_frame(inputs : DeepSwapperInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = swap_face(target_face, temp_vision_frame)
return temp_vision_frame
@@ -10,6 +10,7 @@ import facefusion.jobs.job_store
from facefusion import config, content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, inference_manager, logger, state_manager, video_manager, wording
from facefusion.common_helper import create_int_metavar
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
from facefusion.face_analyser import scale_face
from facefusion.face_helper import paste_back, warp_face_by_face_landmark_5
from facefusion.face_masker import create_box_mask, create_occlusion_mask
from facefusion.face_selector import select_faces
@@ -255,6 +256,7 @@ def process_frame(inputs : ExpressionRestorerInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = restore_expression(target_face, target_vision_frame, temp_vision_frame)
return temp_vision_frame
@@ -6,6 +6,7 @@ import numpy
import facefusion.jobs.job_manager
import facefusion.jobs.job_store
from facefusion import config, content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, logger, state_manager, video_manager, wording
from facefusion.face_analyser import scale_face
from facefusion.face_helper import warp_face_by_face_landmark_5
from facefusion.face_masker import create_area_mask, create_box_mask, create_occlusion_mask, create_region_mask
from facefusion.face_selector import select_faces
@@ -218,6 +219,7 @@ def process_frame(inputs : FaceDebuggerInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = debug_face(target_face, temp_vision_frame)
return temp_vision_frame
@@ -10,6 +10,7 @@ import facefusion.jobs.job_store
from facefusion import config, content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, inference_manager, logger, state_manager, video_manager, wording
from facefusion.common_helper import create_float_metavar
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
from facefusion.face_analyser import scale_face
from facefusion.face_helper import paste_back, scale_face_landmark_5, warp_face_by_face_landmark_5
from facefusion.face_masker import create_box_mask
from facefusion.face_selector import select_faces
@@ -484,6 +485,7 @@ def process_frame(inputs : FaceEditorInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = edit_face(target_face, temp_vision_frame)
return temp_vision_frame
@@ -8,6 +8,7 @@ import facefusion.jobs.job_store
from facefusion import config, content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, inference_manager, logger, state_manager, video_manager, wording
from facefusion.common_helper import create_float_metavar, create_int_metavar
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
from facefusion.face_analyser import scale_face
from facefusion.face_helper import paste_back, warp_face_by_face_landmark_5
from facefusion.face_masker import create_box_mask, create_occlusion_mask
from facefusion.face_selector import select_faces
@@ -363,6 +364,7 @@ def process_frame(inputs : FaceEnhancerInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = enhance_face(target_face, temp_vision_frame)
return temp_vision_frame
@@ -12,7 +12,7 @@ from facefusion import config, content_analyser, face_classifier, face_detector,
from facefusion.common_helper import get_first, is_macos
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
from facefusion.execution import has_execution_provider
from facefusion.face_analyser import get_average_face, get_many_faces, get_one_face
from facefusion.face_analyser import get_average_face, get_many_faces, get_one_face, scale_face
from facefusion.face_helper import paste_back, warp_face_by_face_landmark_5
from facefusion.face_masker import create_area_mask, create_box_mask, create_occlusion_mask, create_region_mask
from facefusion.face_selector import select_faces, sort_faces_by_order
@@ -688,6 +688,7 @@ def process_frame(inputs : FaceSwapperInputs) -> VisionFrame:
if source_face and target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = swap_face(source_face, target_face, temp_vision_frame)
return temp_vision_frame
@@ -10,6 +10,7 @@ from facefusion import config, content_analyser, face_classifier, face_detector,
from facefusion.audio import read_static_voice
from facefusion.common_helper import create_float_metavar
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
from facefusion.face_analyser import scale_face
from facefusion.face_helper import create_bounding_box, paste_back, warp_face_by_bounding_box, warp_face_by_face_landmark_5
from facefusion.face_masker import create_area_mask, create_box_mask, create_occlusion_mask
from facefusion.face_selector import select_faces
@@ -269,6 +270,7 @@ def process_frame(inputs : LipSyncerInputs) -> VisionFrame:
if target_faces:
for target_face in target_faces:
target_face = scale_face(target_face, target_vision_frame, temp_vision_frame)
temp_vision_frame = sync_lip(target_face, source_voice_frame, temp_vision_frame)
return temp_vision_frame
+2
View File
@@ -241,6 +241,8 @@ def process_preview_frame(reference_vision_frame : VisionFrame, source_vision_fr
})
logger.enable()
temp_vision_frame = cv2.resize(temp_vision_frame, target_vision_frame.shape[1::-1])
if preview_mode == 'frame-by-frame':
return numpy.hstack((target_vision_frame, temp_vision_frame))
+2 -2
View File
@@ -22,7 +22,7 @@ def read_static_images(image_paths : List[str]) -> List[VisionFrame]:
return vision_frames
@lru_cache(maxsize = 1024)
@lru_cache(maxsize = 64)
def read_static_image(image_path : str) -> Optional[VisionFrame]:
return read_image(image_path)
@@ -65,7 +65,7 @@ def restrict_image_resolution(image_path : str, resolution : Resolution) -> Reso
return resolution
@lru_cache(maxsize = 1024)
@lru_cache(maxsize = 64)
def read_static_video_frame(video_path : str, frame_number : int = 0) -> Optional[VisionFrame]:
return read_video_frame(video_path, frame_number)
+2 -2
View File
@@ -1,8 +1,8 @@
gradio-rangeslider==0.0.8
gradio==5.42.0
numpy==2.3.2
onnx==1.18.0
onnxruntime==1.22.0
onnx==1.19.0
onnxruntime==1.22.1
opencv-python==4.12.0.88
psutil==7.0.0
tqdm==4.67.1