Revert "Merge pull request #868 from kier007/main"

This reverts commit c03f697729fa8649f58381ae0fd5c217afb18634, reversing
changes made to d8a5cdbc190727bfebf20bb878667ae36931a636.
This commit is contained in:
Kenneth Estanislao 2025-01-06 14:14:21 +08:00
parent b518f4337d
commit b38831dfdf

View File

@ -7,7 +7,6 @@ from cv2_enumerate_cameras import enumerate_cameras # Add this import
from PIL import Image, ImageOps from PIL import Image, ImageOps
import time import time
import json import json
import modules.globals import modules.globals
import modules.metadata import modules.metadata
from modules.face_analyser import ( from modules.face_analyser import (
@ -26,6 +25,11 @@ from modules.utilities import (
resolve_relative_path, resolve_relative_path,
has_image_extension, has_image_extension,
) )
from modules.video_capture import VideoCapturer
import platform
if platform.system() == "Windows":
from pygrabber.dshow_graph import FilterGraph
ROOT = None ROOT = None
POPUP = None POPUP = None
@ -96,7 +100,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 +122,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
@ -315,18 +321,22 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
camera_label.place(relx=0.1, rely=0.86, relwidth=0.2, relheight=0.05) camera_label.place(relx=0.1, rely=0.86, relwidth=0.2, relheight=0.05)
available_cameras = get_available_cameras() available_cameras = get_available_cameras()
# Convert camera indices to strings for CTkOptionMenu camera_indices, camera_names = available_cameras
available_camera_indices, available_camera_strings = available_cameras
camera_variable = ctk.StringVar( if not camera_names or camera_names[0] == "No cameras found":
value=( camera_variable = ctk.StringVar(value="No cameras found")
available_camera_strings[0] camera_optionmenu = ctk.CTkOptionMenu(
if available_camera_strings root,
else "No cameras found" variable=camera_variable,
values=["No cameras found"],
state="disabled",
) )
) else:
camera_optionmenu = ctk.CTkOptionMenu( camera_variable = ctk.StringVar(value=camera_names[0])
root, variable=camera_variable, values=available_camera_strings camera_optionmenu = ctk.CTkOptionMenu(
) root, variable=camera_variable, values=camera_names
)
camera_optionmenu.place(relx=0.35, rely=0.86, relwidth=0.25, relheight=0.05) camera_optionmenu.place(relx=0.35, rely=0.86, relwidth=0.25, relheight=0.05)
live_button = ctk.CTkButton( live_button = ctk.CTkButton(
@ -335,9 +345,16 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
cursor="hand2", cursor="hand2",
command=lambda: webcam_preview( command=lambda: webcam_preview(
root, root,
available_camera_indices[ (
available_camera_strings.index(camera_variable.get()) camera_indices[camera_names.index(camera_variable.get())]
], if camera_names and camera_names[0] != "No cameras found"
else None
),
),
state=(
"normal"
if camera_names and camera_names[0] != "No cameras found"
else "disabled"
), ),
) )
live_button.place(relx=0.65, rely=0.86, relwidth=0.2, relheight=0.05) live_button.place(relx=0.65, rely=0.86, relwidth=0.2, relheight=0.05)
@ -354,7 +371,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
text_color=ctk.ThemeManager.theme.get("URL").get("text_color") text_color=ctk.ThemeManager.theme.get("URL").get("text_color")
) )
donate_label.bind( donate_label.bind(
"<Button>", lambda event: webbrowser.open("https://paypal.me/hacksider") "<Button>", lambda event: webbrowser.open("https://deeplivecam.net")
) )
return root return root
@ -395,8 +412,8 @@ def create_source_target_popup(
def on_submit_click(start): def on_submit_click(start):
if has_valid_map(): if has_valid_map():
simplify_maps() POPUP.destroy()
update_pop_live_status("Mappings submitted successfully!") select_output_path(start)
else: else:
update_pop_status("Atleast 1 source with target is required!") update_pop_status("Atleast 1 source with target is required!")
@ -743,15 +760,9 @@ def update_preview(frame_number: int = 0) -> None:
def webcam_preview(root: ctk.CTk, camera_index: int): def webcam_preview(root: ctk.CTk, camera_index: int):
global POPUP_LIVE
if POPUP_LIVE is not None and POPUP_LIVE.winfo_exists():
POPUP_LIVE.focus()
return
if not modules.globals.map_faces: if not modules.globals.map_faces:
if modules.globals.source_path is None: if modules.globals.source_path is None:
# No image selected update_status("Please select a source image first")
return return
create_webcam_preview(camera_index) create_webcam_preview(camera_index)
else: else:
@ -763,108 +774,164 @@ def webcam_preview(root: ctk.CTk, camera_index: int):
def get_available_cameras(): def get_available_cameras():
"""Returns a list of available camera names and indices.""" """Returns a list of available camera names and indices."""
camera_indices = [] if platform.system() == "Windows":
camera_names = [] try:
graph = FilterGraph()
devices = graph.get_input_devices()
for camera in enumerate_cameras(): # Create list of indices and names
cap = cv2.VideoCapture(camera.index) camera_indices = list(range(len(devices)))
if cap.isOpened(): camera_names = devices
camera_indices.append(camera.index)
camera_names.append(camera.name) # If no cameras found through DirectShow, try OpenCV fallback
cap.release() if not camera_names:
return (camera_indices, camera_names) # Try to open camera with index -1 and 0
test_indices = [-1, 0]
working_cameras = []
for idx in test_indices:
cap = cv2.VideoCapture(idx)
if cap.isOpened():
working_cameras.append(f"Camera {idx}")
cap.release()
if working_cameras:
return test_indices[: len(working_cameras)], working_cameras
# If still no cameras found, return empty lists
if not camera_names:
return [], ["No cameras found"]
return camera_indices, camera_names
except Exception as e:
print(f"Error detecting cameras: {str(e)}")
return [], ["No cameras found"]
else:
# Unix-like systems (Linux/Mac) camera detection
camera_indices = []
camera_names = []
if platform.system() == "Darwin": # macOS specific handling
# Try to open the default FaceTime camera first
cap = cv2.VideoCapture(0)
if cap.isOpened():
camera_indices.append(0)
camera_names.append("FaceTime Camera")
cap.release()
# On macOS, additional cameras typically use indices 1 and 2
for i in [1, 2]:
cap = cv2.VideoCapture(i)
if cap.isOpened():
camera_indices.append(i)
camera_names.append(f"Camera {i}")
cap.release()
else:
# Linux camera detection - test first 10 indices
for i in range(10):
cap = cv2.VideoCapture(i)
if cap.isOpened():
camera_indices.append(i)
camera_names.append(f"Camera {i}")
cap.release()
if not camera_names:
return [], ["No cameras found"]
return camera_indices, camera_names
def create_webcam_preview(camera_index: int): def create_webcam_preview(camera_index: int):
global preview_label, PREVIEW global preview_label, PREVIEW
camera = cv2.VideoCapture(camera_index) cap = VideoCapturer(camera_index)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, PREVIEW_DEFAULT_WIDTH) if not cap.start(PREVIEW_DEFAULT_WIDTH, PREVIEW_DEFAULT_HEIGHT, 60):
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, PREVIEW_DEFAULT_HEIGHT) update_status("Failed to start camera")
camera.set(cv2.CAP_PROP_FPS, 60) return
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 source_image = None
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
try: while True:
while camera: ret, frame = cap.read()
ret, frame = camera.read() if not ret:
if not ret: break
break
temp_frame = frame.copy() temp_frame = frame.copy()
if modules.globals.live_mirror: if modules.globals.live_mirror:
temp_frame = cv2.flip(temp_frame, 1) temp_frame = cv2.flip(temp_frame, 1)
if modules.globals.live_resizable: if modules.globals.live_resizable:
temp_frame = fit_image_to_size( temp_frame = fit_image_to_size(
temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height() 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
if current_time - prev_time >= fps_update_interval:
fps = frame_count / (current_time - prev_time)
frame_count = 0
prev_time = current_time
if modules.globals.show_fps:
cv2.putText(
temp_frame,
f"FPS: {fps:.1f}",
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(0, 255, 0),
2,
)
image = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB)
image = Image.fromarray(image)
image = ImageOps.contain(
image, (temp_frame.shape[1], temp_frame.shape[0]), Image.LANCZOS
) )
image = ctk.CTkImage(image, size=image.size)
preview_label.configure(image=image)
ROOT.update()
if PREVIEW.state() == "withdrawn": else:
break temp_frame = fit_image_to_size(
finally: temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height()
camera.release() )
PREVIEW.withdraw()
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
if current_time - prev_time >= fps_update_interval:
fps = frame_count / (current_time - prev_time)
frame_count = 0
prev_time = current_time
if modules.globals.show_fps:
cv2.putText(
temp_frame,
f"FPS: {fps:.1f}",
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(0, 255, 0),
2,
)
image = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB)
image = Image.fromarray(image)
image = ImageOps.contain(
image, (temp_frame.shape[1], temp_frame.shape[0]), Image.LANCZOS
)
image = ctk.CTkImage(image, size=image.size)
preview_label.configure(image=image)
ROOT.update()
if PREVIEW.state() == "withdrawn":
break
cap.release()
PREVIEW.withdraw()
def create_source_target_popup_for_webcam( def create_source_target_popup_for_webcam(
@ -879,6 +946,7 @@ def create_source_target_popup_for_webcam(
def on_submit_click(): def on_submit_click():
if has_valid_map(): if has_valid_map():
POPUP_LIVE.destroy()
simplify_maps() simplify_maps()
create_webcam_preview(camera_index) create_webcam_preview(camera_index)
else: else:
@ -889,35 +957,16 @@ def create_source_target_popup_for_webcam(
refresh_data(map) refresh_data(map)
update_pop_live_status("Please provide mapping!") update_pop_live_status("Please provide mapping!")
def on_clear_click():
for item in map:
if "source" in item:
item.pop("source")
if "target" in item:
item.pop("target")
refresh_data(map)
update_pop_live_status("Source and target images cleared.")
popup_status_label_live = ctk.CTkLabel(POPUP_LIVE, text=None, justify="center") popup_status_label_live = ctk.CTkLabel(POPUP_LIVE, text=None, justify="center")
popup_status_label_live.grid(row=1, column=0, pady=15) popup_status_label_live.grid(row=1, column=0, pady=15)
add_button = ctk.CTkButton(POPUP_LIVE, text="Add", command=lambda: on_add_click()) add_button = ctk.CTkButton(POPUP_LIVE, text="Add", command=lambda: on_add_click())
add_button.place(relx=0.1, rely=0.92, relwidth=0.2, relheight=0.05) add_button.place(relx=0.2, rely=0.92, relwidth=0.2, relheight=0.05)
clear_button = ctk.CTkButton(
POPUP_LIVE,
text="Clear",
command=lambda: on_clear_click(),
state="normal",
)
clear_button.place(relx=0.4, rely=0.92, relwidth=0.15, relheight=0.05)
close_button = ctk.CTkButton( close_button = ctk.CTkButton(
POPUP_LIVE, text="Submit", command=lambda: on_submit_click() POPUP_LIVE, text="Submit", command=lambda: on_submit_click()
) )
close_button.place(relx=0.7, rely=0.92, relwidth=0.2, relheight=0.05) close_button.place(relx=0.6, rely=0.92, relwidth=0.2, relheight=0.05)
refresh_data(map)
def refresh_data(map: list): def refresh_data(map: list):
@ -964,36 +1013,40 @@ def refresh_data(map: list):
button.grid(row=id, column=3, padx=20, pady=10) button.grid(row=id, column=3, padx=20, pady=10)
if "source" in item: if "source" in item:
source_label = ctk.CTkLabel( image = Image.fromarray(
cv2.cvtColor(item["source"]["cv2"], cv2.COLOR_BGR2RGB)
)
image = image.resize(
(MAPPER_PREVIEW_MAX_WIDTH, MAPPER_PREVIEW_MAX_HEIGHT), Image.LANCZOS
)
tk_image = ctk.CTkImage(image, size=image.size)
source_image = ctk.CTkLabel(
scrollable_frame, scrollable_frame,
text="", text=f"S-{id}",
width=MAPPER_PREVIEW_MAX_WIDTH, width=MAPPER_PREVIEW_MAX_WIDTH,
height=MAPPER_PREVIEW_MAX_HEIGHT, height=MAPPER_PREVIEW_MAX_HEIGHT,
) )
source_label.grid(row=id, column=1, padx=10, pady=10) source_image.grid(row=id, column=1, padx=10, pady=10)
else: source_image.configure(image=tk_image)
ctk.CTkLabel(
scrollable_frame,
text="No Source",
width=MAPPER_PREVIEW_MAX_WIDTH,
height=MAPPER_PREVIEW_MAX_HEIGHT,
).grid(row=id, column=1, padx=10, pady=10)
if "target" in item: if "target" in item:
target_label = ctk.CTkLabel( image = Image.fromarray(
cv2.cvtColor(item["target"]["cv2"], cv2.COLOR_BGR2RGB)
)
image = image.resize(
(MAPPER_PREVIEW_MAX_WIDTH, MAPPER_PREVIEW_MAX_HEIGHT), Image.LANCZOS
)
tk_image = ctk.CTkImage(image, size=image.size)
target_image = ctk.CTkLabel(
scrollable_frame, scrollable_frame,
text="", text=f"T-{id}",
width=MAPPER_PREVIEW_MAX_WIDTH, width=MAPPER_PREVIEW_MAX_WIDTH,
height=MAPPER_PREVIEW_MAX_HEIGHT, height=MAPPER_PREVIEW_MAX_HEIGHT,
) )
target_label.grid(row=id, column=4, padx=20, pady=10) target_image.grid(row=id, column=4, padx=20, pady=10)
else: target_image.configure(image=tk_image)
ctk.CTkLabel(
scrollable_frame,
text="No Target",
width=MAPPER_PREVIEW_MAX_WIDTH,
height=MAPPER_PREVIEW_MAX_HEIGHT,
).grid(row=id, column=4, padx=20, pady=10)
def update_webcam_source( def update_webcam_source(
@ -1016,11 +1069,6 @@ def update_webcam_source(
return map return map
else: else:
cv2_img = cv2.imread(source_path) cv2_img = cv2.imread(source_path)
if cv2_img is None:
update_pop_live_status("Failed to load the selected image. Please try again.")
return map
face = get_one_face(cv2_img) face = get_one_face(cv2_img)
if face: if face: