From 8055d79daf5a6477f4f7c7daab8dee2981600df9 Mon Sep 17 00:00:00 2001 From: KRSHH <136873090+KRSHH@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:10:45 +0530 Subject: [PATCH] Privacy Mode --- modules/core.py | 2 + modules/deeplivecam.ico | Bin 0 -> 270622 bytes modules/fake_face_handler.py | 120 ++++++++++++++++++++++++++++ modules/globals.py | 2 + modules/ui.py | 150 ++++++++++++++++++++++++----------- 5 files changed, 227 insertions(+), 47 deletions(-) create mode 100644 modules/deeplivecam.ico create mode 100644 modules/fake_face_handler.py diff --git a/modules/core.py b/modules/core.py index c0c25f1..cb29643 100644 --- a/modules/core.py +++ b/modules/core.py @@ -20,6 +20,7 @@ import modules.metadata import modules.ui as ui from modules.processors.frame.core import get_frame_processors_modules from modules.utilities import has_image_extension, is_image, is_video, detect_fps, create_video, extract_frames, get_temp_frame_paths, restore_audio, create_temp, move_temp, clean_temp, normalize_output_path +from modules.fake_face_handler import cleanup_fake_face if 'ROCMExecutionProvider' in modules.globals.execution_providers: del torch @@ -239,6 +240,7 @@ def start() -> None: def destroy(to_quit=True) -> None: if modules.globals.target_path: clean_temp(modules.globals.target_path) + cleanup_fake_face() if to_quit: quit() diff --git a/modules/deeplivecam.ico b/modules/deeplivecam.ico new file mode 100644 index 0000000000000000000000000000000000000000..f550109a1719d538c869c0f8b1d941f75cf36df9 GIT binary patch literal 270622 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 str: + """Fetch a face from thispersondoesnotexist.com and save it temporarily""" + try: + # Create temp directory if it doesn't exist + temp_dir = Path(tempfile.gettempdir()) / "deep-live-cam" + temp_dir.mkdir(parents=True, exist_ok=True) + + # Generate temp file path + temp_file = temp_dir / "fake_face.jpg" + + # Basic headers to mimic a browser request + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + } + + # Fetch the image + response = requests.get('https://thispersondoesnotexist.com', headers=headers) + + if response.status_code == 200: + # Read image from response + image_array = np.asarray(bytearray(response.content), dtype=np.uint8) + image = cv2.imdecode(image_array, cv2.IMREAD_COLOR) + + # Add padding around the face + padded_image = add_padding_to_face(image) + + # Save the padded image + cv2.imwrite(str(temp_file), padded_image) + return str(temp_file) + else: + print(f"Failed to fetch fake face: {response.status_code}") + return None + except Exception as e: + print(f"Error fetching fake face: {str(e)}") + return None + +def cleanup_fake_face(): + """Clean up the temporary fake face image""" + try: + if modules.globals.fake_face_path and os.path.exists(modules.globals.fake_face_path): + os.remove(modules.globals.fake_face_path) + modules.globals.fake_face_path = None + except Exception as e: + print(f"Error cleaning up fake face: {str(e)}") + +def refresh_fake_face(): + """Refresh the fake face image""" + cleanup_fake_face() + modules.globals.fake_face_path = get_fake_face() + return modules.globals.fake_face_path is not None \ No newline at end of file diff --git a/modules/globals.py b/modules/globals.py index 693084d..9bd9f4c 100644 --- a/modules/globals.py +++ b/modules/globals.py @@ -41,3 +41,5 @@ show_mouth_mask_box = False mask_feather_ratio = 8 mask_down_size = 0.50 mask_size = 1 +use_fake_face = False +fake_face_path = None diff --git a/modules/ui.py b/modules/ui.py index c491dac..7a14f68 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -28,6 +28,7 @@ from modules.utilities import ( from modules.video_capture import VideoCapturer from modules.gettext import LanguageManager import platform +from modules.fake_face_handler import cleanup_fake_face, refresh_fake_face if platform.system() == "Windows": from pygrabber.dshow_graph import FilterGraph @@ -91,47 +92,52 @@ def init(start: Callable[[], None], destroy: Callable[[], None], lang: str) -> c def save_switch_states(): - switch_states = { - "keep_fps": modules.globals.keep_fps, - "keep_audio": modules.globals.keep_audio, - "keep_frames": modules.globals.keep_frames, - "many_faces": modules.globals.many_faces, - "map_faces": modules.globals.map_faces, - "color_correction": modules.globals.color_correction, - "nsfw_filter": modules.globals.nsfw_filter, - "live_mirror": modules.globals.live_mirror, - "live_resizable": modules.globals.live_resizable, - "fp_ui": modules.globals.fp_ui, - "show_fps": modules.globals.show_fps, - "mouth_mask": modules.globals.mouth_mask, - "show_mouth_mask_box": modules.globals.show_mouth_mask_box, - } - with open("switch_states.json", "w") as f: - json.dump(switch_states, f) + try: + states = { + "keep_fps": modules.globals.keep_fps, + "keep_audio": modules.globals.keep_audio, + "keep_frames": modules.globals.keep_frames, + "many_faces": modules.globals.many_faces, + "map_faces": modules.globals.map_faces, + "color_correction": modules.globals.color_correction, + "nsfw_filter": modules.globals.nsfw_filter, + "live_mirror": modules.globals.live_mirror, + "live_resizable": modules.globals.live_resizable, + "fp_ui": modules.globals.fp_ui, + "show_fps": modules.globals.show_fps, + "mouth_mask": modules.globals.mouth_mask, + "show_mouth_mask_box": modules.globals.show_mouth_mask_box, + "use_fake_face": modules.globals.use_fake_face + } + with open(get_config_path(), 'w') as f: + json.dump(states, f) + except Exception as e: + print(f"Error saving switch states: {str(e)}") def load_switch_states(): try: - with open("switch_states.json", "r") as f: - switch_states = json.load(f) - modules.globals.keep_fps = switch_states.get("keep_fps", True) - modules.globals.keep_audio = switch_states.get("keep_audio", True) - modules.globals.keep_frames = switch_states.get("keep_frames", False) - modules.globals.many_faces = switch_states.get("many_faces", False) - modules.globals.map_faces = switch_states.get("map_faces", False) - modules.globals.color_correction = switch_states.get("color_correction", False) - modules.globals.nsfw_filter = switch_states.get("nsfw_filter", False) - modules.globals.live_mirror = switch_states.get("live_mirror", False) - modules.globals.live_resizable = switch_states.get("live_resizable", 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.mouth_mask = switch_states.get("mouth_mask", False) - modules.globals.show_mouth_mask_box = switch_states.get( - "show_mouth_mask_box", False - ) - except FileNotFoundError: - # If the file doesn't exist, use default values - pass + if os.path.exists(get_config_path()): + with open(get_config_path(), 'r') as f: + states = json.load(f) + modules.globals.keep_fps = states.get("keep_fps", True) + modules.globals.keep_audio = states.get("keep_audio", True) + modules.globals.keep_frames = states.get("keep_frames", False) + modules.globals.many_faces = states.get("many_faces", False) + modules.globals.map_faces = states.get("map_faces", False) + modules.globals.color_correction = states.get("color_correction", False) + modules.globals.nsfw_filter = states.get("nsfw_filter", False) + modules.globals.live_mirror = states.get("live_mirror", False) + modules.globals.live_resizable = states.get("live_resizable", False) + modules.globals.fp_ui = states.get("fp_ui", {"face_enhancer": False}) + modules.globals.show_fps = states.get("show_fps", False) + modules.globals.mouth_mask = states.get("mouth_mask", False) + modules.globals.show_mouth_mask_box = states.get( + "show_mouth_mask_box", False + ) + modules.globals.use_fake_face = states.get('use_fake_face', False) + except Exception as e: + print(f"Error loading switch states: {str(e)}") def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk: @@ -176,6 +182,27 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C ) select_target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1) + # AI Generated Face controls + fake_face_value = ctk.BooleanVar(value=modules.globals.use_fake_face) + fake_face_switch = ctk.CTkSwitch( + root, + text=_("Privacy Mode"), + variable=fake_face_value, + cursor="hand2", + command=lambda: toggle_fake_face(fake_face_value) + ) + fake_face_switch.place(relx=0.1, rely=0.55) + + # Add refresh button next to the switch + refresh_face_button = ctk.CTkButton( + root, + text="↻", + width=30, + cursor="hand2", + command=lambda: refresh_fake_face_clicked() + ) + refresh_face_button.place(relx=0.35, rely=0.55) + # Face Processing Options (Middle Left) many_faces_value = ctk.BooleanVar(value=modules.globals.many_faces) many_faces_switch = ctk.CTkSwitch( @@ -188,7 +215,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C save_switch_states(), ), ) - many_faces_switch.place(relx=0.1, rely=0.55) + many_faces_switch.place(relx=0.1, rely=0.60) map_faces = ctk.BooleanVar(value=modules.globals.map_faces) map_faces_switch = ctk.CTkSwitch( @@ -202,7 +229,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C close_mapper_window() if not map_faces.get() else None ), ) - map_faces_switch.place(relx=0.1, rely=0.6) + map_faces_switch.place(relx=0.1, rely=0.65) enhancer_value = ctk.BooleanVar(value=modules.globals.fp_ui["face_enhancer"]) enhancer_switch = ctk.CTkSwitch( @@ -215,7 +242,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C save_switch_states(), ), ) - enhancer_switch.place(relx=0.1, rely=0.65) + enhancer_switch.place(relx=0.1, rely=0.70) # Additional Options (Middle Right) mouth_mask_var = ctk.BooleanVar(value=modules.globals.mouth_mask) @@ -257,21 +284,21 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C start_button = ctk.CTkButton( root, text=_("Start"), cursor="hand2", command=lambda: analyze_target(start, root) ) - start_button.place(relx=0.15, rely=0.75, relwidth=0.2, relheight=0.05) + start_button.place(relx=0.15, rely=0.80, relwidth=0.2, relheight=0.05) preview_button = ctk.CTkButton( root, text=_("Preview"), cursor="hand2", command=lambda: toggle_preview() ) - preview_button.place(relx=0.4, rely=0.75, relwidth=0.2, relheight=0.05) + preview_button.place(relx=0.4, rely=0.80, relwidth=0.2, relheight=0.05) stop_button = ctk.CTkButton( root, text=_("Destroy"), cursor="hand2", command=lambda: destroy() ) - stop_button.place(relx=0.65, rely=0.75, relwidth=0.2, relheight=0.05) + stop_button.place(relx=0.65, rely=0.80, relwidth=0.2, relheight=0.05) # Camera Section (Bottom) camera_label = ctk.CTkLabel(root, text=_("Select Camera:")) - camera_label.place(relx=0.1, rely=0.85, relwidth=0.2, relheight=0.05) + camera_label.place(relx=0.1, rely=0.87, relwidth=0.2, relheight=0.05) available_cameras = get_available_cameras() camera_indices, camera_names = available_cameras @@ -290,7 +317,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C root, variable=camera_variable, values=camera_names ) - camera_optionmenu.place(relx=0.35, rely=0.85, relwidth=0.25, relheight=0.05) + camera_optionmenu.place(relx=0.35, rely=0.87, relwidth=0.25, relheight=0.05) live_button = ctk.CTkButton( root, @@ -310,7 +337,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C else "disabled" ), ) - live_button.place(relx=0.65, rely=0.85, relwidth=0.2, relheight=0.05) + live_button.place(relx=0.65, rely=0.87, relwidth=0.2, relheight=0.05) # Status and Links (Bottom) status_label = ctk.CTkLabel(root, text=None, justify="center") @@ -1147,4 +1174,33 @@ def update_webcam_target( target_label_dict_live[button_num] = target_image else: update_pop_live_status("Face could not be detected in last upload!") - return map \ No newline at end of file + return map + +def toggle_fake_face(switch_var: ctk.BooleanVar) -> None: + modules.globals.use_fake_face = switch_var.get() + if modules.globals.use_fake_face: + if not modules.globals.fake_face_path: + if refresh_fake_face(): + modules.globals.source_path = modules.globals.fake_face_path + # Update the source image preview + image = render_image_preview(modules.globals.source_path, (200, 200)) + source_label.configure(image=image) + else: + cleanup_fake_face() + # Clear the source image preview + source_label.configure(image=None) + modules.globals.source_path = None + +def refresh_fake_face_clicked() -> None: + if modules.globals.use_fake_face: + if refresh_fake_face(): + modules.globals.source_path = modules.globals.fake_face_path + # Update the source image preview + image = render_image_preview(modules.globals.source_path, (200, 200)) + source_label.configure(image=image) + +def get_config_path() -> str: + """Get the path to the config file""" + config_dir = os.path.join(os.path.expanduser("~"), ".deep-live-cam") + os.makedirs(config_dir, exist_ok=True) + return os.path.join(config_dir, "switch_states.json") \ No newline at end of file