HariLogicgo commited on
Commit
8c09773
Β·
1 Parent(s): d8fb1f1

app.py revised with endpoints

Browse files
Files changed (2) hide show
  1. app.py +65 -27
  2. requirements.txt +4 -0
app.py CHANGED
@@ -1,14 +1,20 @@
1
  import os
2
  os.environ["OMP_NUM_THREADS"] = "1"
3
- import gradio as gr
4
  import cv2
5
  import shutil
6
  import uuid
 
 
7
  import insightface
8
  from insightface.app import FaceAnalysis
9
  from huggingface_hub import hf_hub_download
10
- import subprocess
11
-
 
 
 
 
12
 
13
  # -------------------------------------------------
14
  # Paths
@@ -50,8 +56,8 @@ for f in buffalo_files:
50
  # -------------------------------------------------
51
  # Initialize face analysis and swapper
52
  # -------------------------------------------------
53
- app = FaceAnalysis(name="buffalo_l", root=MODELS_DIR, providers=['CPUExecutionProvider'])
54
- app.prepare(ctx_id=0, det_size=(640, 640))
55
  swapper = insightface.model_zoo.get_model(inswapper_path, providers=['CPUExecutionProvider'])
56
 
57
  # -------------------------------------------------
@@ -72,74 +78,106 @@ ensure_codeformer()
72
  # -------------------------------------------------
73
  # Pipeline Function
74
  # -------------------------------------------------
75
- # -------------------------------------------------
76
- # Pipeline Function (defaults applied)
77
- # -------------------------------------------------
78
  def face_swap_and_enhance(src_img, tgt_img):
79
  try:
80
  src_bgr = cv2.cvtColor(src_img, cv2.COLOR_RGB2BGR)
81
  tgt_bgr = cv2.cvtColor(tgt_img, cv2.COLOR_RGB2BGR)
82
 
83
- src_faces = app.get(src_bgr)
84
- tgt_faces = app.get(tgt_bgr)
85
  if not src_faces or not tgt_faces:
86
- return None, None, "❌ Face not detected in one of the images."
87
 
88
  shutil.rmtree(UPLOAD_DIR, ignore_errors=True)
89
  shutil.rmtree(RESULT_DIR, ignore_errors=True)
90
  os.makedirs(UPLOAD_DIR, exist_ok=True)
91
  os.makedirs(RESULT_DIR, exist_ok=True)
92
 
93
- # ---------------- Save swapped face ----------------
94
  unique_name = f"swapped_{uuid.uuid4().hex[:8]}.jpg"
95
  swapped_path = os.path.join(UPLOAD_DIR, unique_name)
96
  swapped_bgr = swapper.get(tgt_bgr, tgt_faces[0], src_faces[0])
97
  cv2.imwrite(swapped_path, swapped_bgr)
98
 
99
- # ---------------- Run CodeFormer ----------------
100
  cmd = f"python {CODEFORMER_PATH} -w 0.7 --input_path {swapped_path} --output_path {RESULT_DIR} --bg_upsampler realesrgan --face_upsample"
101
  result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
102
  if result.returncode != 0:
103
- return None, None, f"❌ CodeFormer failed:\n{result.stderr}"
104
 
105
- # ---------------- Locate final result ----------------
106
  final_results_dir = os.path.join(RESULT_DIR, "final_results")
107
  if not os.path.exists(final_results_dir):
108
- return None, None, "❌ CodeFormer did not produce final results."
109
 
110
  final_files = [f for f in os.listdir(final_results_dir) if f.endswith(".png")]
111
  if not final_files:
112
- return None, None, "❌ No enhanced image found in final results."
113
 
114
  final_path = os.path.join(final_results_dir, final_files[0])
115
  final_img = cv2.cvtColor(cv2.imread(final_path), cv2.COLOR_BGR2RGB)
116
 
117
- return final_img, final_path, ""
118
 
119
  except Exception as e:
