Noursine commited on
Commit
00cb6fd
·
verified ·
1 Parent(s): 668461c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +5 -22
app.py CHANGED
@@ -1,4 +1,3 @@
1
- import os
2
  import io
3
  import base64
4
  from typing import Optional
@@ -12,7 +11,6 @@ from fastapi.middleware.cors import CORSMiddleware
12
 
13
  from detectron2.engine import DefaultPredictor
14
  from detectron2.config import get_cfg
15
- from detectron2 import model_zoo
16
  from detectron2.data import MetadataCatalog
17
 
18
  # -------------------
@@ -26,9 +24,9 @@ cfg.merge_from_file(
26
  )
27
  cfg.MODEL.ROI_HEADS.NUM_CLASSES = len(classes)
28
  cfg.MODEL.POINT_HEAD.NUM_CLASSES = len(classes)
29
- cfg.MODEL.WEIGHTS = "model_final.pth" # path to your trained PointRend model
30
  cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
31
- cfg.MODEL.DEVICE = "cpu" # change to "cuda" if GPU available
32
  MetadataCatalog.get("__unused__").thing_classes = classes
33
 
34
  predictor = DefaultPredictor(cfg)
@@ -43,13 +41,10 @@ app.add_middleware(
43
  allow_methods=["*"], allow_headers=["*"],
44
  )
45
 
46
-
47
  # -------------------
48
- # Post-processing helpers
49
  # -------------------
50
  def postprocess_simplified(mask: np.ndarray, epsilon_factor: float = 0.01) -> np.ndarray:
51
- if mask is None:
52
- return None
53
  mask_uint8 = (mask * 255).astype(np.uint8) if mask.max() <= 1 else mask.astype(np.uint8)
54
  bw = (mask_uint8 > 127).astype(np.uint8) * 255
55
  contours, _ = cv2.findContours(bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
@@ -62,10 +57,7 @@ def postprocess_simplified(mask: np.ndarray, epsilon_factor: float = 0.01) -> np
62
  cv2.fillPoly(simp, [approx], 255)
63
  return simp
64
 
65
-
66
  def mask_to_polygon(mask: np.ndarray, epsilon_factor: float = 0.01, min_area: int = 150) -> Optional[np.ndarray]:
67
- if mask is None:
68
- return None
69
  mask_uint8 = (mask * 255).astype(np.uint8) if mask.max() <= 1 else mask.astype(np.uint8)
70
  bw = (mask_uint8 > 127).astype(np.uint8) * 255
71
  contours, _ = cv2.findContours(bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
@@ -78,16 +70,14 @@ def mask_to_polygon(mask: np.ndarray, epsilon_factor: float = 0.01, min_area: in
78
  approx = cv2.approxPolyDP(contour, epsilon, True)
79
  return approx.reshape(-1, 2)
80
 
81
-
82
  def im_to_b64_png(im: np.ndarray) -> str:
83
  ok, buf = cv2.imencode(".png", im)
84
  if not ok:
85
  raise RuntimeError("Failed to encode image")
86
  return base64.b64encode(buf).decode("utf-8")
87
 
88
-
89
  # -------------------
90
- # Prediction endpoint: return only one G-Zone + overlay + polygon
91
  # -------------------
92
  @app.post("/polygon")
93
  async def polygon_endpoint(file: UploadFile = File(...)):
@@ -104,17 +94,14 @@ async def polygon_endpoint(file: UploadFile = File(...)):
104
  if len(instances) == 0:
105
  return JSONResponse(content={"chosen": None, "polygon": None, "image": None})
106
 
107
- # --- Pick one G-Zone: first instance (can change to largest if needed) ---
108
  idx = 0
109
  cls_id = int(instances.pred_classes[idx])
110
  cls_name = classes[cls_id]
111
  raw_mask = instances.pred_masks[idx].numpy().astype(np.uint8)
112
 
113
- # --- Simplify mask and convert to polygon ---
114
  simp_mask = postprocess_simplified(raw_mask)
115
  poly = mask_to_polygon(simp_mask)
116
 
117
- # --- Overlay polygon on original image ---
118
  overlay = im.copy()
119
  poly_list = None
120
  if poly is not None:
@@ -123,8 +110,4 @@ async def polygon_endpoint(file: UploadFile = File(...)):
123
 
124
  img_b64 = im_to_b64_png(overlay)
125
 
126
- return {
127
- "chosen": cls_name,
128
- "polygon": poly_list,
129
- "image": img_b64
130
- }
 
 
1
  import io
2
  import base64
3
  from typing import Optional
 
11
 
12
  from detectron2.engine import DefaultPredictor
13
  from detectron2.config import get_cfg
 
14
  from detectron2.data import MetadataCatalog
15
 
16
  # -------------------
 
24
  )
25
  cfg.MODEL.ROI_HEADS.NUM_CLASSES = len(classes)
26
  cfg.MODEL.POINT_HEAD.NUM_CLASSES = len(classes)
27
+ cfg.MODEL.WEIGHTS = "model_final.pth" # make sure this file is in repo
28
  cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
29
+ cfg.MODEL.DEVICE = "cpu"
30
  MetadataCatalog.get("__unused__").thing_classes = classes
31
 
32
  predictor = DefaultPredictor(cfg)
 
41
  allow_methods=["*"], allow_headers=["*"],
42
  )
43
 
 
44
  # -------------------
45
+ # Helpers
46
  # -------------------
47
  def postprocess_simplified(mask: np.ndarray, epsilon_factor: float = 0.01) -> np.ndarray:
 
 
48
  mask_uint8 = (mask * 255).astype(np.uint8) if mask.max() <= 1 else mask.astype(np.uint8)
49
  bw = (mask_uint8 > 127).astype(np.uint8) * 255
50
  contours, _ = cv2.findContours(bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
57
  cv2.fillPoly(simp, [approx], 255)
58
  return simp
59
 
 
60
  def mask_to_polygon(mask: np.ndarray, epsilon_factor: float = 0.01, min_area: int = 150) -> Optional[np.ndarray]:
 
 
61
  mask_uint8 = (mask * 255).astype(np.uint8) if mask.max() <= 1 else mask.astype(np.uint8)
62
  bw = (mask_uint8 > 127).astype(np.uint8) * 255
63
  contours, _ = cv2.findContours(bw, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
70
  approx = cv2.approxPolyDP(contour, epsilon, True)
71
  return approx.reshape(-1, 2)
72
 
 
73
  def im_to_b64_png(im: np.ndarray) -> str:
74
  ok, buf = cv2.imencode(".png", im)
75
  if not ok:
76
  raise RuntimeError("Failed to encode image")
77
  return base64.b64encode(buf).decode("utf-8")
78
 
 
79
  # -------------------
80
+ # Prediction endpoint
81
  # -------------------
82
  @app.post("/polygon")
83
  async def polygon_endpoint(file: UploadFile = File(...)):
 
94
  if len(instances) == 0:
95
  return JSONResponse(content={"chosen": None, "polygon": None, "image": None})
96
 
 
97
  idx = 0
98
  cls_id = int(instances.pred_classes[idx])
99
  cls_name = classes[cls_id]
100
  raw_mask = instances.pred_masks[idx].numpy().astype(np.uint8)
101
 
 
102
  simp_mask = postprocess_simplified(raw_mask)
103
  poly = mask_to_polygon(simp_mask)
104
 
 
105
  overlay = im.copy()
106
  poly_list = None
107
  if poly is not None:
 
110
 
111
  img_b64 = im_to_b64_png(overlay)
112
 
113
+ return {"chosen": cls_name, "polygon": poly_list, "image": img_b64}