fangbin commited on
Commit
f4cd92d
·
1 Parent(s): 732af2a
Files changed (4) hide show
  1. Dockerfile +3 -0
  2. app.py +2 -1
  3. modules/core.py +5 -7
  4. modules/ui2.py +132 -0
Dockerfile CHANGED
@@ -35,6 +35,9 @@ ENV MPLCONFIGDIR=/tmp/matplotlib
35
  RUN mkdir -p /.fonts /.config /app/models && \
36
  chmod -R 777 /.fonts /.config /app/models
37
 
 
 
 
38
  # 创建非 root 用户
39
  RUN useradd -m appuser
40
  USER appuser
 
35
  RUN mkdir -p /.fonts /.config /app/models && \
36
  chmod -R 777 /.fonts /.config /app/models
37
 
38
+ RUN mkdir -p /app/flagged && chmod 777 /app/flagged
39
+
40
+
41
  # 创建非 root 用户
42
  RUN useradd -m appuser
43
  USER appuser
app.py CHANGED
@@ -22,7 +22,8 @@ iface = gr.Interface(
22
  ],
23
  outputs=gr.Image(type="filepath", label="Output Image"),
24
  title="Face Swapper",
25
- description="Upload a source face and a target image to swap faces."
 
26
  )
27
 
28
  iface.launch()
 
22
  ],
23
  outputs=gr.Image(type="filepath", label="Output Image"),
24
  title="Face Swapper",
25
+ description="Upload a source face and a target image to swap faces.",
26
+ flagging_dir="/app/flagged"
27
  )
28
 
29
  iface.launch()
modules/core.py CHANGED
@@ -18,6 +18,7 @@ import tensorflow
18
  import modules.globals
19
  import modules.metadata
20
  import modules.ui as ui
 
21
  from modules.processors.frame.core import get_frame_processors_modules
22
  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
23
 
@@ -167,12 +168,9 @@ def pre_check() -> bool:
167
 
168
 
169
  def update_status(message: str, scope: str = 'DLC.CORE') -> None:
170
- if 'DISPLAY' in os.environ:
171
- # GUI 环境
172
  ui.update_status(message)
173
- else:
174
- # 非 GUI 环境
175
- print(f"[{scope}] {message}")
176
 
177
  def start() -> None:
178
  for frame_processor in get_frame_processors_modules(modules.globals.frame_processors):
@@ -254,5 +252,5 @@ def run() -> None:
254
  if modules.globals.headless:
255
  start()
256
  else:
257
- window = ui.init(start, destroy)
258
- window.mainloop()
 
18
  import modules.globals
19
  import modules.metadata
20
  import modules.ui as ui
21
+ import modules.ui2 as ui2
22
  from modules.processors.frame.core import get_frame_processors_modules
23
  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
24
 
 
168
 
169
 
170
  def update_status(message: str, scope: str = 'DLC.CORE') -> None:
171
+ print(f'[{scope}] {message}')
172
+ if not modules.globals.headless:
173
  ui.update_status(message)
 
 
 
174
 
175
  def start() -> None:
176
  for frame_processor in get_frame_processors_modules(modules.globals.frame_processors):
 
252
  if modules.globals.headless:
253
  start()
254
  else:
