HariLogicgo commited on
Commit
91eee68
Β·
1 Parent(s): feb34ce

concurrency increased

Browse files
Files changed (1) hide show
  1. app.py +54 -39
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
- import shutil
3
  import uuid
 
 
4
  import cv2
5
  import numpy as np
6
  import threading
@@ -127,59 +128,73 @@ async def shutdown_db():
127
  logger.info("MongoDB connection closed")
128
 
129
  # -------------------------------------------------
130
- # Lock for face swap
131
  # -------------------------------------------------
132
- swap_lock = threading.Lock()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- # -------------------------------------------------
135
- # Pipeline Function
136
- # -------------------------------------------------
137
- def face_swap_and_enhance(src_img, tgt_img):
138
  try:
139
- with swap_lock:
140
- shutil.rmtree(UPLOAD_DIR, ignore_errors=True)
141
- shutil.rmtree(RESULT_DIR, ignore_errors=True)
142
- os.makedirs(UPLOAD_DIR, exist_ok=True)
143
- os.makedirs(RESULT_DIR, exist_ok=True)
144
 
145
- src_bgr = cv2.cvtColor(src_img, cv2.COLOR_RGB2BGR)
146
- tgt_bgr = cv2.cvtColor(tgt_img, cv2.COLOR_RGB2BGR)
 
 
147
 
148
- src_faces = face_analysis_app.get(src_bgr)
149
- tgt_faces = face_analysis_app.get(tgt_bgr)
150
- if not src_faces or not tgt_faces:
151
- return None, None, "❌ Face not detected in one of the images"
 
152
 
153
- swapped_path = os.path.join(UPLOAD_DIR, f"swapped_{uuid.uuid4().hex[:8]}.jpg")
154
- swapped_bgr = swapper.get(tgt_bgr, tgt_faces[0], src_faces[0])
155
- if swapped_bgr is None:
156
- return None, None, "❌ Face swap failed"
157
 
158
- cv2.imwrite(swapped_path, swapped_bgr)
 
 
159
 
160
- cmd = f"python {CODEFORMER_PATH} -w 0.7 --input_path {swapped_path} --output_path {RESULT_DIR} --bg_upsampler realesrgan --face_upsample"
161
- result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
162
- if result.returncode != 0:
163
- return None, None, f"❌ CodeFormer failed:\n{result.stderr}"
164
 
165
- final_results_dir = os.path.join(RESULT_DIR, "final_results")
166
- final_files = [f for f in os.listdir(final_results_dir) if f.endswith(".png")]
167
- if not final_files:
168
- return None, None, "❌ No enhanced image found"
169
-
170
- final_path = os.path.join(final_results_dir, final_files[0])
171
- final_img = cv2.cvtColor(cv2.imread(final_path), cv2.COLOR_BGR2RGB)
172
-
173
- return final_img, final_path, ""
174
 
175
  except Exception as e:
176
  return None, None, f"❌ Error: {str(e)}"
177
 
 
 
 
 
 
178
  # -------------------------------------------------
179
  # Gradio UI
180
  # -------------------------------------------------
181
  with gr.Blocks() as demo:
182
- gr.Markdown("Face Swap")
183
 
184
  with gr.Row():
185
  src_input = gr.Image(type="numpy", label="Upload Your Face")
@@ -191,7 +206,7 @@ with gr.Blocks() as demo:
191
  error_box = gr.Textbox(label="Logs / Errors", interactive=False)
192
 
193
  def process(src, tgt):
194
- img, path, err = face_swap_and_enhance(src, tgt)
195
  return img, path, err
196
 
197
  btn.click(process, [src_input, tgt_input], [output_img, download, error_box])
@@ -254,7 +269,7 @@ async def perform_faceswap(request: FaceSwapRequest):
254
  src_rgb = cv2.cvtColor(src_bgr, cv2.COLOR_BGR2RGB)
255
  tgt_rgb = cv2.cvtColor(tgt_bgr, cv2.COLOR_BGR2RGB)
256
 
257
- final_img, final_path, err = face_swap_and_enhance(src_rgb, tgt_rgb)
258
  if err:
259
  raise HTTPException(status_code=500, detail=err)
260
 
 
1
  import os
 
2
  import uuid
3
+ import shutil
4
+ import glob
5
  import cv2
6
  import numpy as np
7
  import threading
 
128
  logger.info("MongoDB connection closed")
129
 
