Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- Dockerfile +15 -0
- app.py +76 -0
- models/inswapper_128.onnx +3 -0
- requirements.txt +7 -0
Dockerfile
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.9
|
2 |
+
|
3 |
+
RUN useradd -m -u 1000 user
|
4 |
+
USER user
|
5 |
+
ENV PATH="/home/user/.local/bin:$PATH"
|
6 |
+
|
7 |
+
WORKDIR /app
|
8 |
+
|
9 |
+
COPY --chown=user ./requirements.txt requirements.txt
|
10 |
+
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
11 |
+
|
12 |
+
COPY --chown=user . /app
|
13 |
+
EXPOSE 7860
|
14 |
+
|
15 |
+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
app.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, File, UploadFile, HTTPException
|
2 |
+
from fastapi.responses import JSONResponse
|
3 |
+
import cv2
|
4 |
+
import numpy as np
|
5 |
+
import insightface
|
6 |
+
from insightface.app import FaceAnalysis
|
7 |
+
import uvicorn
|
8 |
+
import logging
|
9 |
+
import base64
|
10 |
+
|
11 |
+
# Configurar logging
|
12 |
+
logging.basicConfig(level=logging.INFO)
|
13 |
+
|
14 |
+
app = FastAPI()
|
15 |
+
|
16 |
+
|
17 |
+
face_app = FaceAnalysis(name='buffalo_l')
|
18 |
+
face_app.prepare(ctx_id=0, det_size=(640, 640))
|
19 |
+
# Carga el modelo desde la carpeta 'models'
|
20 |
+
swapper = insightface.model_zoo.get_model('models/inswapper_128.onnx', download=False, download_zip=False)
|
21 |
+
|
22 |
+
def process_images(image1_bytes: bytes, image2_bytes: bytes):
|
23 |
+
# Convertir bytes a imágenes con OpenCV
|
24 |
+
nparr1 = np.frombuffer(image1_bytes, np.uint8)
|
25 |
+
img1 = cv2.imdecode(nparr1, cv2.IMREAD_COLOR)
|
26 |
+
nparr2 = np.frombuffer(image2_bytes, np.uint8)
|
27 |
+
img2 = cv2.imdecode(nparr2, cv2.IMREAD_COLOR)
|
28 |
+
if img1 is None or img2 is None:
|
29 |
+
raise ValueError("Error al decodificar una de las imágenes.")
|
30 |
+
|
31 |
+
# Detección de rostros
|
32 |
+
faces1 = face_app.get(img1)
|
33 |
+
faces2 = face_app.get(img2)
|
34 |
+
if not faces1 or not faces2:
|
35 |
+
raise ValueError("No se detectó ningún rostro en una o ambas imágenes.")
|
36 |
+
|
37 |
+
# Usar el primer rostro detectado en cada imagen
|
38 |
+
face1 = faces1[0]
|
39 |
+
face2 = faces2[0]
|
40 |
+
|
41 |
+
# Realizar el intercambio de rostros
|
42 |
+
img1_swap = swapper.get(img1, face1, face2, paste_back=True)
|
43 |
+
img2_swap = swapper.get(img2, face2, face1, paste_back=True)
|
44 |
+
return img1_swap, img2_swap
|
45 |
+
|
46 |
+
def image_to_base64(image) -> str:
|
47 |
+
# Codificar la imagen a JPEG y luego a base64
|
48 |
+
success, buffer = cv2.imencode(".jpg", image)
|
49 |
+
if not success:
|
50 |
+
raise ValueError("No se pudo codificar la imagen.")
|
51 |
+
return base64.b64encode(buffer).decode("utf-8")
|
52 |
+
|
53 |
+
@app.post("/swap_faces")
|
54 |
+
async def swap_faces(image1: UploadFile = File(...), image2: UploadFile = File(...)):
|
55 |
+
"""
|
56 |
+
Endpoint que recibe dos imágenes por POST y devuelve un JSON con las imágenes
|
57 |
+
con los rostros intercambiados codificadas en base64.
|
58 |
+
"""
|
59 |
+
try:
|
60 |
+
# Leer los archivos
|
61 |
+
image1_bytes = await image1.read()
|
62 |
+
image2_bytes = await image2.read()
|
63 |
+
# Procesar las imágenes
|
64 |
+
img1_swap, img2_swap = process_images(image1_bytes, image2_bytes)
|
65 |
+
# Convertir imágenes a base64
|
66 |
+
result = {
|
67 |
+
"image1": image_to_base64(img1_swap),
|
68 |
+
"image2": image_to_base64(img2_swap)
|
69 |
+
}
|
70 |
+
return JSONResponse(content=result)
|
71 |
+
except Exception as e:
|
72 |
+
logging.exception("Error al procesar las imágenes")
|
73 |
+
raise HTTPException(status_code=500, detail=str(e))
|
74 |
+
|
75 |
+
if __name__ == "__main__":
|
76 |
+
uvicorn.run(app, host="0.0.0.0", port=7860)
|
models/inswapper_128.onnx
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:e4a3f08c753cb72d04e10aa0f7dbe3deebbf39567d4ead6dce08e98aa49e16af
|
3 |
+
size 554253681
|
requirements.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
fastapi
|
2 |
+
uvicorn[standard]
|
3 |
+
numpy
|
4 |
+
opencv-python
|
5 |
+
matplotlib
|
6 |
+
onnxruntime
|
7 |
+
insightface
|