AkashKumarave commited on
Commit
a73b3bc
·
verified ·
1 Parent(s): 4556a5a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -35
app.py CHANGED
@@ -10,6 +10,7 @@ import shutil
10
  import logging
11
  import requests
12
  from pathlib import Path
 
13
 
14
  app = FastAPI()
15
 
@@ -26,7 +27,15 @@ app.add_middleware(
26
  allow_headers=["*"],
27
  )
28
 
 
 
 
29
  def download_model():
 
 
 
 
 
30
  model_dir = Path("models")
31
  model_path = model_dir / "inswapper_128.onnx"
32
  model_url = "https://huggingface.co/ezioruan/inswapper_128.onnx/resolve/main/inswapper_128.onnx"
@@ -35,61 +44,83 @@ def download_model():
35
  logger.info("Model not found. Downloading inswapper_128.onnx...")
36
  model_dir.mkdir(exist_ok=True)
37
  try:
38
- response = requests.get(model_url, stream=True)
39
  response.raise_for_status()
40
  with open(model_path, 'wb') as f:
41
  for chunk in response.iter_content(chunk_size=8192):
42
  f.write(chunk)
43
  logger.info("Model downloaded successfully.")
 
44
  except Exception as e:
45
  logger.error(f"Failed to download model: {e}")
46
  raise RuntimeError("Could not download inswapper_128.onnx. Please check logs.")
47
-
48
- # Download model on startup
49
- download_model()
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  def get_many_faces(image):
52
- """Simplified face detection using insightface (placeholder)."""
53
- from insightface.app import FaceAnalysis
54
- app = FaceAnalysis(name="buffalo_l")
55
- app.prepare(ctx_id=0, det_size=(640, 640))
56
- faces = app.get(image)
57
- return faces if faces else []
 
 
 
 
58
 
59
  def swap_faces(source_img, target_img):
60
  """Perform face swapping using insightface and inswapper model."""
61
- from insightface.utils import face_align
62
- from insightface.model_zoo import face_swapper
 
63
 
64
- # Initialize face analysis
65
- face_analyzer = FaceAnalysis(name="buffalo_l")
66
- face_analyzer.prepare(ctx_id=0, det_size=(640, 640))
67
 
68
- # Detect faces
69
- source_faces = face_analyzer.get(source_img)
70
- target_faces = face_analyzer.get(target_img)
71
 
72
- if not source_faces or not target_faces:
73
- raise ValueError("No faces detected in one or both images.")
74
- if len(source_faces) > 1 or len(target_faces) > 1:
75
- raise ValueError("Multiple faces detected; only one face per image is supported.")
76
 
77
- source_face = source_faces[0]
78
- target_face = target_faces[0]
79
 
80
- # Load the face swapper model
81
- model_path = Path("models/inswapper_128.onnx")
82
- swapper = face_swapper.FaceSwapper(model_path)
 
 
83
 
84
- # Perform face swap
85
- result = swapper.get(target_img, target_face, source_face, paste_back=True)
86
 
87
- # Resize to match target image size
88
- target_pil = Image.fromarray(cv2.cvtColor(target_img, cv2.COLOR_BGR2RGB))
89
- result_pil = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
90
- result_pil = result_pil.resize(target_pil.size, Image.Resampling.LANCZOS)
91
 
92
- return cv2.cvtColor(np.array(result_pil), cv2.COLOR_RGB2BGR)
 
 
 
93
 
94
  @app.post("/swap-face/")
95
  async def swap_face(source_file: UploadFile = File(...), target_file: UploadFile = File(...), doFaceEnhancer: bool = True):
@@ -135,4 +166,8 @@ async def swap_face(source_file: UploadFile = File(...), target_file: UploadFile
135
 
136
  except Exception as e:
137
  logger.error("Error in swap_face: %s", str(e))
138
- raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
10
  import logging
11
  import requests
12
  from pathlib import Path
13
+ import uvicorn
14
 
15
  app = FastAPI()
16
 
 
27
  allow_headers=["*"],
28
  )
29
 
30
+ # Global flag to prevent multiple downloads
31
+ MODEL_DOWNLOADED = False
32
+
33
  def download_model():
34
+ global MODEL_DOWNLOADED
35
+ if MODEL_DOWNLOADED:
36
+ logger.info("Model already downloaded, skipping.")
37
+ return
38
+
39
  model_dir = Path("models")
