parent
							
								
									60e27f4755
								
							
						
					
					
						commit
						95742c8fd5
					
				|  | @ -35,3 +35,4 @@ log_level = 'error' | ||||||
| fp_ui: Dict[str, bool] = {} | fp_ui: Dict[str, bool] = {} | ||||||
| camera_input_combobox = None | camera_input_combobox = None | ||||||
| webcam_preview_running = False | webcam_preview_running = False | ||||||
|  | opacity = 100  | ||||||
|  |  | ||||||
								
									
									
										
											147
										
									
									modules/ui.py
									
									
									
									
								
								
							
							
										
											147
										
									
									modules/ui.py
									
									
									
									
								|  | @ -3,6 +3,7 @@ import webbrowser | ||||||
| import customtkinter as ctk | import customtkinter as ctk | ||||||
| from typing import Callable, Tuple | from typing import Callable, Tuple | ||||||
| import cv2 | import cv2 | ||||||
|  | from cv2_enumerate_cameras import enumerate_cameras | ||||||
| from PIL import Image, ImageOps | from PIL import Image, ImageOps | ||||||
| import tkinterdnd2 as tkdnd | import tkinterdnd2 as tkdnd | ||||||
| import time | import time | ||||||
|  | @ -25,6 +26,7 @@ from modules.utilities import ( | ||||||
|     has_image_extension, |     has_image_extension, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | modules.globals.face_opacity = 100 | ||||||
| os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" | os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" | ||||||
| os.environ["QT_SCREEN_SCALE_FACTORS"] = "1" | os.environ["QT_SCREEN_SCALE_FACTORS"] = "1" | ||||||
| os.environ["QT_SCALE_FACTOR"] = "1" | os.environ["QT_SCALE_FACTOR"] = "1" | ||||||
|  | @ -402,11 +404,33 @@ def create_root( | ||||||
|     ) |     ) | ||||||
|     preview_button.pack(side="left", padx=10, expand=True) |     preview_button.pack(side="left", padx=10, expand=True) | ||||||
| 
 | 
 | ||||||
|  |     # --- Camera Selection --- | ||||||
|  |     camera_label = ctk.CTkLabel(root, text="Select Camera:") | ||||||
|  |     camera_label.place(relx=0.4, rely=0.86, relwidth=0.2, relheight=0.05) | ||||||
|  |     available_cameras = get_available_cameras() | ||||||
|  |     # Convert camera indices to strings for CTkOptionMenu | ||||||
|  |     available_camera_indices, available_camera_strings = available_cameras | ||||||
|  |     camera_variable = ctk.StringVar( | ||||||
|  |         value=available_camera_strings[0] | ||||||
|  |         if available_camera_strings | ||||||
|  |         else "No cameras found" | ||||||
|  |     ) | ||||||
|  |     camera_optionmenu = ctk.CTkOptionMenu( | ||||||
|  |         root, variable=camera_variable, values=available_camera_strings | ||||||
|  |     ) | ||||||
|  |     camera_optionmenu.place(relx=0.65, rely=0.86, relwidth=0.2, relheight=0.05) | ||||||
|  |     # --- End Camera Selection --- | ||||||
|  | 
 | ||||||
