Compare commits

...

3 Commits

Author SHA1 Message Date
Makaru 5c12a45269
Merge 441412e7ae into f164d9234b 2025-01-12 23:04:32 +08:00
KRSHH f164d9234b
Shifted Disclaimer to Bottom
Its pretty much standard in any repo
2025-01-12 16:35:11 +05:30
Makaru 441412e7ae
Update ui.py
Added:
- Transparency dropdown

Note:
- I also update the face_swapper.py
2025-01-11 16:52:19 +08:00
2 changed files with 71 additions and 54 deletions

View File

@ -12,13 +12,6 @@
<img src="media/demo.gif" alt="Demo GIF" width="800">
</p>
## Disclaimer
###### This software is intended as a productive contribution to the AI-generated media industry. It aims to assist artists with tasks like animating custom characters or using them as models for clothing, etc.
###### We are aware of the potential for unethical applications and are committed to preventative measures. A built-in check prevents the program from processing inappropriate media (nudity, graphic content, sensitive material like war footage, etc.). We will continue to develop this project responsibly, adhering to the law and ethics. We may shut down the project or add watermarks if legally required.
###### Users are expected to use this software responsibly and legally. If using a real person's face, obtain their consent and clearly label any output as a deepfake when sharing online. We are not responsible for end-user actions.
## Quick Start - Pre-built (Windows / Nvidia)
<a href="https://hacksider.gumroad.com/l/vccdmm"> <img src="https://github.com/user-attachments/assets/7d993b32-e3e8-4cd3-bbfb-a549152ebdd5" width="285" height="77" />
@ -282,3 +275,11 @@ Looking for a CLI mode? Using the -s/--source argument will make the run program
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=hacksider/deep-live-cam&type=Date" />
</picture>
</a>
## Disclaimer
###### This software is intended as a productive contribution to the AI-generated media industry. It aims to assist artists with tasks like animating custom characters or using them as models for clothing, etc.
###### We are aware of the potential for unethical applications and are committed to preventative measures. A built-in check prevents the program from processing inappropriate media (nudity, graphic content, sensitive material like war footage, etc.). We will continue to develop this project responsibly, adhering to the law and ethics. We may shut down the project or add watermarks if legally required.
###### Users are expected to use this software responsibly and legally. If using a real person's face, obtain their consent and clearly label any output as a deepfake when sharing online. We are not responsible for end-user actions.

View File

