Zeldeo commited on
Commit
3f12567
·
verified ·
1 Parent(s): 61484d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -41
app.py CHANGED
@@ -1,14 +1,15 @@
1
  from fastapi import FastAPI, File, UploadFile
2
  from fastapi.responses import JSONResponse
3
  from fastapi.middleware.cors import CORSMiddleware
4
- import torch
5
  from PIL import Image
6
- from transformers import AutoImageProcessor, AutoBackbone
7
  import io
 
8
  import numpy as np
 
9
 
10
  app = FastAPI(title="FAST TextNet API")
11
 
 
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
@@ -16,71 +17,76 @@ app.add_middleware(
16
  allow_headers=["*"],
17
  )
18
 
 
19
  print("Chargement du modèle...")
20
  processor = AutoImageProcessor.from_pretrained("czczup/textnet-base")
21
  model = AutoBackbone.from_pretrained("czczup/textnet-base")
22
  model.eval()
23
  print("Modèle prêt !")
24
 
 
25
  @app.get("/")
26
  def health():
27
  return {"status": "ok", "model": "czczup/textnet-base"}
28
 
 
29
  @app.post("/detect")
30
  async def detect_text(file: UploadFile = File(...)):
31
  try:
 
32
  image_bytes = await file.read()
33
  image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
34
 
 
35
  inputs = processor(image, return_tensors="pt")
36
 
 
37
  with torch.no_grad():
38
  outputs = model(**inputs)
39
 
40
- # Récupère tous les feature maps
41
- feature_maps = []
42
- for fm in outputs.feature_maps:
43
- feature_maps.append({
44
- "shape": list(fm.shape),
45
- "mean": float(fm.mean()),
46
- "std": float(fm.std()),
47
- "min": float(fm.min()),
48
- "max": float(fm.max()),
49
- })
50
-
51
-
52
  # On prend la dernière feature map
53
  fm = outputs.feature_maps[-1][0] # shape: [C, H, W]
54
-
55
- # On fait une "heatmap" simple
56
  heatmap = fm.mean(dim=0).numpy()
57
-
 
58
  threshold = heatmap.max() * 0.5
59
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  boxes = []
61
-
62
- H, W = heatmap.shape
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- print("Heatmap min:", heatmap.min())
65
- print("Heatmap max:", heatmap.max())
66
- print("Threshold:", threshold)
67
-
68
- print("Feature maps:", len(outputs.feature_maps))
69
- print("Shape:", outputs.feature_maps[-1].shape)
70
-
71
-
72
- for y in range(0, H, 5):
73
- for x in range(0, W, 5):
74
- if heatmap[y, x] > threshold:
75
- boxes.append({
76
- "x": int(x * 4),
77
- "y": int(y * 4),
78
- "w": 40,
79
- "h": 20,
80
- "text": "text"
81
- })
82
-
83
- return boxes
84
 
85
  except Exception as e:
86
- return JSONResponse({"success": False, "error": str(e)}, status_code=500)
 
1
  from fastapi import FastAPI, File, UploadFile
2
  from fastapi.responses import JSONResponse
3
  from fastapi.middleware.cors import CORSMiddleware
 
4
  from PIL import Image
 
5
  import io
6
+ import torch
7
  import numpy as np
8
+ from transformers import AutoImageProcessor, AutoBackbone
9
 
10
  app = FastAPI(title="FAST TextNet API")
11
 
12
+ # --- Autoriser Flutter / navigateur ---
13
  app.add_middleware(
14
  CORSMiddleware,
15
  allow_origins=["*"],
 
17
  allow_headers=["*"],
18
  )
19
 
20
+ # --- Chargement modèle ---
21
  print("Chargement du modèle...")
22
  processor = AutoImageProcessor.from_pretrained("czczup/textnet-base")
23
  model = AutoBackbone.from_pretrained("czczup/textnet-base")
24
  model.eval()
25
  print("Modèle prêt !")
26
 
27
+ # --- Health check ---
28
  @app.get("/")
29
  def health():
30
  return {"status": "ok", "model": "czczup/textnet-base"}
31
 
32
+ # --- Détection texte ---
33
  @app.post("/detect")
34
  async def detect_text(file: UploadFile = File(...)):
35
  try:
36
+ # Lire image
37
  image_bytes = await file.read()
38
  image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
39
 
40
+ # Préparer entrée modèle
41
  inputs = processor(image, return_tensors="pt")
42
 
43
+ # Inference
44
  with torch.no_grad():
45
  outputs = model(**inputs)
46
 
47
+ # --- Post-processing simple ---
 
 
 
 
 
 
 
 
 
 
 
48
  # On prend la dernière feature map
49
  fm = outputs.feature_maps[-1][0] # shape: [C, H, W]
 
 
50
  heatmap = fm.mean(dim=0).numpy()
51
+
52
+ H, W = heatmap.shape
53
  threshold = heatmap.max() * 0.5
54
+
55
+ # Extraire points chauds
56
+ points = [(x, y) for y in range(H) for x in range(W) if heatmap[y, x] > threshold]
57
+
58
+ # Regrouper par ligne (simple)
59
+ lines = {}
60
+ for (x, y) in points:
61
+ key = int(y / 10) # regroupe tous les y proches
62
+ if key not in lines:
63
+ lines[key] = []
64
+ lines[key].append((x, y))
65
+
66
+ # Générer les boxes
67
+ scale_x = image.width / W
68
+ scale_y = image.height / H
69
+
70
  boxes = []
71
+ for line in lines.values():
72
+ xs = [p[0] for p in line]
73
+ ys = [p[1] for p in line]
74
+ min_x, max_x = min(xs), max(xs)
75
+ min_y, max_y = min(ys), max(ys)
76
+
77
+ # Filtre petites boxes
78
+ if (max_x - min_x) < 5 or (max_y - min_y) < 2:
79
+ continue
80
+
81
+ boxes.append({
82
+ "x": int(min_x * scale_x),
83
+ "y": int(min_y * scale_y),
84
+ "w": int((max_x - min_x) * scale_x),
85
+ "h": int((max_y - min_y) * scale_y),
86
+ "text": "ligne détectée"
87
+ })
88
 
89
+ return JSONResponse(boxes)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  except Exception as e:
92
+ return JSONResponse({"success": False, "error": str(e)}, status_code=500)