ssboost commited on
Commit
8b2504d
ยท
verified ยท
1 Parent(s): f8f2937

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +145 -39
app.py CHANGED
@@ -6,7 +6,12 @@ import gfpgan
6
  import tempfile
7
  import time
8
  import gradio as gr
 
 
 
9
 
 
 
10
 
11
  class Predictor:
12
  def __init__(self):
@@ -23,63 +28,164 @@ class Predictor:
23
  os.system(
24
  'wget https://huggingface.co/ashleykleynhans/inswapper/resolve/main/inswapper_128.onnx'
25
  )
26
- os.chdir('..')
27
 
28
- """Load the model into memory to make running multiple predictions efficient"""
29
  self.face_swapper = insightface.model_zoo.get_model('models/inswapper_128.onnx',
30
  providers=onnxruntime.get_available_providers())
 
 
31
  self.face_enhancer = gfpgan.GFPGANer(model_path='models/GFPGANv1.4.pth', upscale=1)
32
  self.face_analyser = insightface.app.FaceAnalysis(name='buffalo_l')
33
  self.face_analyser.prepare(ctx_id=0, det_size=(640, 640))
34
 
35
- def get_face(self, img_data):
36
- analysed = self.face_analyser.get(img_data)
37
- try:
38
- largest = max(analysed, key=lambda x: (x.bbox[2] - x.bbox[0]) * (x.bbox[3] - x.bbox[1]))
39
- return largest
40
- except:
41
- print("No face found")
42
- return None
43
 
44
- def predict(self, input_image, swap_image):
45
- """Run a single prediction on the model"""
46
  try:
47
- frame = cv2.imread(input_image.name)
48
- face = self.get_face(frame)
49
- source_face = self.get_face(cv2.imread(swap_image.name))
50
- try:
51
- print(frame.shape, face.shape, source_face.shape)
52
- except:
53
- print("printing shapes failed.")
54
- result = self.face_swapper.get(frame, face, source_face, paste_back=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
 
56
  _, _, result = self.face_enhancer.enhance(
57
  result,
58
  paste_back=True
59
  )
60
- out_path = tempfile.mkdtemp() + f"/{str(int(time.time()))}.jpg"
61
  cv2.imwrite(out_path, result)
62
  return out_path
63
  except Exception as e:
64
  print(f"{e}")
65
  return None
66
 
67
-
68
- # Instantiate the Predictor class
69
  predictor = Predictor()
70
- title = "Swap Faces Using Our Model!!!"
71
-
72
- # Create Gradio Interface
73
- iface = gr.Interface(
74
- fn=predictor.predict,
75
- inputs=[
76
- gr.Image(type="filepath", label="Target Image"),
77
- gr.Image(type="filepath", label="Swap Image")
78
- ],
79
- outputs=gr.Image(type="filepath", label="Result"),
80
- title=title,
81
- examples=[["input.jpg", "swap img.jpg"]])
82
-
83
-
84
- # Launch the Gradio Interface
85
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  import tempfile
7
  import time
8
  import gradio as gr
9
+ import sys
10
+ from torchvision.transforms import functional
11
+ from PIL import Image
12
 
13
+ # ์ฐธ์กฐ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋œ ๋ชจ๋“ˆ ์ž„ํฌํŠธ ์ˆ˜์ •
14
+ sys.modules["torchvision.transforms.functional_tensor"] = functional
15
 
16
  class Predictor:
17
  def __init__(self):
 
28
  os.system(
29
  'wget https://huggingface.co/ashleykleynhans/inswapper/resolve/main/inswapper_128.onnx'
30
  )
31
+ os.chdir('..') # ๋””๋ ‰ํ† ๋ฆฌ ๋ณ€๊ฒฝ ์™„๋ฃŒ
32
 
33
+ """๐Ÿ’Ž Load the model into memory to make running multiple predictions efficient"""
34
  self.face_swapper = insightface.model_zoo.get_model('models/inswapper_128.onnx',
35
  providers=onnxruntime.get_available_providers())
36
+ # self.face_swapper.prepare(ctx_id=0, det_size=(640, 640)) # ์ด ์ค„์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
37
+
38
  self.face_enhancer = gfpgan.GFPGANer(model_path='models/GFPGANv1.4.pth', upscale=1)
39
  self.face_analyser = insightface.app.FaceAnalysis(name='buffalo_l')
40
  self.face_analyser.prepare(ctx_id=0, det_size=(640, 640))
41
 
42
+ def get_face_image(self, img_data, face):
43
+ # ์–ผ๊ตด ์˜์—ญ์„ ์ž˜๋ผ๋‚ด๊ธฐ
44
+ x1, y1, x2, y2 = [int(coord) for coord in face.bbox]
45
+ face_img = img_data[y1:y2, x1:x2]
46
+ return face_img
 
 
 
47
 
48
+ def predict(self, input_image_path, swap_image_path):
49
+ """๐Ÿงถ Run a single prediction on the model"""
50
  try:
51
+ frame = cv2.imread(input_image_path)
52
+ if frame is None:
53
+ print("โŒ Target image could not be read.")
54
+ return None
55
+ analysed = self.face_analyser.get(frame)
56
+ if not analysed:
57
+ print("โŒ No face found in target image.")
58
+ return None
59
+ face = max(analysed, key=lambda x: (x.bbox[2] - x.bbox[0]) * (x.bbox[3] - x.bbox[1]))
60
+ target_face_img = self.get_face_image(frame, face)
61
+
62
+ swap_frame = cv2.imread(swap_image_path)
63
+ if swap_frame is None:
64
+ print("โŒ Swap image could not be read.")
65
+ return None
66
+ swap_analysed = self.face_analyser.get(swap_frame)
67
+ if not swap_analysed:
68
+ print("โŒ No face found in swap image.")
69
+ return None
70
+ swap_face = max(swap_analysed, key=lambda x: (x.bbox[2] - x.bbox[0]) * (x.bbox[3] - x.bbox[1]))
71
+ swap_face_img = self.get_face_image(swap_frame, swap_face)
72
+
73
+ # ์–ผ๊ตด ๊ต์ฒด ์ˆ˜ํ–‰
74
+ result = self.face_swapper.get(frame, face, swap_face, paste_back=True)
75
 
76
+ # ์–ผ๊ตด ํ–ฅ์ƒ ์ˆ˜ํ–‰
77
  _, _, result = self.face_enhancer.enhance(
78
  result,
79
  paste_back=True
80
  )
81
+ out_path = os.path.join(tempfile.mkdtemp(), f"{str(int(time.time()))}.jpg")
82
  cv2.imwrite(out_path, result)
83
  return out_path
84
  except Exception as e:
85
  print(f"{e}")
86
  return None
87
 
88
+ # Predictor ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
 
89
  predictor = Predictor()
90
+
91
+ # CSS ๋ฐ ํ…Œ๋งˆ ์„ค์ •
92
+ css = """
93
+ /* "Swap Faces" ๋ฒ„ํŠผ ์Šคํƒ€์ผ */
94
+ button#swap-button {
95
+ background-color: #FB923C !important; /* ์ฃผํ™ฉ์ƒ‰ ๋ฐฐ๊ฒฝ */
96
+ color: white !important; /* ํฐ์ƒ‰ ๊ธ€์”จ */
97
+ }
98
+ /* "์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ (JPG)" ๋ฒ„ํŠผ ์Šคํƒ€์ผ */
99
+ button#download-button {
100
+ background-color: #FB923C !important; /* ์ฃผํ™ฉ์ƒ‰ ๋ฐฐ๊ฒฝ */
101
+ color: white !important; /* ํฐ์ƒ‰ ๊ธ€์”จ */
102
+ }
103
+ /* ํ•„์š”์— ๋”ฐ๋ผ ์ถ”๊ฐ€์ ์ธ ์Šคํƒ€์ผ์„ ์—ฌ๊ธฐ์— ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค */
104
+ """
105
+
106
+ demo_theme = gr.themes.Soft(
107
+ primary_hue=gr.themes.Color(
108
+ c50="#FFF7ED",
109
+ c100="#FFEDD5",
110
+ c200="#FED7AA",
111
+ c300="#FDBA74",
112
+ c400="#FB923C",
113
+ c500="#F97316",
114
+ c600="#EA580C",
115
+ c700="#C2410C",
116
+ c800="#9A3412",
117
+ c900="#7C2D12",
118
+ c950="#431407",
119
+ ),
120
+ secondary_hue="zinc",
121
+ neutral_hue="zinc",
122
+ font=("Pretendard", "sans-serif")
123
+ )
124
+
125
+ # JPG ๋‹ค์šด๋กœ๋“œ ๊ธฐ๋Šฅ ๊ตฌํ˜„
126
+ def save_as_jpg(file_path):
127
+ try:
128
+ if file_path is None:
129
+ return None
130
+ # ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋ฐ›์•„ PIL ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜
131
+ img = Image.open(file_path)
132
+ with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tmp:
133
+ img.save(tmp, format="JPEG")
134
+ tmp_path = tmp.name
135
+ return tmp_path # ํŒŒ์ผ ๊ฒฝ๋กœ ๋ฐ˜ํ™˜
136
+ except Exception as error:
137
+ print(f"Error saving as JPG: {error}")
138
+ return None
139
+
140
+ # Clear ํ•จ์ˆ˜: ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์ดˆ๊ธฐํ™”
141
+ def clear_all():
142
+ return [None, None, None]
143
+
144
+ # Gradio Interface ๊ตฌ์„ฑ
145
+ with gr.Blocks(theme=demo_theme, css=css) as demo:
146
+ with gr.Row():
147
+ # ์™ผ์ชฝ ์„น์…˜: ์ž…๋ ฅ
148
+ with gr.Column(scale=1):
149
+ target_image = gr.Image(
150
+ type="filepath",
151
+ label="์–ผ๊ตด์„ ๋ณ€๊ฒฝํ•  ์ด๋ฏธ์ง€"
152
+ )
153
+ swap_image = gr.Image(
154
+ type="filepath",
155
+ label="๊ต์ฒดํ•  ์–ผ๊ตด"
156
+ )
157
+ swap_button = gr.Button("์–ผ๊ตด ๊ต์ฒด", elem_id="swap-button")
158
+ clear_button = gr.Button("๋ฆฌ์…‹ํ•˜๊ธฐ")
159
+
160
+ # ์˜ค๋ฅธ์ชฝ ์„น์…˜: ์ถœ๋ ฅ
161
+ with gr.Column(scale=1):
162
+ result_image = gr.Image(
163
+ type="filepath",
164
+ label="๊ฒฐ๊ณผ ์ด๋ฏธ์ง€"
165
+ )
166
+ download_jpg_button = gr.Button("JPG๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ", elem_id="download-button")
167
+ download_file = gr.File(label="JPG ์ด๋ฏธ์ง€ ๋‹ค์šด๋ฐ›๊ธฐ")
168
+
169
+ # ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์˜ˆ์ธก ํ•จ์ˆ˜ ํ˜ธ์ถœ
170
+ swap_button.click(
171
+ fn=predictor.predict,
172
+ inputs=[target_image, swap_image],
173
+ outputs=result_image
174
+ )
175
+
176
+ # ๋ฆฌ์…‹ํ•˜๊ธฐ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์ด๋ฏธ์ง€ ์ดˆ๊ธฐํ™”
177
+ clear_button.click(
178
+ fn=clear_all,
179
+ inputs=None,
180
+ outputs=[target_image, swap_image, result_image]
181
+ )
182
+
183
+ # JPG ๋‹ค์šด๋กœ๋“œ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํŒŒ์ผ ์ƒ์„ฑ
184
+ download_jpg_button.click(
185
+ fn=save_as_jpg,
186
+ inputs=result_image,
187
+ outputs=download_file
188
+ )
189
+
190
+ # Gradio Interface ์‹คํ–‰
191
+ demo.launch()