@ -26,7 +26,6 @@ from modules.utilities import (
has_image_extension,
)
from modules.video_capture import VideoCapturer
from modules.gettext import LanguageManager
import platform
if platform.system() == "Windows":
@ -64,7 +63,6 @@ RECENT_DIRECTORY_SOURCE = None
RECENT_DIRECTORY_TARGET = None
RECENT_DIRECTORY_OUTPUT = None
_ = None
preview_label = None
preview_slider = None
source_label = None
@ -79,11 +77,9 @@ target_label_dict_live = {}
img_ft, vid_ft = modules.globals.file_types
def init(start: Callable[[], None], destroy: Callable[[], None], lang: str) -> ctk.CTk:
global ROOT, PREVIEW, _
def init(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk:
global ROOT, PREVIEW
lang_manager = LanguageManager(lang)
_ = lang_manager._
ROOT = create_root(start, destroy)
PREVIEW = create_preview(ROOT)
@ -158,27 +154,47 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25)
select_face_button = ctk.CTkButton(
root, text=_("Select a face"), cursor="hand2", command=lambda: select_source_path()
root, text="Select a face", cursor="hand2", command=lambda: select_source_path()
)
select_face_button.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)
select_face_button.place(relx=0.1, rely=0.375, relwidth=0.3, relheight=0.1)
swap_faces_button = ctk.CTkButton(
root, text="", cursor="hand2", command=lambda: swap_faces_paths()
)
swap_faces_button.place(relx=0.45, rely=0.4, relwidth=0.1, relheight=0.1)
swap_faces_button.place(relx=0.45, rely=0.375, relwidth=0.1, relheight=0.1)
select_target_button = ctk.CTkButton(
root,
text=_("Select a target"),
text="Select a target",
cursor="hand2",
command=lambda: select_target_path(),
)
select_target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)
select_target_button.place(relx=0.6, rely=0.375, relwidth=0.3, relheight=0.1)
transparency_values = ["25%", "50%", "75%", "100%"]
transparency_var = ctk.StringVar(value="100%") # Default to 100%
def on_transparency_change(value: str):
percentage = int(value.strip('%'))
opacity = percentage / 100.0
modules.globals.opacity = opacity # Save opacity globally for real-time updates
update_status(f"Transparency set to {value}")
transparency_label = ctk.CTkLabel(root, text="Transparency:")
transparency_label.place(relx=0.1, rely=0.5, relwidth=0.2, relheight=0.05)
transparency_dropdown = ctk.CTkOptionMenu(
root,
values=transparency_values,
variable=transparency_var,
command=on_transparency_change,
)
transparency_dropdown.place(relx=0.35, rely=0.5, relwidth=0.25, relheight=0.05)
keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps)
keep_fps_checkbox = ctk.CTkSwitch(
root,
text=_("Keep fps"),
text="Keep fps",
variable=keep_fps_value,
cursor="hand2",
command=lambda: (
@ -191,7 +207,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
keep_frames_value = ctk.BooleanVar(value=modules.globals.keep_frames)
keep_frames_switch = ctk.CTkSwitch(
root,
text=_("Keep frames"),
text="Keep frames",
variable=keep_frames_value,
cursor="hand2",
command=lambda: (
@ -204,7 +220,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
enhancer_value = ctk.BooleanVar(value=modules.globals.fp_ui["face_enhancer"])
enhancer_switch = ctk.CTkSwitch(
root,
text=_("Face Enhancer"),
text="Face Enhancer",
variable=enhancer_value,
cursor="hand2",
command=lambda: (
@ -217,7 +233,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
keep_audio_value = ctk.BooleanVar(value=modules.globals.keep_audio)
keep_audio_switch = ctk.CTkSwitch(
root,
text=_("Keep audio"),
text="Keep audio",
variable=keep_audio_value,
cursor="hand2",
command=lambda: (
@ -230,7 +246,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
many_faces_value = ctk.BooleanVar(value=modules.globals.many_faces)
many_faces_switch = ctk.CTkSwitch(
root,
text=_("Many faces"),
text="Many faces",
variable=many_faces_value,
cursor="hand2",
command=lambda: (
@ -243,7 +259,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
color_correction_value = ctk.BooleanVar(value=modules.globals.color_correction)
color_correction_switch = ctk.CTkSwitch(
root,
text=_("Fix Blueish Cam"),
text="Fix Blueish Cam",
variable=color_correction_value,
cursor="hand2",
command=lambda: (
@ -260,7 +276,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
map_faces = ctk.BooleanVar(value=modules.globals.map_faces)
map_faces_switch = ctk.CTkSwitch(
root,
text=_("Map faces"),
text="Map faces",
variable=map_faces,
cursor="hand2",
command=lambda: (
@ -274,7 +290,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
show_fps_value = ctk.BooleanVar(value=modules.globals.show_fps)
show_fps_switch = ctk.CTkSwitch(
root,
text=_("Show FPS"),
text="Show FPS",
variable=show_fps_value,
cursor="hand2",
command=lambda: (
@ -287,7 +303,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
mouth_mask_var = ctk.BooleanVar(value=modules.globals.mouth_mask)
mouth_mask_switch = ctk.CTkSwitch(
root,
text=_("Mouth Mask"),
text="Mouth Mask",
variable=mouth_mask_var,
cursor="hand2",
command=lambda: setattr(modules.globals, "mouth_mask", mouth_mask_var.get()),
@ -297,7 +313,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
show_mouth_mask_box_var = ctk.BooleanVar(value=modules.globals.show_mouth_mask_box)
show_mouth_mask_box_switch = ctk.CTkSwitch(
root,
text=_("Show Mouth Mask Box"),
text="Show Mouth Mask Box",
variable=show_mouth_mask_box_var,
cursor="hand2",
command=lambda: setattr(
@ -307,22 +323,22 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
show_mouth_mask_box_switch.place(relx=0.6, rely=0.55)
start_button = ctk.CTkButton(
root, text=_("Start"), cursor="hand2", command=lambda: analyze_target(start, root)
root, text="Start", cursor="hand2", command=lambda: analyze_target(start, root)
)
start_button.place(relx=0.15, rely=0.80, relwidth=0.2, relheight=0.05)
stop_button = ctk.CTkButton(
root, text=_("Destroy"), cursor="hand2", command=lambda: destroy()
root, text="Destroy", cursor="hand2", command=lambda: destroy()
)
stop_button.place(relx=0.4, rely=0.80, relwidth=0.2, relheight=0.05)
preview_button = ctk.CTkButton(
root, text=_("Preview"), cursor="hand2", command=lambda: toggle_preview()
root, text="Preview", cursor="hand2", command=lambda: toggle_preview()
)
preview_button.place(relx=0.65, rely=0.80, relwidth=0.2, relheight=0.05)
# --- Camera Selection ---
camera_label = ctk.CTkLabel(root, text=_("Select Camera:"))
camera_label = ctk.CTkLabel(root, text="Select Camera:")
camera_label.place(relx=0.1, rely=0.86, relwidth=0.2, relheight=0.05)
available_cameras = get_available_cameras()
@ -346,7 +362,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
live_button = ctk.CTkButton(
root,
text=_("Live"),
text="Live",
cursor="hand2",
command=lambda: webcam_preview(
root,
@ -420,7 +436,7 @@ def create_source_target_popup(
global POPUP, popup_status_label
POPUP = ctk.CTkToplevel(root)
POPUP.title(_("Source x Target Mapper"))
POPUP.title("Source x Target Mapper")
POPUP.geometry(f"{POPUP_WIDTH}x{POPUP_HEIGHT}")
POPUP.focus()
@ -444,7 +460,7 @@ def create_source_target_popup(
button = ctk.CTkButton(
scrollable_frame,
text=_("Select source image"),
text="Select source image",
command=lambda id=id: on_button_click(map, id),
width=DEFAULT_BUTTON_WIDTH,
height=DEFAULT_BUTTON_HEIGHT,
@ -478,7 +494,7 @@ def create_source_target_popup(
popup_status_label.grid(row=1, column=0, pady=15)
close_button = ctk.CTkButton(
POPUP, text=_("Submit"), command=lambda: on_submit_click(start)
POPUP, text="Submit", command=lambda: on_submit_click(start)
)
close_button.grid(row=2, column=0, pady=10)
@ -489,7 +505,7 @@ def update_popup_source(
global source_label_dict
source_path = ctk.filedialog.askopenfilename(
title=_("select an source image"),
title="select an source image",
initialdir=RECENT_DIRECTORY_SOURCE,
filetypes=[img_ft],
)
@ -540,7 +556,7 @@ def create_preview(parent: ctk.CTkToplevel) -> ctk.CTkToplevel:
preview = ctk.CTkToplevel(parent)
preview.withdraw()
preview.title(_("Preview"))
preview.title("Preview")
preview.configure()
preview.protocol("WM_DELETE_WINDOW", lambda: toggle_preview())
preview.resizable(width=True, height=True)
@ -556,16 +572,16 @@ def create_preview(parent: ctk.CTkToplevel) -> ctk.CTkToplevel:
def update_status(text: str) -> None:
status_label.configure(text=_(text))
status_label.configure(text=text)
ROOT.update()
def update_pop_status(text: str) -> None:
popup_status_label.configure(text=_(text))
popup_status_label.configure(text=text)
def update_pop_live_status(text: str) -> None:
popup_status_label_live.configure(text=_(text))
popup_status_label_live.configure(text=text)
def update_tumbler(var: str, value: bool) -> None:
@ -584,7 +600,7 @@ def select_source_path() -> None:
PREVIEW.withdraw()
source_path = ctk.filedialog.askopenfilename(
title=_("select an source image"),
title="select an source image",
initialdir=RECENT_DIRECTORY_SOURCE,
filetypes=[img_ft],
)
@ -627,7 +643,7 @@ def select_target_path() -> None:
PREVIEW.withdraw()
target_path = ctk.filedialog.askopenfilename(
title=_("select an target image or video"),
title="select an target image or video",
initialdir=RECENT_DIRECTORY_TARGET,
filetypes=[img_ft, vid_ft],
)
@ -651,7 +667,7 @@ def select_output_path(start: Callable[[], None]) -> None:
if is_image(modules.globals.target_path):
output_path = ctk.filedialog.asksaveasfilename(
title=_("save image output file"),
title="save image output file",
filetypes=[img_ft],
defaultextension=".png",
initialfile="output.png",
@ -659,7 +675,7 @@ def select_output_path(start: Callable[[], None]) -> None:
)
elif is_video(modules.globals.target_path):
output_path = ctk.filedialog.asksaveasfilename(
title=_("save video output file"),
title="save video output file",
filetypes=[vid_ft],
defaultextension=".mp4",
initialfile="output.mp4",
@ -962,7 +978,7 @@ def create_source_target_popup_for_webcam(
global POPUP_LIVE, popup_status_label_live
POPUP_LIVE = ctk.CTkToplevel(root)
POPUP_LIVE.title(_("Source x Target Mapper"))
POPUP_LIVE.title("Source x Target Mapper")
POPUP_LIVE.geometry(f"{POPUP_LIVE_WIDTH}x{POPUP_LIVE_HEIGHT}")
POPUP_LIVE.focus()
@ -987,14 +1003,14 @@ def create_source_target_popup_for_webcam(
popup_status_label_live = ctk.CTkLabel(POPUP_LIVE, text=None, justify="center")
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)
clear_button = ctk.CTkButton(POPUP_LIVE, text=_("Clear"), command=lambda: on_clear_click())
clear_button = ctk.CTkButton(POPUP_LIVE, text="Clear", command=lambda: on_clear_click())
clear_button.place(relx=0.4, rely=0.92, relwidth=0.2, relheight=0.05)
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)
@ -1037,7 +1053,7 @@ def refresh_data(map: list):
button = ctk.CTkButton(
scrollable_frame,
text=_("Select source image"),
text="Select source image",
command=lambda id=id: on_sbutton_click(map, id),
width=DEFAULT_BUTTON_WIDTH,
height=DEFAULT_BUTTON_HEIGHT,
@ -1054,7 +1070,7 @@ def refresh_data(map: list):
button = ctk.CTkButton(
scrollable_frame,
text=_("Select target image"),
text="Select target image",
command=lambda id=id: on_tbutton_click(map, id),
width=DEFAULT_BUTTON_WIDTH,
height=DEFAULT_BUTTON_HEIGHT,
@ -1104,7 +1120,7 @@ def update_webcam_source(
global source_label_dict_live
source_path = ctk.filedialog.askopenfilename(
title=_("select an source image"),
title="select an source image",
initialdir=RECENT_DIRECTORY_SOURCE,
filetypes=[img_ft],
)
@ -1156,7 +1172,7 @@ def update_webcam_target(
global target_label_dict_live
target_path = ctk.filedialog.askopenfilename(
title=_("select an target image"),
title="select an target image",
initialdir=RECENT_DIRECTORY_SOURCE,
filetypes=[img_ft],
)
@ -1199,4 +1215,4 @@ 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
return map