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

This reverts commit c03f697729, reversing
changes made to d8a5cdbc19.
pull/873/head
Kenneth Estanislao 2025-01-06 14:14:21 +08:00
parent b518f4337d
commit b38831dfdf
1 changed files with 201 additions and 153 deletions

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]
if available_camera_strings
else "No cameras found"
)
)
camera_optionmenu = ctk.CTkOptionMenu( camera_optionmenu = ctk.CTkOptionMenu(
root, variable=camera_variable, values=available_camera_strings root,
variable=camera_variable,
values=["No cameras found"],
state="disabled",
) )
else:
camera_variable = ctk.StringVar(value=camera_names[0])
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,41 +774,94 @@ 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."""
if platform.system() == "Windows":
try:
graph = FilterGraph()
devices = graph.get_input_devices()
# Create list of indices and names
camera_indices = list(range(len(devices)))
camera_names = devices
# If no cameras found through DirectShow, try OpenCV fallback
if not 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_indices = []
camera_names = [] camera_names = []
for camera in enumerate_cameras(): if platform.system() == "Darwin": # macOS specific handling
cap = cv2.VideoCapture(camera.index) # Try to open the default FaceTime camera first
cap = cv2.VideoCapture(0)
if cap.isOpened(): if cap.isOpened():
camera_indices.append(camera.index) camera_indices.append(0)
camera_names.append(camera.name) camera_names.append("FaceTime Camera")
cap.release() cap.release()
return (camera_indices, camera_names)
# 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
@ -811,6 +875,11 @@ def create_webcam_preview(camera_index: int):
temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height() temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height()
) )
else:
temp_frame = fit_image_to_size(
temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height()
)
if not modules.globals.map_faces: if not modules.globals.map_faces:
if source_image is None and modules.globals.source_path: if source_image is None and modules.globals.source_path:
source_image = get_one_face(cv2.imread(modules.globals.source_path)) source_image = get_one_face(cv2.imread(modules.globals.source_path))
@ -823,7 +892,6 @@ def create_webcam_preview(camera_index: int):
temp_frame = frame_processor.process_frame(source_image, temp_frame) temp_frame = frame_processor.process_frame(source_image, temp_frame)
else: else:
modules.globals.target_path = None modules.globals.target_path = None
for frame_processor in frame_processors: for frame_processor in frame_processors:
if frame_processor.NAME == "DLC.FACE-ENHANCER": if frame_processor.NAME == "DLC.FACE-ENHANCER":
if modules.globals.fp_ui["face_enhancer"]: if modules.globals.fp_ui["face_enhancer"]:
@ -861,10 +929,9 @@ def create_webcam_preview(camera_index: int):
if PREVIEW.state() == "withdrawn": if PREVIEW.state() == "withdrawn":
break break
finally:
camera.release()
PREVIEW.withdraw()
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: