Spaces:
Sleeping
Sleeping
| # 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] | |
| 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)} | |
| ) | |