120
- return None, None, f"❌ Error: {str(e)}"
 
 
 
 
 
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  # -------------------------------------------------
124
- # Gradio Interface (simplified)
125
  # -------------------------------------------------
126
  with gr.Blocks() as demo:
127
- gr.Markdown("Face Swap")
128
 
129
  with gr.Row():
130
  src_input = gr.Image(type="numpy", label="Upload Your Face")
131
  tgt_input = gr.Image(type="numpy", label="Upload Target Image")
132
 
133
  btn = gr.Button("Swap Face")
134
-
135
  output_img = gr.Image(type="numpy", label="Enhanced Output")
136
- download = gr.File(label="⬇️ Download Enhanced Image")
137
  error_box = gr.Textbox(label="Logs / Errors", interactive=False)
138
 
139
  def process(src, tgt):
140
- img, path, err = face_swap_and_enhance(src, tgt)
141
- return img, path, err
 
 
 
 
142
 
143
- btn.click(process, [src_input, tgt_input], [output_img, download, error_box])
 
 
 
 
144
 
145
- demo.launch()
 
 
1
  import os
2
  os.environ["OMP_NUM_THREADS"] = "1"
3
+
4
  import cv2
5
  import shutil
6
  import uuid
7
+ import subprocess
8
+ import numpy as np
9
  import insightface
10
  from insightface.app import FaceAnalysis
11
  from huggingface_hub import hf_hub_download
12
+ from fastapi import FastAPI, UploadFile, File
13
+ from fastapi.responses import StreamingResponse, JSONResponse
14
+ import io
15
+ import threading
16
+ import gradio as gr
17
+ import uvicorn
18
 
19
  # -------------------------------------------------
20
  # Paths
 
56
  # -------------------------------------------------
57
  # Initialize face analysis and swapper
58
  # -------------------------------------------------
59
+ app_face = FaceAnalysis(name="buffalo_l", root=MODELS_DIR, providers=['CPUExecutionProvider'])
60
+ app_face.prepare(ctx_id=0, det_size=(640, 640))
61
  swapper = insightface.model_zoo.get_model(inswapper_path, providers=['CPUExecutionProvider'])
62
 
63
  # -------------------------------------------------
 
78
  # -------------------------------------------------
79
  # Pipeline Function
80
  # -------------------------------------------------
 
 
 
81
  def face_swap_and_enhance(src_img, tgt_img):
82
  try:
83
  src_bgr = cv2.cvtColor(src_img, cv2.COLOR_RGB2BGR)
84
  tgt_bgr = cv2.cvtColor(tgt_img, cv2.COLOR_RGB2BGR)
85
 
86
+ src_faces = app_face.get(src_bgr)
87
+ tgt_faces = app_face.get(tgt_bgr)
88
  if not src_faces or not tgt_faces:
89
+ return None, "❌ Face not detected in one of the images."
90
 
91
  shutil.rmtree(UPLOAD_DIR, ignore_errors=True)
92
  shutil.rmtree(RESULT_DIR, ignore_errors=True)
93
  os.makedirs(UPLOAD_DIR, exist_ok=True)
94
  os.makedirs(RESULT_DIR, exist_ok=True)
95
 
96
+ # Save swapped face
97
  unique_name = f"swapped_{uuid.uuid4().hex[:8]}.jpg"
98
  swapped_path = os.path.join(UPLOAD_DIR, unique_name)
99
  swapped_bgr = swapper.get(tgt_bgr, tgt_faces[0], src_faces[0])
100
  cv2.imwrite(swapped_path, swapped_bgr)
101
 
102
+ # Run CodeFormer
103
  cmd = f"python {CODEFORMER_PATH} -w 0.7 --input_path {swapped_path} --output_path {RESULT_DIR} --bg_upsampler realesrgan --face_upsample"
104
  result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
105
  if result.returncode != 0:
106
+ return None, f"❌ CodeFormer failed:\n{result.stderr}"
107
 
 
108
  final_results_dir = os.path.join(RESULT_DIR, "final_results")