40
  model_path = model_dir / "inswapper_128.onnx"
41
  model_url = "https://huggingface.co/ezioruan/inswapper_128.onnx/resolve/main/inswapper_128.onnx"
 
44
  logger.info("Model not found. Downloading inswapper_128.onnx...")
45
  model_dir.mkdir(exist_ok=True)
46
  try:
47
+ response = requests.get(model_url, stream=True, timeout=30)
48
  response.raise_for_status()
49
  with open(model_path, 'wb') as f:
50
  for chunk in response.iter_content(chunk_size=8192):
51
  f.write(chunk)
52
  logger.info("Model downloaded successfully.")
53
+ MODEL_DOWNLOADED = True
54
  except Exception as e:
55
  logger.error(f"Failed to download model: {e}")
56
  raise RuntimeError("Could not download inswapper_128.onnx. Please check logs.")
57
+ else:
58
+ logger.info("Model already exists at: %s", model_path)
59
+ MODEL_DOWNLOADED = True
60
+
61
+ @app.on_event("startup")
62
+ async def startup_event():
63
+ """Run startup tasks like downloading the model."""
64
+ logger.info("Starting up application...")
65
+ try:
66
+ download_model()
67
+ logger.info("Startup completed successfully.")
68
+ except Exception as e:
69
+ logger.error(f"Startup failed: {e}")
70
+ raise
71
 
72
  def get_many_faces(image):
73
+ """Simplified face detection using insightface."""
74
+ try:
75
+ from insightface.app import FaceAnalysis
76
+ app = FaceAnalysis(name="buffalo_l")
77
+ app.prepare(ctx_id=0, det_size=(640, 640))
78
+ faces = app.get(image)
79
+ return faces if faces else []
80
+ except Exception as e:
81
+ logger.error(f"Face detection failed: {e}")
82
+ raise
83
 
84
  def swap_faces(source_img, target_img):
85
  """Perform face swapping using insightface and inswapper model."""
86
+ try:
87
+ from insightface.utils import face_align
88
+ from insightface.model_zoo import face_swapper
89
 
90
+ # Initialize face analysis
91
+ face_analyzer = FaceAnalysis(name="buffalo_l")
92
+ face_analyzer.prepare(ctx_id=0, det_size=(640, 640))
93
 
94
+ # Detect faces
95
+ source_faces = face_analyzer.get(source_img)
96
+ target_faces = face_analyzer.get(target_img)
97
 
98
+ if not source_faces or not target_faces:
99
+ raise ValueError("No faces detected in one or both images.")
100
+ if len(source_faces) > 1 or len(target_faces) > 1:
101
+ raise ValueError("Multiple faces detected; only one face per image is supported.")
102
 
103
+ source_face = source_faces[0]
104
+ target_face = target_faces[0]
105
 
106
+ # Load the face swapper model
107
+ model_path = Path("models/inswapper_128.onnx")
108
+ if not model_path.exists():
109
+ raise FileNotFoundError("Model file inswapper_128.onnx not found.")
110
+ swapper = face_swapper.FaceSwapper(model_path)
111
 
112
+ # Perform face swap
113
+ result = swapper.get(target_img, target_face, source_face, paste_back=True)
114
 
115
+ # Resize to match target image size
116
+ target_pil = Image.fromarray(cv2.cvtColor(target_img, cv2.COLOR_BGR2RGB))
117
+ result_pil = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
118
+ result_pil = result_pil.resize(target_pil.size, Image.Resampling.LANCZOS)
119
 
120
+ return cv2.cvtColor(np.array(result_pil), cv2.COLOR_RGB2BGR)
121
+ except Exception as e:
122
+ logger.error(f"Face swap failed: {e}")
123
+ raise
124
 
125
  @app.post("/swap-face/")
126
  async def swap_face(source_file: UploadFile = File(...), target_file: UploadFile = File(...), doFaceEnhancer: bool = True):
 
166
 
167
  except Exception as e:
168
  logger.error("Error in swap_face: %s", str(e))
169
+ raise HTTPException(status_code=500, detail=str(e))
170
+
171
+ if __name__ == "__main__":
172
+ # Hugging Face Spaces expects the app to run on port 7860
173
+ uvicorn.run(app, host="0.0.0.0", port=7860)