|     live_button = ModernButton( |     live_button = ModernButton( | ||||||
|         button_frame, |         button_frame, | ||||||
|         text="Live", |         text="Live", | ||||||
|         cursor="hand2", |         cursor="hand2", | ||||||
|         command=lambda: webcam_preview(root), |         command=lambda: webcam_preview( | ||||||
|  |             root, | ||||||
|  |             available_camera_indices[ | ||||||
|  |                 available_camera_strings.index(camera_variable.get()) | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|     ) |     ) | ||||||
|     live_button.pack(side="left", padx=10, expand=True) |     live_button.pack(side="left", padx=10, expand=True) | ||||||
| 
 | 
 | ||||||
|  | @ -454,6 +478,29 @@ def create_root( | ||||||
|     ) |     ) | ||||||
|     remove_donate_button.pack(side="right", padx=(10, 0)) |     remove_donate_button.pack(side="right", padx=(10, 0)) | ||||||
| 
 | 
 | ||||||
|  |     # Add opacity slider | ||||||
|  |     opacity_frame = ctk.CTkFrame(options_column, fg_color="#2a2d2e") | ||||||
|  |     opacity_frame.pack(pady=5, anchor="w", fill="x") | ||||||
|  | 
 | ||||||
|  |     opacity_label = ctk.CTkLabel( | ||||||
|  |         opacity_frame, text="Face Opacity:", font=("Roboto", 14, "bold") | ||||||
|  |     ) | ||||||
|  |     opacity_label.pack(side="left", padx=(0, 10)) | ||||||
|  | 
 | ||||||
|  |     opacity_slider = ctk.CTkSlider( | ||||||
|  |         opacity_frame, | ||||||
|  |         from_=0, | ||||||
|  |         to=100, | ||||||
|  |         number_of_steps=100, | ||||||
|  |         command=update_opacity, | ||||||
|  |         fg_color=("gray75", "gray25"), | ||||||
|  |         progress_color="#3a7ebf", | ||||||
|  |         button_color="#3a7ebf", | ||||||
|  |         button_hover_color="#2b5d8b", | ||||||
|  |     ) | ||||||
|  |     opacity_slider.pack(side="left", fill="x", expand=True) | ||||||
|  |     opacity_slider.set(modules.globals.face_opacity) | ||||||
|  | 
 | ||||||
|     main_frame.grid_columnconfigure((0, 2), weight=1) |     main_frame.grid_columnconfigure((0, 2), weight=1) | ||||||
|     main_frame.grid_rowconfigure((0, 1, 2), weight=1) |     main_frame.grid_rowconfigure((0, 1, 2), weight=1) | ||||||
| 
 | 
 | ||||||
|  | @ -959,75 +1006,111 @@ def update_preview(frame_number: int = 0) -> None: | ||||||
|         PREVIEW.deiconify() |         PREVIEW.deiconify() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def webcam_preview(root: ctk.CTk): | def webcam_preview(root: ctk.CTk, camera_index: int): | ||||||
|     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 |             # No image selected | ||||||
|             return |             return | ||||||
|         create_webcam_preview() |         create_webcam_preview(camera_index) | ||||||
|     else: |     else: | ||||||
|         modules.globals.souce_target_map = [] |         modules.globals.souce_target_map = [] | ||||||
|         create_source_target_popup_for_webcam(root, modules.globals.souce_target_map) |         create_source_target_popup_for_webcam(root, modules.globals.souce_target_map) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def create_webcam_preview(): | def get_available_cameras(): | ||||||
|  |     """Returns a list of available camera names and indices.""" | ||||||
|  |     camera_indices = [] | ||||||
|  |     camera_names = [] | ||||||
|  | 
 | ||||||
|  |     for camera in enumerate_cameras(): | ||||||
|  |         cap = cv2.VideoCapture(camera.index) | ||||||
|  |         if cap.isOpened(): | ||||||
|  |             camera_indices.append(camera.index) | ||||||
|  |             camera_names.append(camera.name) | ||||||
|  |             cap.release() | ||||||
|  |     return (camera_indices, camera_names) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Add this function to update the opacity value | ||||||
|  | def update_opacity(value): | ||||||
|  |     modules.globals.face_opacity = int(value) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Modify the create_webcam_preview function to include the slider | ||||||
|  | def create_webcam_preview(camera_index): | ||||||
|     global preview_label, PREVIEW |     global preview_label, PREVIEW | ||||||
| 
 | 
 | ||||||
|     camera = cv2.VideoCapture( |     camera = cv2.VideoCapture(camera_index) | ||||||
|         0 |     if not camera.isOpened(): | ||||||
|     )  # Use index for the webcam (adjust the index accordingly if necessary) |         update_status(f"Error: Could not open camera with index {camera_index}") | ||||||
|     camera.set( |         return | ||||||
|         cv2.CAP_PROP_FRAME_WIDTH, PREVIEW_DEFAULT_WIDTH |     camera.set(cv2.CAP_PROP_FRAME_WIDTH, PREVIEW_DEFAULT_WIDTH) | ||||||
|     )  # Set the width of the resolution |     camera.set(cv2.CAP_PROP_FRAME_HEIGHT, PREVIEW_DEFAULT_HEIGHT) | ||||||
|     camera.set( |     camera.set(cv2.CAP_PROP_FPS, 60) | ||||||
|         cv2.CAP_PROP_FRAME_HEIGHT, PREVIEW_DEFAULT_HEIGHT |  | ||||||
|     )  # Set the height of the resolution |  | ||||||
|     camera.set(cv2.CAP_PROP_FPS, 60)  # Set the frame rate of the webcam |  | ||||||
| 
 | 
 | ||||||
|     preview_label.configure( |     PREVIEW.deiconify() | ||||||
|         width=PREVIEW_DEFAULT_WIDTH, height=PREVIEW_DEFAULT_HEIGHT |  | ||||||
|     )  # Reset the preview image before startup |  | ||||||
| 
 | 
 | ||||||
|     PREVIEW.deiconify()  # Open preview window |     # Remove any existing widgets in PREVIEW window | ||||||
|  |     for widget in PREVIEW.winfo_children(): | ||||||
|  |         widget.destroy() | ||||||
|  | 
 | ||||||
|  |     # Create a main frame to hold all widgets | ||||||
|  |     main_frame = ctk.CTkFrame(PREVIEW) | ||||||
|  |     main_frame.pack(fill="both", expand=True) | ||||||
|  | 
 | ||||||
|  |     # Create a frame for the preview label | ||||||
|  |     preview_frame = ctk.CTkFrame(main_frame) | ||||||
|  |     preview_frame.pack(fill="both", expand=True, padx=10, pady=10) | ||||||
|  | 
 | ||||||
|  |     preview_label = ctk.CTkLabel(preview_frame, text="") | ||||||
|  |     preview_label.pack(fill="both", expand=True) | ||||||
| 
 | 
 | ||||||
|     frame_processors = get_frame_processors_modules(modules.globals.frame_processors) |     frame_processors = get_frame_processors_modules(modules.globals.frame_processors) | ||||||
| 
 | 
 | ||||||
|     source_image = None  # Initialize variable for the selected face image |     source_image = None | ||||||
|  | 
 | ||||||
|  |     def update_frame_size(event): | ||||||
|  |         nonlocal temp_frame | ||||||
|  |         if modules.globals.live_resizable: | ||||||
|  |             temp_frame = fit_image_to_size(temp_frame, event.width, event.height) | ||||||
|  | 
 | ||||||
|  |     preview_frame.bind("<Configure>", update_frame_size) | ||||||
| 
 | 
 | ||||||
|     while camera: |     while camera: | ||||||
|         ret, frame = camera.read() |         ret, frame = camera.read() | ||||||
|         if not ret: |         if not ret: | ||||||
|             break |             break | ||||||
| 
 | 
 | ||||||
|         temp_frame = frame.copy()  # Create a copy of the frame |         temp_frame = frame.copy() | ||||||
| 
 | 
 | ||||||
|         if modules.globals.live_mirror: |         if modules.globals.live_mirror: | ||||||
|             temp_frame = cv2.flip(temp_frame, 1)  # horizontal flipping |             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 not modules.globals.map_faces: | ||||||
|             # Select and save face image only once |  | ||||||
|             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)) | ||||||
| 
 | 
 | ||||||