109
  if not os.path.exists(final_results_dir):
110
+ return None, "❌ CodeFormer did not produce final results."
111
 
112
  final_files = [f for f in os.listdir(final_results_dir) if f.endswith(".png")]
113
  if not final_files:
114
+ return None, "❌ No enhanced image found in final results."
115
 
116
  final_path = os.path.join(final_results_dir, final_files[0])
117
  final_img = cv2.cvtColor(cv2.imread(final_path), cv2.COLOR_BGR2RGB)
118
 
119
+ return final_img, None
120
 
121
  except Exception as e:
122
+ return None, f"❌ Error: {str(e)}"
123
+
124
+ # -------------------------------------------------
125
+ # FastAPI REST API
126
+ # -------------------------------------------------
127
+ api = FastAPI()
128
 
129
+ @api.post("/api/faceswap")
130
+ async def faceswap(src_img: UploadFile = File(...), tgt_img: UploadFile = File(...)):
131
+ try:
132
+ src_bytes = await src_img.read()
133
+ tgt_bytes = await tgt_img.read()
134
+
135
+ src = cv2.imdecode(np.frombuffer(src_bytes, np.uint8), cv2.IMREAD_COLOR)
136
+ tgt = cv2.imdecode(np.frombuffer(tgt_bytes, np.uint8), cv2.IMREAD_COLOR)
137
+
138
+ if src is None or tgt is None:
139
+ return JSONResponse({"error": "Invalid images"}, status_code=400)
140
+
141
+ img_rgb_src = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
142
+ img_rgb_tgt = cv2.cvtColor(tgt, cv2.COLOR_BGR2RGB)
143
+
144
+ result_img, err = face_swap_and_enhance(img_rgb_src, img_rgb_tgt)
145
+ if result_img is None:
146
+ return JSONResponse({"error": err}, status_code=500)
147
+
148
+ _, buffer = cv2.imencode(".png", cv2.cvtColor(result_img, cv2.COLOR_RGB2BGR))
149
+ return StreamingResponse(io.BytesIO(buffer.tobytes()), media_type="image/png")
150
+
151
+ except Exception as e:
152
+ return JSONResponse({"error": str(e)}, status_code=500)
153
 
154
  # -------------------------------------------------
155
+ # Gradio UI (kept for demo)
156
  # -------------------------------------------------
157
  with gr.Blocks() as demo:
158
+ gr.Markdown("Face Swap Demo")
159
 
160
  with gr.Row():
161
  src_input = gr.Image(type="numpy", label="Upload Your Face")
162
  tgt_input = gr.Image(type="numpy", label="Upload Target Image")
163
 
164
  btn = gr.Button("Swap Face")
 
165
  output_img = gr.Image(type="numpy", label="Enhanced Output")
 
166
  error_box = gr.Textbox(label="Logs / Errors", interactive=False)
167
 
168
  def process(src, tgt):
169
+ img, err = face_swap_and_enhance(src, tgt)
170
+ if img is None:
171
+ return None, err
172
+ return img, ""
173
+
174
+ btn.click(process, [src_input, tgt_input], [output_img, error_box])
175
 
176
+ # -------------------------------------------------
177
+ # Run both FastAPI + Gradio
178
+ # -------------------------------------------------
179
+ def run_api():
180
+ uvicorn.run(api, host="0.0.0.0", port=7861)
181
 
182
+ threading.Thread(target=run_api).start()
183
+ demo.launch(server_port=7860, server_name="0.0.0.0")
requirements.txt CHANGED
@@ -32,5 +32,9 @@ onnx
32
  gradio
33
  huggingface_hub
34
 
 
 
 
 
35
  # Optional but included in CodeFormer repo
36
  tb-nightly
 
32
  gradio
33
  huggingface_hub
34
 
35
+ # FastAPI REST API + server
36
+ fastapi
37
+ uvicorn
38
+
39
  # Optional but included in CodeFormer repo
40
  tb-nightly