diff --git a/README-Fixed.md b/README-Fixed.md new file mode 100644 index 0000000..4716e17 --- /dev/null +++ b/README-Fixed.md @@ -0,0 +1,139 @@ +**免责声明** + +**这个分支经过 NITSC 的修改,只经过我们(NITSC)的电脑验证,没有经过大众验证。** +这款软件旨在为蓬勃发展的AI生成媒体行业做出积极贡献,帮助艺术家完成动画自定义角色、使用角色作为服装模型等任务。 +开发人员意识到该软件可能存在不道德的应用,并承诺采取预防措施。它内置了检查功能,防止程序在包括裸露、图形内容、战争画面等在内的不适当媒体上运行。我们将继续积极开发该项目,并遵守法律和道德规范。如果法律要求,该项目可能会关闭或在输出中包含水印。 +用户应负责任地使用该软件,并遵守当地法律。如果使用真实人物的面孔,建议用户从相关人员那里获得许可,并在在线发布内容时明确说明这是深度伪造视频。该软件的开发人员不承担最终用户行为的责任。 + +**如何安装**? +### 基本安装 (CPU) +1. **设置平台**: + - python (推荐使用 3.10) + - pip + - git + - [ffmpeg](https://www.youtube.com/watch?v=OlNWCpFdVMA) + - [visual studio 2022 runtimes (windows)](https://visualstudio.microsoft.com/visual-cpp-build-tools/) + - C:\Users\<用户名>\.keras\keras.json 改为以下内容: + ``` + { + "image_data_format": "channels_last", + "epsilon": 1e-07, + "floatx": "float32", + "backend": "tensorflow" + } + ``` +2. **克隆仓库**: + ``` + https://github.com/hacksider/Deep-Live-Cam.git + ``` +3. **下载模型**: + 1. [GFPGANv1.4](https://huggingface.co/hacksider/deep-live-cam/resolve/main/GFPGANv1.4.pth) + 2. [inswapper_128_fp16.onnx](https://huggingface.co/hacksider/deep-live-cam/resolve/main/inswapper_128_fp16.onnx) + 然后将这两个文件放在“**models**”文件夹中。 +4. **安装依赖项**: + 我们强烈建议使用 `venv` 以避免问题。 + + (适用于 Python3.12.x) + ``` + pip install -r requirements.txt + ``` + (适用于 Python3.10.x) + ``` + pip install -r orginal_requirements.txt + ``` + 完成 !!! 如果您没有 GPU,您应该能够使用 `python run.py` 命令运行 roop。请注意,在首次运行程序时,它将下载一些模型,这可能会根据您的网络连接花费一些时间。 +### GPU 加速 +#### CUDA 执行提供程序 (Nvidia) +1. 安装 [CUDA Toolkit 11.8](https://developer.nvidia.com/cuda-11-8-0-download-archive) + +2. 安装依赖项: + ``` + pip uninstall onnxruntime onnxruntime-gpu + pip install onnxruntime-gpu==1.16.3 + ``` +3. 如果提供程序可用,则使用: + ``` + python run.py --execution-provider cuda + ``` +#### CoreML 执行提供程序 (Apple Silicon) +1. 安装依赖项: + ``` + pip uninstall onnxruntime onnxruntime-silicon + pip install onnxruntime-silicon==1.13.1 + ``` +2. 如果提供程序可用,则使用: + ``` + python run.py --execution-provider coreml + ``` +#### CoreML 执行提供程序 (Apple Legacy) +1. 安装依赖项: + ``` + pip uninstall onnxruntime onnxruntime-coreml + pip install onnxruntime-coreml==1.13.1 + ``` +2. 如果提供程序可用,则使用: + ``` + python run.py --execution-provider coreml + ``` +#### DirectML 执行提供程序 (Windows) +1. 安装依赖项: + ``` + pip uninstall onnxruntime onnxruntime-directml + pip install onnxruntime-directml==1.15.1 + ``` +2. 如果提供程序可用,则使用: + ``` + python run.py --execution-provider dml + ``` +#### OpenVINO™ 执行提供程序 (Intel) +1. 安装依赖项: + ``` + pip uninstall onnxruntime onnxruntime-openvino + pip install onnxruntime-openvino==1.15.0 + ``` +2. 如果提供程序可用,则使用: + ``` + python run.py --execution-provider openvino + ``` +**如何使用**? +> 注意:首次运行此程序时,它将下载一些模型,大小约为 300MB。 +执行 `python run.py` 命令将启动以下窗口: +![gui-demo](instruction.png) +选择一个面部 (包含所需面部的图像) 和目标图像/视频 (您想要替换面部的图像/视频),然后单击“开始”。打开文件资源管理器,导航到您选择的输出目录。您将找到名为 `` 的目录,其中可以实时查看交换的帧。处理完成后,它将创建输出文件。就这样。 +**网络摄像头模式** +只需按照屏幕截图上的步骤操作: +1. 选择一个面部 +2. 单击“实时” +3. 等待几秒钟 (通常需要 10 到 30 秒才能显示预览) +![demo-gif](demo.gif) +只需使用您喜欢的屏幕录制软件进行直播,例如 OBS。 +> 注意:如果您想更改您的面部,只需选择另一张图片,预览模式将重新启动 (所以只需等待一会儿)。 +以下是一些额外的命令行参数。要了解它们的功能,请查看 [此指南](https://github.com/s0md3v/roop/wiki/Advanced-Options)。 +``` +options: + -h, --help 显示此帮助消息并退出 + -s SOURCE_PATH, --source SOURCE_PATH 选择源图像 + -t TARGET_PATH, --target TARGET_PATH 选择目标图像或视频 + -o OUTPUT_PATH, --output OUTPUT_PATH 选择输出文件或目录 + --frame-processor FRAME_PROCESSOR [FRAME_PROCESSOR ...] 帧处理器 (choices: face_swapper, face_enhancer, ...) + --keep-fps 保持原始 fps + --keep-audio 保持原始音频 + --keep-frames 保留临时帧 + --many-faces 处理每个面部 + --video-encoder {libx264,libx265,libvpx-vp9} 调整输出视频编码器 + --video-quality [0-51] 调整输出视频质量 + --max-memory MAX_MEMORY 最大 RAM 量 (GB) + --execution-provider {cpu} [{cpu} ...] 可用的执行提供程序 (choices: cpu, ...) + --execution-threads EXECUTION_THREADS 执行线程数 + -v, --version 显示程序的版本号并退出 +``` +想要 CLI 模式?使用 -s/--source 参数将使 run 程序以 CLI 模式运行。 +**想要立即获得下一个更新**? +如果您想要最新的构建版本或想体验一些新的功能,请转到我们的 [experimental branch](https://github.com/hacksider/Deep-Live-Cam/tree/experimental) 并体验贡献者带来的功能。 +**致谢** +- [ffmpeg](https://ffmpeg.org/): 让视频相关操作变得容易 +- [deepinsight](https://github.com/deepinsight): 他们的 [insightface](https://github.com/deepinsight/insightface) 项目提供了一个制作精良的库和模型。 +- [havok2-htwo](https://github.com/havok2-htwo) : 分享用于网络摄像头的代码 +- [GosuDRM](https://github.com/GosuDRM/nsfw-roop) : 解除 roop 的审查 +- 以及 [所有开发者](https://github.com/hacksider/Deep-Live-Cam/graphs/contributors) 在该项目中使用的库背后的所有开发者。 +- 脚注:[这原本是 roop-cam,请在此处查看代码的完整历史。](https://github.com/hacksider/roop-cam) 请注意,代码的基础作者是 [s0md3v](https://github.com/s0md3v/roop) diff --git a/modules/ui.py b/modules/ui.py index 1d0bb69..dd5c71b 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -61,47 +61,47 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C target_label = ctk.CTkLabel(root, text=None) target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25) - source_button = ctk.CTkButton(root, text='Select a face', cursor='hand2', command=lambda: select_source_path()) + source_button = ctk.CTkButton(root, text='选择一个面部', cursor='hand2', command=lambda: select_source_path()) source_button.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1) - target_button = ctk.CTkButton(root, text='Select a target', cursor='hand2', command=lambda: select_target_path()) + target_button = ctk.CTkButton(root, text='选择一个目标', cursor='hand2', command=lambda: select_target_path()) target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1) keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps) - keep_fps_checkbox = ctk.CTkSwitch(root, text='Keep fps', variable=keep_fps_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_fps', not modules.globals.keep_fps)) + keep_fps_checkbox = ctk.CTkSwitch(root, text='保持帧率', variable=keep_fps_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_fps', not modules.globals.keep_fps)) keep_fps_checkbox.place(relx=0.1, rely=0.6) keep_frames_value = ctk.BooleanVar(value=modules.globals.keep_frames) - keep_frames_switch = ctk.CTkSwitch(root, text='Keep frames', variable=keep_frames_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_frames', keep_frames_value.get())) + keep_frames_switch = ctk.CTkSwitch(root, text='保留镜框', variable=keep_frames_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_frames', keep_frames_value.get())) keep_frames_switch.place(relx=0.1, rely=0.65) # for FRAME PROCESSOR ENHANCER tumbler: enhancer_value = ctk.BooleanVar(value=modules.globals.fp_ui['face_enhancer']) - enhancer_switch = ctk.CTkSwitch(root, text='Face Enhancer', variable=enhancer_value, cursor='hand2', command=lambda: update_tumbler('face_enhancer',enhancer_value.get())) + enhancer_switch = ctk.CTkSwitch(root, text='面部优化', variable=enhancer_value, cursor='hand2', command=lambda: update_tumbler('face_enhancer',enhancer_value.get())) enhancer_switch.place(relx=0.1, rely=0.7) keep_audio_value = ctk.BooleanVar(value=modules.globals.keep_audio) - keep_audio_switch = ctk.CTkSwitch(root, text='Keep audio', variable=keep_audio_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_audio', keep_audio_value.get())) + keep_audio_switch = ctk.CTkSwitch(root, text='保留音频', variable=keep_audio_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_audio', keep_audio_value.get())) keep_audio_switch.place(relx=0.6, rely=0.6) many_faces_value = ctk.BooleanVar(value=modules.globals.many_faces) - many_faces_switch = ctk.CTkSwitch(root, text='Many faces', variable=many_faces_value, cursor='hand2', command=lambda: setattr(modules.globals, 'many_faces', many_faces_value.get())) + many_faces_switch = ctk.CTkSwitch(root, text='多脸', variable=many_faces_value, cursor='hand2', command=lambda: setattr(modules.globals, 'many_faces', many_faces_value.get())) many_faces_switch.place(relx=0.6, rely=0.65) nsfw_value = ctk.BooleanVar(value=modules.globals.nsfw) nsfw_switch = ctk.CTkSwitch(root, text='NSFW', variable=nsfw_value, cursor='hand2', command=lambda: setattr(modules.globals, 'nsfw', nsfw_value.get())) nsfw_switch.place(relx=0.6, rely=0.7) - start_button = ctk.CTkButton(root, text='Start', cursor='hand2', command=lambda: select_output_path(start)) + start_button = ctk.CTkButton(root, text='开始', cursor='hand2', command=lambda: select_output_path(start)) 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()) + stop_button = ctk.CTkButton(root, text='关闭', 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()) + preview_button = ctk.CTkButton(root, text='预览', cursor='hand2', command=lambda: toggle_preview()) preview_button.place(relx=0.65, rely=0.80, relwidth=0.2, relheight=0.05) - live_button = ctk.CTkButton(root, text='Live', cursor='hand2', command=lambda: webcam_preview()) + live_button = ctk.CTkButton(root, text='实时', cursor='hand2', command=lambda: webcam_preview()) live_button.place(relx=0.40, rely=0.86, relwidth=0.2, relheight=0.05) status_label = ctk.CTkLabel(root, text=None, justify='center') @@ -120,7 +120,7 @@ def create_preview(parent: ctk.CTkToplevel) -> ctk.CTkToplevel: preview = ctk.CTkToplevel(parent) preview.withdraw() - preview.title('Preview') + preview.title('预览') preview.configure() preview.protocol('WM_DELETE_WINDOW', lambda: toggle_preview()) preview.resizable(width=False, height=False) @@ -146,7 +146,7 @@ def select_source_path() -> None: global RECENT_DIRECTORY_SOURCE, img_ft, vid_ft PREVIEW.withdraw() - source_path = ctk.filedialog.askopenfilename(title='select an source image', initialdir=RECENT_DIRECTORY_SOURCE, filetypes=[img_ft]) + source_path = ctk.filedialog.askopenfilename(title='选择源图像', initialdir=RECENT_DIRECTORY_SOURCE, filetypes=[img_ft]) if is_image(source_path): modules.globals.source_path = source_path RECENT_DIRECTORY_SOURCE = os.path.dirname(modules.globals.source_path) @@ -161,7 +161,7 @@ def select_target_path() -> None: global RECENT_DIRECTORY_TARGET, img_ft, vid_ft PREVIEW.withdraw() - target_path = ctk.filedialog.askopenfilename(title='select an target image or video', initialdir=RECENT_DIRECTORY_TARGET, filetypes=[img_ft, vid_ft]) + target_path = ctk.filedialog.askopenfilename(title='选择目标图像或视频', initialdir=RECENT_DIRECTORY_TARGET, filetypes=[img_ft, vid_ft]) if is_image(target_path): modules.globals.target_path = target_path RECENT_DIRECTORY_TARGET = os.path.dirname(modules.globals.target_path) @@ -181,9 +181,9 @@ def select_output_path(start: Callable[[], None]) -> None: global RECENT_DIRECTORY_OUTPUT, img_ft, vid_ft if is_image(modules.globals.target_path): - output_path = ctk.filedialog.asksaveasfilename(title='save image output file', filetypes=[img_ft], defaultextension='.png', initialfile='output.png', initialdir=RECENT_DIRECTORY_OUTPUT) + output_path = ctk.filedialog.asksaveasfilename(title='保存输出图像', filetypes=[img_ft], defaultextension='.png', initialfile='output.png', initialdir=RECENT_DIRECTORY_OUTPUT) elif is_video(modules.globals.target_path): - output_path = ctk.filedialog.asksaveasfilename(title='save video output file', filetypes=[vid_ft], defaultextension='.mp4', initialfile='output.mp4', initialdir=RECENT_DIRECTORY_OUTPUT) + output_path = ctk.filedialog.asksaveasfilename(title='保存输出视频', filetypes=[vid_ft], defaultextension='.mp4', initialfile='output.mp4', initialdir=RECENT_DIRECTORY_OUTPUT) else: output_path = None if output_path: diff --git a/orginal_requirements.txt b/orginal_requirements.txt new file mode 100644 index 0000000..f65195e --- /dev/null +++ b/orginal_requirements.txt @@ -0,0 +1,23 @@ +--extra-index-url https://download.pytorch.org/whl/cu118 + +numpy==1.23.5 +opencv-python==4.8.1.78 +onnx==1.16.0 +insightface==0.7.3 +psutil==5.9.8 +tk==0.1.0 +customtkinter==5.2.2 +pillow==9.5.0 +torch==2.0.1+cu118; sys_platform != 'darwin' +torch==2.0.1; sys_platform == 'darwin' +torchvision==0.15.2+cu118; sys_platform != 'darwin' +torchvision==0.15.2; sys_platform == 'darwin' +onnxruntime==1.18.0; sys_platform == 'darwin' and platform_machine != 'arm64' +onnxruntime-silicon==1.16.3; sys_platform == 'darwin' and platform_machine == 'arm64' +onnxruntime-gpu==1.18.0; sys_platform != 'darwin' +tensorflow==2.13.0rc1; sys_platform == 'darwin' +tensorflow==2.12.1; sys_platform != 'darwin' +opennsfw2==0.10.2 +protobuf==4.23.2 +tqdm==4.66.4 +gfpgan==1.3.8 diff --git a/requirements.txt b/requirements.txt index f65195e..fcbeff7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,23 +1,108 @@ ---extra-index-url https://download.pytorch.org/whl/cu118 - -numpy==1.23.5 -opencv-python==4.8.1.78 -onnx==1.16.0 -insightface==0.7.3 -psutil==5.9.8 -tk==0.1.0 +absl-py==2.1.0 +addict==2.4.0 +albucore==0.0.13 +albumentations==1.4.13 +annotated-types==0.7.0 +astunparse==1.6.3 +basicsr==1.4.2 +beautifulsoup4==4.12.3 +certifi==2024.7.4 +charset-normalizer==3.3.2 +colorama==0.4.6 +coloredlogs==15.0.1 +contourpy==1.2.1 customtkinter==5.2.2 -pillow==9.5.0 -torch==2.0.1+cu118; sys_platform != 'darwin' -torch==2.0.1; sys_platform == 'darwin' -torchvision==0.15.2+cu118; sys_platform != 'darwin' -torchvision==0.15.2; sys_platform == 'darwin' -onnxruntime==1.18.0; sys_platform == 'darwin' and platform_machine != 'arm64' -onnxruntime-silicon==1.16.3; sys_platform == 'darwin' and platform_machine == 'arm64' -onnxruntime-gpu==1.18.0; sys_platform != 'darwin' -tensorflow==2.13.0rc1; sys_platform == 'darwin' -tensorflow==2.12.1; sys_platform != 'darwin' -opennsfw2==0.10.2 -protobuf==4.23.2 -tqdm==4.66.4 +cycler==0.12.1 +Cython==3.0.11 +darkdetect==0.8.0 +easydict==1.13 +eval_type_backport==0.2.0 +facexlib==0.3.0 +filelock==3.15.4 +filterpy==1.4.5 +flatbuffers==24.3.25 +fonttools==4.53.1 +fsspec==2024.6.1 +future==1.0.0 +gast==0.6.0 +gdown==5.2.0 gfpgan==1.3.8 +google-pasta==0.2.0 +grpcio==1.65.4 +h5py==3.11.0 +humanfriendly==10.0 +idna==3.7 +imageio==2.34.2 +importlib_metadata==8.2.0 +insightface==0.7.3 +Jinja2==3.1.4 +joblib==1.4.2 +keras==3.5.0 +kiwisolver==1.4.5 +lazy_loader==0.4 +libclang==18.1.1 +llvmlite==0.43.0 +lmdb==1.5.1 +Markdown==3.6 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +matplotlib==3.9.1.post1 +mdurl==0.1.2 +ml-dtypes==0.4.0 +mpmath==1.3.0 +namex==0.0.8 +networkx==3.3 +numba==0.60.0 +numpy==1.26.4 +onnx==1.16.0 +onnxruntime==1.18.0 +opencv-python==4.8.1.78 +opencv-python-headless==4.10.0.84 +opennsfw2==0.10.2 +opt-einsum==3.3.0 +optree==0.12.1 +packaging==24.1 +Pillow==9.5.0 +platformdirs==4.2.2 +prettytable==3.11.0 +protobuf==4.23.2 +psutil==5.9.8 +pydantic==2.8.2 +pydantic_core==2.20.1 +Pygments==2.18.0 +pyparsing==3.1.2 +pyreadline3==3.4.1 +PySocks==1.7.1 +python-dateutil==2.9.0.post0 +PyYAML==6.0.2 +realesrgan==0.3.0 +requests==2.32.3 +rich==13.7.1 +scikit-image==0.24.0 +scikit-learn==1.5.1 +scipy==1.14.0 +setuptools==72.1.0 +six==1.16.0 +soupsieve==2.5 +sympy==1.13.2 +tb-nightly==2.18.0a20240812 +tensorboard==2.17.0 +tensorboard-data-server==0.7.2 +tensorflow==2.17.0 +tensorflow-intel==2.17.0 +termcolor==2.4.0 +threadpoolctl==3.5.0 +tifffile==2024.8.10 +tk==0.1.0 +tomli==2.0.1 +torch==2.2.0 +torchvision==0.17.0 +tqdm==4.66.4 +typing_extensions==4.12.2 +urllib3==2.2.2 +wcwidth==0.2.13 +Werkzeug==3.0.3 +wheel==0.44.0 +wrapt==1.16.0 +yapf==0.40.2 +zipp==3.20.0 diff --git a/run.py b/run.py index 31bc6da..95d679c 100644 --- a/run.py +++ b/run.py @@ -2,5 +2,8 @@ from modules import core +import os +os.environ['KERAS_BACKEND'] = 'tensorflow' + if __name__ == '__main__': core.run()