File size: 2,082 Bytes
cebb2ac
 
b8df022
 
 
cebb2ac
b8df022
 
 
 
 
cebb2ac
 
b8df022
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cebb2ac
 
 
 
 
b8df022
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cebb2ac
b8df022
 
 
6a5790f
b8df022
 
6a5790f
3868453
6a5790f
b8df022
 
6a5790f
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
# comentarios sin tildes / sin enye

import io, os
import numpy as np
from fastapi import FastAPI, UploadFile, File
from fastapi.responses import JSONResponse
from PIL import Image
from segment_anything import sam_model_registry, SamAutomaticMaskGenerator
import torch

app = FastAPI(title="Accudoctor Strip Analyzer")

DEVICE = "cuda" if torch.cuda.is_available() else "cpu"

# cargar modelo SAM2
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
sam.to(device=DEVICE)
mask_generator = SamAutomaticMaskGenerator(sam)

def dominant_color(pil_img):
    img = pil_img.resize((60, 60))
    arr = np.array(img)
    arr = arr.reshape((-1, 3))

    pixels, counts = np.unique(arr, axis=0, return_counts=True)
    dom = pixels[counts.argmax()]

    return "#{:02x}{:02x}{:02x}".format(dom[0], dom[1], dom[2])

def analyze_strip(image_bytes):

    img = Image.open(io.BytesIO(image_bytes))
    if img.mode != "RGB":
        img = img.convert("RGB")

    np_img = np.array(img)

    masks = mask_generator.generate(np_img)

    blocks = []
    H = np_img.shape[0]

    for m in masks:
        x, y, w, h = m["bbox"]
        aspect = h / (w + 1e-6)

        if aspect < 3:
            continue

        if h < H * 0.04:
            continue

        crop = img.crop((x, y, x+w, y+h))
        color = dominant_color(crop)

        blocks.append({
            "bbox": [int(x), int(y), int(x+w), int(y+h)],
            "color_hex": color,
            "y_center": y + h/2
        })

    blocks = sorted(blocks, key=lambda b: b["y_center"])
    for i,b in enumerate(blocks):
        b["index"] = i+1
        del b["y_center"]

    return blocks[:11]

@app.post("/strip/")
async def strip(front: UploadFile = File(...)):
    try:
        bytes_img = await front.read()
        result = analyze_strip(bytes_img)

        return JSONResponse(
            status_code=200,
            content={"code": 200, "blocks": result}
        )
    except Exception as e:
        return JSONResponse(
            status_code=200,
            content={"code": 500, "error": str(e)}
        )