|
from fastapi import FastAPI, UploadFile, File, Request |
|
from fastapi.responses import JSONResponse |
|
from fastapi.responses import HTMLResponse |
|
from pydantic import BaseModel |
|
from fastapi.staticfiles import StaticFiles |
|
from fastapi.templating import Jinja2Templates |
|
import torch |
|
import cv2 |
|
from PIL import Image |
|
from model import Resnet50FER |
|
from config import Resnet50Config |
|
|
|
|
|
app = FastAPI() |
|
|
|
|
|
STATIC_DIR = "static" |
|
|
|
|
|
app.mount("/static", StaticFiles(directory="static"), name="static") |
|
|
|
|
|
templates = Jinja2Templates(directory="templates") |
|
|
|
|
|
config = Resnet50Config( |
|
num_classes=10 |
|
) |
|
|
|
|
|
html_content = """ |
|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>FastAPI con Imagen de Fondo</title> |
|
<style> |
|
body { |
|
background-image: url('static/background.png'); /* Ruta a tu imagen de fondo en la carpeta 'static' */ |
|
background-size: cover; |
|
background-repeat: no-repeat; |
|
background-attachment: fixed; |
|
font-family: Arial, sans-serif; |
|
color: #333; |
|
margin: 0; |
|
padding: 0; |
|
} |
|
.container { |
|
max-width: 800px; |
|
margin: 0 auto; |
|
padding: 20px; |
|
background-color: rgba(255, 255, 255, 0.8); /* Fondo semi-transparente para mejor legibilidad */ |
|
border-radius: 10px; |
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
<h1>FastAPI con Imagen de Fondo</h1> |
|
<p>Ejemplo de una aplicación FastAPI con una imagen de fondo.</p> |
|
<form id="uploadForm" action="/upload/" method="post" enctype="multipart/form-data" onsubmit="uploadImage(event)"> |
|
<input type="file" name="image" accept="image/*" required> |
|
<button type="submit">Subir Imagen</button> |
|
</form> |
|
</div> |
|
<script> |
|
async function uploadImage(event) { |
|
event.preventDefault(); // Evita el envío tradicional del formulario |
|
const formData = new FormData(); |
|
formData.append('image', document.querySelector('input[name="image"]').files[0]); |
|
try { |
|
const response = await fetch('/recognize-face/', { |
|
method: 'POST', |
|
body: formData |
|
}); |
|
if (!response.ok) { |
|
throw new Error('Error al enviar la imagen'); |
|
} |
|
const result = await response.json(); |
|
console.log(result); |
|
} catch (error) { |
|
console.error('Error:', error); |
|
} |
|
} |
|
</script> |
|
</body> |
|
</html> |
|
""" |
|
|
|
|
|
@app.get("/", response_class=HTMLResponse) |
|
async def homepage(request: Request): |
|
return HTMLResponse(content=html_content) |
|
|
|
|
|
model = Resnet50FER(config) |
|
model.eval() |
|
|
|
|
|
class Item(BaseModel): |
|
|
|
image: UploadFile |
|
|
|
|
|
@app.post("/upload/") |
|
async def upload_image(image: UploadFile = File(...)): |
|
return {"filename": image.filename} |
|
|
|
|
|
@app.post("/predict/") |
|
def predict(item: Item): |
|
|
|
image_bytes = item.image.file.read() |
|
|
|
|
|
return {"message": "Endpoint para predicciones con Resnet50FER"} |
|
|
|
|
|
@app.post("/recognize-face/") |
|
async def recognize_face(image: UploadFile = File(...)): |
|
try: |
|
|
|
contents = await image.read() |
|
img = Image.open(BytesIO(contents)) |
|
|
|
|
|
|
|
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') |
|
gray = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2GRAY) |
|
faces = face_cascade.detectMultiScale(gray, 1.3, 5) |
|
|
|
|
|
detected_faces = [{"x": int(x), "y": int(y), "w": int(w), "h": int(h)} for (x, y, w, h) in faces] |
|
return JSONResponse(content={"detected_faces": detected_faces}) |
|
|
|
except Exception as e: |
|
raise HTTPException(status_code=500, detail=str(e)) |
|
|
|
|
|
if __name__ == "__main__": |
|
import uvicorn |
|
uvicorn.run(app, host="0.0.0.0", port=8000) |
|
|