|  |             original_frame = temp_frame.copy() | ||||||
|             for frame_processor in frame_processors: |             for frame_processor in frame_processors: | ||||||
|                 temp_frame = frame_processor.process_frame(source_image, temp_frame) |                 temp_frame = frame_processor.process_frame(source_image, temp_frame) | ||||||
|  | 
 | ||||||
|  |             # Apply opacity | ||||||
|  |             opacity = modules.globals.face_opacity / 100 | ||||||
|  |             temp_frame = cv2.addWeighted( | ||||||
|  |                 temp_frame, opacity, original_frame, 1 - opacity, 0 | ||||||
|  |             ) | ||||||
|         else: |         else: | ||||||
|             modules.globals.target_path = None |             modules.globals.target_path = None | ||||||
| 
 | 
 | ||||||
|             for frame_processor in frame_processors: |             for frame_processor in frame_processors: | ||||||
|                 temp_frame = frame_processor.process_frame_v2(temp_frame) |                 temp_frame = frame_processor.process_frame_v2(temp_frame) | ||||||
| 
 | 
 | ||||||
|         image = cv2.cvtColor( |         image = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB) | ||||||
|             temp_frame, cv2.COLOR_BGR2RGB |  | ||||||
|         )  # Convert the image to RGB format to display it with Tkinter |  | ||||||
|         image = Image.fromarray(image) |         image = Image.fromarray(image) | ||||||
|         image = ImageOps.contain( |         image = ImageOps.contain( | ||||||
|             image, (temp_frame.shape[1], temp_frame.shape[0]), Image.LANCZOS |             image, | ||||||
|  |             (preview_frame.winfo_width(), preview_frame.winfo_height()), | ||||||
|  |             Image.LANCZOS, | ||||||
|         ) |         ) | ||||||
|         image = ctk.CTkImage(image, size=image.size) |         image = ctk.CTkImage(image, size=image.size) | ||||||
|         preview_label.configure(image=image) |         preview_label.configure(image=image) | ||||||
|  | @ -1037,7 +1120,7 @@ def create_webcam_preview(): | ||||||
|             break |             break | ||||||
| 
 | 
 | ||||||
|     camera.release() |     camera.release() | ||||||
|     PREVIEW.withdraw()  # Close preview window when loop is finished |     PREVIEW.withdraw() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def create_source_target_popup_for_webcam(root: ctk.CTk, map: list) -> None: | def create_source_target_popup_for_webcam(root: ctk.CTk, map: list) -> None: | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| numpy>=1.23.5,<2 | numpy>=1.23.5,<2 | ||||||
| opencv-python==4.8.1.78 | opencv-python==4.8.1.78 | ||||||
|  | cv2_enumerate_cameras==1.1.15 | ||||||
| onnx==1.16.0 | onnx==1.16.0 | ||||||
| insightface==0.7.3 | insightface==0.7.3 | ||||||
| psutil==5.9.8 | psutil==5.9.8 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue