2x FPS
parent
71c33437fc
commit
0187936c18
|
@ -58,6 +58,20 @@ def get_face_swapper() -> Any:
|
||||||
FACE_SWAPPER = insightface.model_zoo.get_model(
|
FACE_SWAPPER = insightface.model_zoo.get_model(
|
||||||
model_path, providers=modules.globals.execution_providers
|
model_path, providers=modules.globals.execution_providers
|
||||||
)
|
)
|
||||||
|
# Set optimal inference parameters
|
||||||
|
if hasattr(FACE_SWAPPER, "session"):
|
||||||
|
FACE_SWAPPER.session.set_providers(["CUDAExecutionProvider"])
|
||||||
|
FACE_SWAPPER.session.set_provider_options(
|
||||||
|
{
|
||||||
|
"CUDAExecutionProvider": {
|
||||||
|
"cuda_mem_limit": 2 * 1024 * 1024 * 1024, # 2GB VRAM limit
|
||||||
|
"arena_extend_strategy": "kNextPowerOfTwo",
|
||||||
|
"gpu_mem_limit": 2 * 1024 * 1024 * 1024,
|
||||||
|
"cudnn_conv_algo_search": "EXHAUSTIVE",
|
||||||
|
"do_copy_in_default_stream": True,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
return FACE_SWAPPER
|
return FACE_SWAPPER
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +107,15 @@ def swap_face(source_face: Face, target_face: Face, temp_frame: Frame) -> Frame:
|
||||||
|
|
||||||
|
|
||||||
def process_frame(source_face: Face, temp_frame: Frame) -> Frame:
|
def process_frame(source_face: Face, temp_frame: Frame) -> Frame:
|
||||||
|
# Add caching for repeated faces
|
||||||
|
cache_key = hash(str(source_face))
|
||||||
|
if hasattr(process_frame, "_cache") and cache_key in process_frame._cache:
|
||||||
|
source_face = process_frame._cache[cache_key]
|
||||||
|
else:
|
||||||
|
if not hasattr(process_frame, "_cache"):
|
||||||
|
process_frame._cache = {}
|
||||||
|
process_frame._cache[cache_key] = source_face
|
||||||
|
|
||||||
if modules.globals.color_correction:
|
if modules.globals.color_correction:
|
||||||
temp_frame = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB)
|
temp_frame = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB)
|
||||||
|
|
||||||
|
|
156
modules/ui.py
156
modules/ui.py
|
@ -96,7 +96,7 @@ def save_switch_states():
|
||||||
"fp_ui": modules.globals.fp_ui,
|
"fp_ui": modules.globals.fp_ui,
|
||||||
"show_fps": modules.globals.show_fps,
|
"show_fps": modules.globals.show_fps,
|
||||||
"mouth_mask": modules.globals.mouth_mask,
|
"mouth_mask": modules.globals.mouth_mask,
|
||||||
"show_mouth_mask_box": modules.globals.show_mouth_mask_box
|
"show_mouth_mask_box": modules.globals.show_mouth_mask_box,
|
||||||
}
|
}
|
||||||
with open("switch_states.json", "w") as f:
|
with open("switch_states.json", "w") as f:
|
||||||
json.dump(switch_states, f)
|
json.dump(switch_states, f)
|
||||||
|
@ -118,7 +118,9 @@ def load_switch_states():
|
||||||
modules.globals.fp_ui = switch_states.get("fp_ui", {"face_enhancer": False})
|
modules.globals.fp_ui = switch_states.get("fp_ui", {"face_enhancer": False})
|
||||||
modules.globals.show_fps = switch_states.get("show_fps", False)
|
modules.globals.show_fps = switch_states.get("show_fps", False)
|
||||||
modules.globals.mouth_mask = switch_states.get("mouth_mask", False)
|
modules.globals.mouth_mask = switch_states.get("mouth_mask", False)
|
||||||
modules.globals.show_mouth_mask_box = switch_states.get("show_mouth_mask_box", False)
|
modules.globals.show_mouth_mask_box = switch_states.get(
|
||||||
|
"show_mouth_mask_box", False
|
||||||
|
)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
# If the file doesn't exist, use default values
|
# If the file doesn't exist, use default values
|
||||||
pass
|
pass
|
||||||
|
@ -772,69 +774,118 @@ def get_available_cameras():
|
||||||
def create_webcam_preview(camera_index: int):
|
def create_webcam_preview(camera_index: int):
|
||||||
global preview_label, PREVIEW
|
global preview_label, PREVIEW
|
||||||
|
|
||||||
|
# Initialize camera with optimized settings
|
||||||
camera = cv2.VideoCapture(camera_index)
|
camera = cv2.VideoCapture(camera_index)
|
||||||
camera.set(cv2.CAP_PROP_FRAME_WIDTH, PREVIEW_DEFAULT_WIDTH)
|
camera.set(cv2.CAP_PROP_FRAME_WIDTH, PREVIEW_DEFAULT_WIDTH)
|
||||||
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, PREVIEW_DEFAULT_HEIGHT)
|
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, PREVIEW_DEFAULT_HEIGHT)
|
||||||
camera.set(cv2.CAP_PROP_FPS, 60)
|
camera.set(cv2.CAP_PROP_FPS, 60)
|
||||||
|
camera.set(cv2.CAP_PROP_BUFFERSIZE, 2) # Slightly larger buffer for smoother frames
|
||||||
|
|
||||||
preview_label.configure(width=PREVIEW_DEFAULT_WIDTH, height=PREVIEW_DEFAULT_HEIGHT)
|
preview_label.configure(width=PREVIEW_DEFAULT_WIDTH, height=PREVIEW_DEFAULT_HEIGHT)
|
||||||
|
|
||||||
PREVIEW.deiconify()
|
PREVIEW.deiconify()
|
||||||
|
|
||||||
frame_processors = get_frame_processors_modules(modules.globals.frame_processors)
|
frame_processors = get_frame_processors_modules(modules.globals.frame_processors)
|
||||||
|
|
||||||
source_image = None
|
# Pre-load source face
|
||||||
|
source_face = (
|
||||||
|
None
|
||||||
|
if modules.globals.map_faces
|
||||||
|
else get_one_face(cv2.imread(modules.globals.source_path))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Performance tracking
|
||||||
prev_time = time.time()
|
prev_time = time.time()
|
||||||
fps_update_interval = 0.5 # Update FPS every 0.5 seconds
|
fps_update_interval = 0.5
|
||||||
frame_count = 0
|
frame_count = 0
|
||||||
fps = 0
|
fps = 0
|
||||||
|
|
||||||
while camera:
|
# Processing settings - adjusted for better quality
|
||||||
|
process_scale = 0.75 # Increased base scale for better quality
|
||||||
|
min_scale = 0.5 # Minimum allowed scale
|
||||||
|
max_scale = 1.0 # Maximum allowed scale
|
||||||
|
skip_frames = 0 # Counter for frame skipping
|
||||||
|
max_skip = 1 # Reduced max skip for smoother video
|
||||||
|
target_fps = 24.0 # Slightly reduced target FPS for better quality
|
||||||
|
min_process_time = 1.0 / target_fps
|
||||||
|
scale_adjust_rate = 0.02 # More gradual scale adjustments
|
||||||
|
|
||||||
|
while camera.isOpened() and PREVIEW.state() != "withdrawn":
|
||||||
ret, frame = camera.read()
|
ret, frame = camera.read()
|
||||||
if not ret:
|
if not ret:
|
||||||
break
|
break
|
||||||
|
|
||||||
temp_frame = frame.copy()
|
|
||||||
|
|
||||||
if modules.globals.live_mirror:
|
|
||||||
temp_frame = cv2.flip(temp_frame, 1)
|
|
||||||
|
|
||||||
if modules.globals.live_resizable:
|
|
||||||
temp_frame = fit_image_to_size(
|
|
||||||
temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height()
|
|
||||||
)
|
|
||||||
|
|
||||||
if not modules.globals.map_faces:
|
|
||||||
if source_image is None and modules.globals.source_path:
|
|
||||||
source_image = get_one_face(cv2.imread(modules.globals.source_path))
|
|
||||||
|
|
||||||
for frame_processor in frame_processors:
|
|
||||||
if frame_processor.NAME == "DLC.FACE-ENHANCER":
|
|
||||||
if modules.globals.fp_ui["face_enhancer"]:
|
|
||||||
temp_frame = frame_processor.process_frame(None, temp_frame)
|
|
||||||
else:
|
|
||||||
temp_frame = frame_processor.process_frame(source_image, temp_frame)
|
|
||||||
else:
|
|
||||||
modules.globals.target_path = None
|
|
||||||
|
|
||||||
for frame_processor in frame_processors:
|
|
||||||
if frame_processor.NAME == "DLC.FACE-ENHANCER":
|
|
||||||
if modules.globals.fp_ui["face_enhancer"]:
|
|
||||||
temp_frame = frame_processor.process_frame_v2(temp_frame)
|
|
||||||
else:
|
|
||||||
temp_frame = frame_processor.process_frame_v2(temp_frame)
|
|
||||||
|
|
||||||
# Calculate and display FPS
|
|
||||||
current_time = time.time()
|
|
||||||
frame_count += 1
|
frame_count += 1
|
||||||
if current_time - prev_time >= fps_update_interval:
|
current_time = time.time()
|
||||||
fps = frame_count / (current_time - prev_time)
|
elapsed_time = current_time - prev_time
|
||||||
|
|
||||||
|
# Skip frames if processing is too slow
|
||||||
|
if skip_frames > 0:
|
||||||
|
skip_frames -= 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create processing copy
|
||||||
|
if modules.globals.live_mirror:
|
||||||
|
frame = cv2.flip(frame, 1)
|
||||||
|
|
||||||
|
# Scale down for processing with better interpolation
|
||||||
|
if process_scale != 1.0:
|
||||||
|
proc_frame = cv2.resize(
|
||||||
|
frame,
|
||||||
|
None,
|
||||||
|
fx=process_scale,
|
||||||
|
fy=process_scale,
|
||||||
|
interpolation=cv2.INTER_AREA,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
proc_frame = frame.copy()
|
||||||
|
|
||||||
|
# Process frame
|
||||||
|
try:
|
||||||
|
if not modules.globals.map_faces:
|
||||||
|
for processor in frame_processors:
|
||||||
|
if processor.NAME == "DLC.FACE-ENHANCER":
|
||||||
|
if modules.globals.fp_ui["face_enhancer"]:
|
||||||
|
proc_frame = processor.process_frame(None, proc_frame)
|
||||||
|
else:
|
||||||
|
proc_frame = processor.process_frame(source_face, proc_frame)
|
||||||
|
else:
|
||||||
|
for processor in frame_processors:
|
||||||
|
if processor.NAME == "DLC.FACE-ENHANCER":
|
||||||
|
if modules.globals.fp_ui["face_enhancer"]:
|
||||||
|
proc_frame = processor.process_frame_v2(proc_frame)
|
||||||
|
else:
|
||||||
|
proc_frame = processor.process_frame_v2(proc_frame)
|
||||||
|
|
||||||
|
# Scale back up if needed, using better interpolation
|
||||||
|
if process_scale != 1.0:
|
||||||
|
proc_frame = cv2.resize(
|
||||||
|
proc_frame,
|
||||||
|
(frame.shape[1], frame.shape[0]),
|
||||||
|
interpolation=cv2.INTER_LANCZOS4,
|
||||||
|
)
|
||||||
|
|
||||||
|
# More gradual performance-based scaling adjustments
|
||||||
|
process_time = time.time() - current_time
|
||||||
|
if process_time > min_process_time * 1.2: # Allow more tolerance
|
||||||
|
process_scale = max(min_scale, process_scale - scale_adjust_rate)
|
||||||
|
skip_frames = min(max_skip, skip_frames + 1)
|
||||||
|
elif process_time < min_process_time * 0.8:
|
||||||
|
process_scale = min(max_scale, process_scale + scale_adjust_rate)
|
||||||
|
skip_frames = max(0, skip_frames - 1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Frame processing error: {str(e)}")
|
||||||
|
proc_frame = frame
|
||||||
|
|
||||||
|
# Calculate and show FPS
|
||||||
|
if elapsed_time >= fps_update_interval:
|
||||||
|
fps = frame_count / elapsed_time
|
||||||
frame_count = 0
|
frame_count = 0
|
||||||
prev_time = current_time
|
prev_time = current_time
|
||||||
|
|
||||||
if modules.globals.show_fps:
|
if modules.globals.show_fps:
|
||||||
cv2.putText(
|
cv2.putText(
|
||||||
temp_frame,
|
proc_frame,
|
||||||
f"FPS: {fps:.1f}",
|
f"FPS: {fps:.1f}",
|
||||||
(10, 30),
|
(10, 30),
|
||||||
cv2.FONT_HERSHEY_SIMPLEX,
|
cv2.FONT_HERSHEY_SIMPLEX,
|
||||||
|
@ -843,18 +894,23 @@ def create_webcam_preview(camera_index: int):
|
||||||
2,
|
2,
|
||||||
)
|
)
|
||||||
|
|
||||||
image = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB)
|
# Update preview with better quality settings
|
||||||
image = Image.fromarray(image)
|
if modules.globals.live_resizable:
|
||||||
image = ImageOps.contain(
|
proc_frame = fit_image_to_size(
|
||||||
image, (temp_frame.shape[1], temp_frame.shape[0]), Image.LANCZOS
|
proc_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height()
|
||||||
)
|
)
|
||||||
image = ctk.CTkImage(image, size=image.size)
|
|
||||||
|
# Improve color handling
|
||||||
|
if modules.globals.color_correction:
|
||||||
|
proc_frame = cv2.cvtColor(proc_frame, cv2.COLOR_BGR2RGB)
|
||||||
|
else:
|
||||||
|
proc_frame = cv2.cvtColor(proc_frame, cv2.COLOR_BGR2RGB)
|
||||||
|
|
||||||
|
image = Image.fromarray(proc_frame)
|
||||||
|
image = ctk.CTkImage(image, size=(proc_frame.shape[1], proc_frame.shape[0]))
|
||||||
preview_label.configure(image=image)
|
preview_label.configure(image=image)
|
||||||
ROOT.update()
|
ROOT.update()
|
||||||
|
|
||||||
if PREVIEW.state() == "withdrawn":
|
|
||||||
break
|
|
||||||
|
|
||||||
camera.release()
|
camera.release()
|
||||||
PREVIEW.withdraw()
|
PREVIEW.withdraw()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue