File size: 2,702 Bytes
0eef1a6
8969de7
 
 
0eef1a6
 
 
 
 
 
 
 
8969de7
 
a2a680b
8969de7
a8e3ede
1b09ccf
8969de7
0eef1a6
 
 
 
 
 
 
8969de7
 
 
0eef1a6
8969de7
 
 
 
 
0eef1a6
8969de7
0eef1a6
 
 
 
 
 
 
 
 
 
 
 
8969de7
 
 
 
 
 
 
 
 
0eef1a6
 
 
8969de7
 
1b09ccf
8969de7
 
1b09ccf
8969de7
 
 
 
5f075c7
8969de7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
991bcc7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import cv2
import numpy as np
import pickle
import math
from fastapi import FastAPI, File, UploadFile, HTTPException
from PIL import Image
from io import BytesIO
from pydantic import BaseModel
from typing import List
from scipy.ndimage import median_filter
from scipy.signal import convolve2d
from minisom import MiniSom

def load_model():
    with open('somlucuma.pkl', 'rb') as fid:
        som = pickle.load(fid)
    MM = np.loadtxt('matrizMM.txt', delimiter=" ")
    return som, MM

def sobel(patron):
    gx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float32)
    gy = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], dtype=np.float32)

    Gx = convolve2d(patron, gx, mode='valid')
    Gy = convolve2d(patron, gy, mode='valid')

    return Gx, Gy

def medfilt2(G, d=3):
    return median_filter(G, size=d)

def orientacion(patron, w):
    Gx, Gy = sobel(patron)
    Gx = medfilt2(Gx)
    Gy = medfilt2(Gy)

    m, n = Gx.shape
    mOrientaciones = np.zeros((m // w, n // w), dtype=np.float32)

    for i in range(m // w):
        for j in range(n // w):
            Gx_patch = Gx[i*w:(i+1)*w, j*w:(j+1)*w]
            Gy_patch = Gy[i*w:(i+1)*w, j*w:(j+1)*w]

            YY = np.sum(2 * Gx_patch * Gy_patch)
            XX = np.sum(Gx_patch**2 - Gy_patch**2)

            mOrientaciones[i, j] = (0.5 * np.arctan2(YY, XX) + np.pi / 2.0) * (18.0 / np.pi)

    return mOrientaciones

def representativo(imarray):
    imarray = np.squeeze(imarray)
    m, n = imarray.shape
    patron = imarray[1:m-1, 1:n-1]
    EE = orientacion(patron, 14)
    return np.asarray(EE).reshape(-1)

class InputData(BaseModel):
    data: List[float]

app = FastAPI()

som, MM = load_model()

@app.post("/predict/")
async def predict(file: UploadFile = File(...)):
    try:
        contents = await file.read()
        image = Image.open(BytesIO(contents)).convert('L')
        image = np.asarray(image)
        image = cv2.resize(image, (256, 256), interpolation=cv2.INTER_AREA)
        if image.shape != (256, 256):
            raise ValueError("La imagen debe ser de tamaño 256x256.")
        image = image.reshape(256, 256, 1)
        print(f"Imagen convertida a matriz: {image.shape}")
        
        representative_data = representativo(image)
        print(f"Datos representativos de la imagen: {representative_data.shape}")
        representative_data = representative_data.reshape(1, -1)
        
        w = som.winner(representative_data)
        print(f"Índice ganador del SOM: {w}")
        prediction = MM[w]
        print(f"Predicción: {prediction}")
        
        return {"prediction": prediction}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))