130
  # -------------------------------------------------
131
+ # Multi-user safe face swap
132
  # -------------------------------------------------
133
+ MAX_CONCURRENT_SWAPS = 2
134
+ swap_semaphore = threading.Semaphore(MAX_CONCURRENT_SWAPS)
135
+
136
+ def cleanup_old_dirs(base_dir, age_seconds=3600):
137
+ for folder in glob.glob(os.path.join(base_dir, "*")):
138
+ if os.path.isdir(folder):
139
+ try:
140
+ shutil.rmtree(folder, ignore_errors=True)
141
+ except Exception:
142
+ pass
143
+
144
+ def face_swap_and_enhance_multiuser(src_img, tgt_img):
145
+ session_id = uuid.uuid4().hex
146
+ upload_dir = os.path.join(UPLOAD_DIR, session_id)
147
+ result_dir = os.path.join(RESULT_DIR, session_id)
148
+ os.makedirs(upload_dir, exist_ok=True)
149
+ os.makedirs(result_dir, exist_ok=True)
150
+
151
+ # Try acquiring GPU slot
152
+ acquired = swap_semaphore.acquire(blocking=False)
153
+ if not acquired:
154
+ return None, None, "⚠️ GPU is busy. Please try again in a few seconds."
155
 
 
 
 
 
156
  try:
157
+ src_bgr = cv2.cvtColor(src_img, cv2.COLOR_RGB2BGR)
158
+ tgt_bgr = cv2.cvtColor(tgt_img, cv2.COLOR_RGB2BGR)
 
 
 
159
 
160
+ src_faces = face_analysis_app.get(src_bgr)
161
+ tgt_faces = face_analysis_app.get(tgt_bgr)
162
+ if not src_faces or not tgt_faces:
163
+ return None, None, "❌ Face not detected in one of the images"
164
 
165
+ swapped_path = os.path.join(upload_dir, f"swapped_{uuid.uuid4().hex[:8]}.jpg")
166
+ swapped_bgr = swapper.get(tgt_bgr, tgt_faces[0], src_faces[0])
167
+ if swapped_bgr is None:
168
+ return None, None, "❌ Face swap failed"
169
+ cv2.imwrite(swapped_path, swapped_bgr)
170
 
171
+ cmd = f"python {CODEFORMER_PATH} -w 0.7 --input_path {swapped_path} --output_path {result_dir} --bg_upsampler realesrgan --face_upsample"
172
+ result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
173
+ if result.returncode != 0:
174
+ return None, None, f"❌ CodeFormer failed:\n{result.stderr}"
175
 
176
+ final_files = glob.glob(os.path.join(result_dir, "final_results", "*.png"))
177
+ if not final_files:
178
+ return None, None, "❌ No enhanced image found"
179
 
180
+ final_path = final_files[0]
181
+ final_img = cv2.cvtColor(cv2.imread(final_path), cv2.COLOR_BGR2RGB)
 
 
182
 
183
+ return final_img, final_path, ""
 
 
 
 
 
 
 
 
184
 
185
  except Exception as e:
186
  return None, None, f"❌ Error: {str(e)}"
187
 
188
+ finally:
189
+ swap_semaphore.release()
190
+ cleanup_old_dirs(UPLOAD_DIR)
191
+ cleanup_old_dirs(RESULT_DIR)
192
+
193
  # -------------------------------------------------
194
  # Gradio UI
195
  # -------------------------------------------------
196
  with gr.Blocks() as demo:
197
+ gr.Markdown("## Face Swap & Enhancement")
198
 
199
  with gr.Row():
200
  src_input = gr.Image(type="numpy", label="Upload Your Face")
 
206
  error_box = gr.Textbox(label="Logs / Errors", interactive=False)
207
 
208
  def process(src, tgt):
209
+ img, path, err = face_swap_and_enhance_multiuser(src, tgt)
210
  return img, path, err
211
 
212
  btn.click(process, [src_input, tgt_input], [output_img, download, error_box])
 
269
  src_rgb = cv2.cvtColor(src_bgr, cv2.COLOR_BGR2RGB)
270
  tgt_rgb = cv2.cvtColor(tgt_bgr, cv2.COLOR_BGR2RGB)
271
 
272
+ final_img, final_path, err = face_swap_and_enhance_multiuser(src_rgb, tgt_rgb)
273
  if err:
274
  raise HTTPException(status_code=500, detail=err)
275