255
+ demo = ui2.create_ui(start, destroy)
256
+ demo.launch()
modules/ui2.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import webbrowser
3
+ import customtkinter as ctk
4
+ from typing import Callable, Tuple
5
+ import cv2
6
+ from PIL import Image, ImageOps
7
+ import tkinterdnd2 as tkdnd
8
+ import gradio as gr
9
+ import traceback
10
+ import logging
11
+ import io
12
+
13
+ import modules.globals
14
+ import modules.metadata
15
+ from modules.face_analyser import (
16
+ get_one_face,
17
+ get_unique_faces_from_target_image,
18
+ get_unique_faces_from_target_video,
19
+ add_blank_map,
20
+ has_valid_map,
21
+ simplify_maps,
22
+ )
23
+ from modules.capturer import get_video_frame, get_video_frame_total
24
+ from modules.processors.frame.core import get_frame_processors_modules
25
+ from modules.utilities import (
26
+ is_image,
27
+ is_video,
28
+ resolve_relative_path,
29
+ has_image_extension,
30
+ )
31
+ import gradio as gr
32
+
33
+ # 创建一个StringIO对象来捕获日志
34
+ log_capture_string = io.StringIO()
35
+ logging.basicConfig(stream=log_capture_string, level=logging.INFO,
36
+ format='%(asctime)s - %(levelname)s - %(message)s')
37
+
38
+ def create_ui(start, destroy):
39
+ # 使用gr.State来存储文件路径,给予初始值
40
+ source_path = gr.State(value="")
41
+ target_path = gr.State(value="")
42
+
43
+ def process(src_path, tgt_path):
44
+ """
45
+ 处理源图像和目标图像/视频
46
+
47
+ 参数:
48
+ src_path (str): 源图像路径
49
+ tgt_path (str): 目标图像/视频路径
50
+
51
+ 返回:
52
+ tuple: (处理结果信息, 错误日志)
53
+ """
54
+ try:
55
+ if src_path and tgt_path:
56
+ logging.info(f"源路径: {src_path}")
57
+ logging.info(f"目标路径: {tgt_path}")
58
+ modules.globals.source_path = src_path
59
+ modules.globals.target_path = tgt_path
60
+ logging.info("开始处理...")
61
+ start()
62
+ return "处理完成", error_log_capture.getvalue()
63
+ else:
64
+ return "请先选择源图像和目标图像/视频", ""
65
+ except Exception as e:
66
+ error_msg = f"处理过程中出错: {str(e)}\n{traceback.format_exc()}"
67
+ logging.error(error_msg)
68
+ return "处理失败", error_log_capture.getvalue()
69
+
70
+ def update_source(image):
71
+ """
72
+ 更新源图像
73
+
74
+ 参数:
75
+ image (PIL.Image): 上传的图像
76
+
77
+ 返回:
78
+ str: 更新后的源图像路径
79
+ """
80
+ if image is not None:
81
+ temp_path = "temp_source.png"
82
+ image.save(temp_path)
83
+ return temp_path
84
+ return ""
85
+
86
+ def update_target(file):
87
+ """
88
+ 更新目标文件并生成预览
89
+
90
+ 参数:
91
+ file (UploadedFile): 上传的文件对象
92
+
93
+ 返回:
94
+ tuple: (文件路径, 预览图像路径, 预览可见性更新)
95
+ """
96
+ if file is not None:
97
+ file_path = file.name
98
+ if is_image(file_path):
99
+ return file_path, file_path, gr.update(visible=True)
100
+ elif is_video(file_path):
101
+ video = cv2.VideoCapture(file_path)
102
+ success, frame = video.read()
103
+ if success:
104
+ preview_path = "temp_preview.jpg"
105
+ cv2.imwrite(preview_path, frame)
106
+ video.release()
107
+ return file_path, preview_path, gr.update(visible=True)
108
+ return "", None, gr.update(visible=False)
109
+
110
+ # 创建Gradio界面
111
+ with gr.Blocks() as demo:
112
+ gr.Markdown("# 人脸交换")
113
+
114
+ with gr.Row():
115
+ source_image = gr.Image(label="源图像", type="pil", elem_id="source_image")
116
+ target_file = gr.File(label="目标图像/视频", elem_id="target_file")
117
+
118
+ target_preview = gr.Image(label="目标预览", visible=False, elem_id="target_preview")
119
+
120
+ process_btn = gr.Button("开始处理", elem_id="process_btn")
121
+
122
+ output = gr.Textbox(label="输出信息", elem_id="output")
123
+
124
+ # 错误日志显示区域
125
+ error_log_output = gr.Textbox(label="错误日志", lines=5, elem_id="error_log")
126
+
127
+ # 设置组件事件
128
+ source_image.change(update_source, inputs=[source_image], outputs=[source_path])
129
+ target_file.change(update_target, inputs=[target_file], outputs=[target_path, target_preview, target_preview])
130
+ process_btn.click(process, inputs=[source_path, target_path], outputs=[output, error_log_output])
131
+
132
+ return demo