fix: persistenza immagini su disco (sopravvive restart server)
Bug: _IMAGES era dict in-memory, restart server → browser con id cached
riceveva 404 'Immagini non trovate'.
Fix: scrittura PNG in /tmp/pm2d_cache/{id}.png al upload, _load_image()
prova cache memory prima di leggere disco.
Rimossa funzione _store_image duplicata.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+30
-16
@@ -9,17 +9,15 @@ Endpoint:
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import io
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from fastapi import FastAPI, File, HTTPException, UploadFile
|
||||
from fastapi.responses import FileResponse, HTMLResponse, Response, StreamingResponse
|
||||
from fastapi.responses import HTMLResponse, Response
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -31,20 +29,36 @@ WEB_DIR = Path(__file__).parent
|
||||
STATIC_DIR = WEB_DIR / "static"
|
||||
STATIC_DIR.mkdir(exist_ok=True)
|
||||
|
||||
# In-memory image store: id → np.ndarray BGR
|
||||
_IMAGES: dict[str, np.ndarray] = {}
|
||||
# Cache del last annotated: (image_id, matches_hash) → png bytes
|
||||
_ANNOT_CACHE: dict[tuple[str, int], bytes] = {}
|
||||
# Persistenza immagini su disco (sopravvive a restart server)
|
||||
CACHE_DIR = Path(tempfile.gettempdir()) / "pm2d_cache"
|
||||
CACHE_DIR.mkdir(exist_ok=True)
|
||||
|
||||
app = FastAPI(title="PM2D Webapp", version="1.0.0")
|
||||
# Cache in-memory (soft, ricaricata da disco se mancante)
|
||||
_IMG_CACHE: dict[str, np.ndarray] = {}
|
||||
|
||||
|
||||
def _store_image(img: np.ndarray) -> str:
|
||||
iid = uuid.uuid4().hex[:12]
|
||||
_IMAGES[iid] = img
|
||||
cv2.imwrite(str(CACHE_DIR / f"{iid}.png"), img)
|
||||
_IMG_CACHE[iid] = img
|
||||
return iid
|
||||
|
||||
|
||||
def _load_image(iid: str) -> np.ndarray | None:
|
||||
cached = _IMG_CACHE.get(iid)
|
||||
if cached is not None:
|
||||
return cached
|
||||
p = CACHE_DIR / f"{iid}.png"
|
||||
if not p.exists():
|
||||
return None
|
||||
img = cv2.imread(str(p))
|
||||
if img is not None:
|
||||
_IMG_CACHE[iid] = img
|
||||
return img
|
||||
|
||||
app = FastAPI(title="PM2D Webapp", version="1.0.0")
|
||||
|
||||
|
||||
def _encode_png(img: np.ndarray) -> bytes:
|
||||
ok, buf = cv2.imencode(".png", img)
|
||||
if not ok:
|
||||
@@ -257,7 +271,7 @@ async def upload(file: UploadFile = File(...)):
|
||||
|
||||
@app.get("/image/{iid}/raw")
|
||||
def image_raw(iid: str):
|
||||
img = _IMAGES.get(iid)
|
||||
img = _load_image(iid)
|
||||
if img is None:
|
||||
raise HTTPException(404, "Image not found")
|
||||
return Response(_encode_png(img), media_type="image/png")
|
||||
@@ -265,8 +279,8 @@ def image_raw(iid: str):
|
||||
|
||||
@app.post("/match", response_model=MatchResp)
|
||||
def match(p: MatchParams):
|
||||
model = _IMAGES.get(p.model_id)
|
||||
scene = _IMAGES.get(p.scene_id)
|
||||
model = _load_image(p.model_id)
|
||||
scene = _load_image(p.scene_id)
|
||||
if model is None or scene is None:
|
||||
raise HTTPException(404, "Immagini non trovate")
|
||||
x, y, w, h = p.roi
|
||||
@@ -317,8 +331,8 @@ def match_simple(p: SimpleMatchParams):
|
||||
Il server deriva i parametri tecnici (num_features, soglie gradiente,
|
||||
piramide, ecc.) dall'analisi automatica della ROI.
|
||||
"""
|
||||
model = _IMAGES.get(p.model_id)
|
||||
scene = _IMAGES.get(p.scene_id)
|
||||
model = _load_image(p.model_id)
|
||||
scene = _load_image(p.scene_id)
|
||||
if model is None or scene is None:
|
||||
raise HTTPException(404, "Immagini non trovate")
|
||||
x, y, w, h = p.roi
|
||||
@@ -364,7 +378,7 @@ def match_simple(p: SimpleMatchParams):
|
||||
|
||||
@app.post("/auto_tune")
|
||||
def tune(p: TuneParams):
|
||||
model = _IMAGES.get(p.model_id)
|
||||
model = _load_image(p.model_id)
|
||||
if model is None:
|
||||
raise HTTPException(404, "Immagine non trovata")
|
||||
x, y, w, h = p.roi
|
||||
|
||||
Reference in New Issue
Block a user