Alex Vega commited on
Commit
4dbd30d
1 Parent(s): f930c12
Files changed (2) hide show
  1. Dockerfile +13 -0
  2. main.py +67 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+
7
+ RUN pip install --no-cache-dir --upgrade pip -r requirements.txt
8
+
9
+ COPY . .
10
+
11
+ EXPOSE 8000
12
+
13
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
main.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # main.py
2
+
3
+ import io
4
+ import numpy as np
5
+ import tensorflow as tf
6
+ from fastapi import FastAPI, File, UploadFile
7
+ from fastapi.responses import JSONResponse
8
+ from PIL import Image
9
+ from pydantic import BaseModel
10
+
11
+ class TranslationResponse(BaseModel):
12
+ prediction: str
13
+ confidence: float
14
+
15
+ try:
16
+ model = tf.keras.models.load_model('best_model.keras')
17
+ except Exception as e:
18
+ raise IOError(f"Error al cargar el modelo 'best_model.keras'. Aseg煤rate de que el archivo est谩 en el directorio correcto. Error: {e}")
19
+
20
+ app = FastAPI(
21
+ title="API de Traducci贸n de Lenguaje de Se帽as Americano",
22
+ description="Sube una imagen del alfabeto de se帽as (ASL) para obtener una predicci贸n del modelo.",
23
+ version="1.0.0"
24
+ )
25
+
26
+ CLASS_NAMES = [
27
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
28
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
29
+ 'del', 'nothing', 'space'
30
+ ]
31
+
32
+ def preprocess_image(image: Image.Image) -> np.ndarray:
33
+ image = image.resize((96, 96))
34
+ image_array = np.array(image)
35
+
36
+ # Si la imagen es RGBA o en escala de grises, la convierte a RGB
37
+ if image_array.shape[2] == 4:
38
+ image_array = image_array[..., :3]
39
+
40
+ # Normaliza y expande dimensiones para que coincida con la entrada del modelo (1, 96, 96, 3)
41
+ normalized_array = image_array.astype('float32') / 255.0
42
+ return np.expand_dims(normalized_array, axis=0)
43
+
44
+ @app.post("/predict/", response_model=TranslationResponse)
45
+ async def predict(file: UploadFile = File(...)):
46
+ contents = await file.read()
47
+
48
+ try:
49
+ image = Image.open(io.BytesIO(contents)).convert('RGB')
50
+ except Exception as e:
51
+ return JSONResponse(status_code=400, content={"message": f"Error al leer la imagen: {e}"})
52
+
53
+ processed_image = preprocess_image(image)
54
+
55
+ predictions = model.predict(processed_image)
56
+
57
+ predicted_index = np.argmax(predictions, axis=1)[0]
58
+
59
+ confidence = float(predictions[0][predicted_index])
60
+
61
+ prediction_label = CLASS_NAMES[predicted_index]
62
+
63
+ return TranslationResponse(prediction=prediction_label, confidence=confidence)
64
+
65
+ @app.get("/")
66
+ def read_root():
67
+ return {"message": "ok"}