newtechdevng commited on
Commit
23f1a0d
·
verified ·
1 Parent(s): 8143697

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -27
app.py CHANGED
@@ -43,21 +43,20 @@ def detect_aruco_scale(img, marker_size_cm=10.0):
43
  corners, ids, _ = ARUCO_DETECTOR.detectMarkers(gray)
44
  if ids is None:
45
  return None, None
46
- # Use first detected marker
47
  marker_corners = corners[0][0]
48
  w_px = np.linalg.norm(marker_corners[0] - marker_corners[1])
49
  h_px = np.linalg.norm(marker_corners[1] - marker_corners[2])
50
  pixels_per_cm = (w_px + h_px) / 2 / marker_size_cm
51
- return pixels_per_cm, corners
52
 
53
  @app.get("/")
54
  def root():
55
  return {
56
  "model": MODEL_FILE,
57
  "classes": list(CLASS_COLORS.keys()),
58
- "calibration": "Auto via ArUco marker on hard hat (10cm × 10cm)",
59
  "endpoints": {
60
- "POST /detect": "Send image → get detections in cm (if hard hat in frame)",
61
  "GET /health": "Health check"
62
  }
63
  }
@@ -70,7 +69,8 @@ def health():
70
  async def detect(
71
  file: UploadFile = File(...),
72
  marker_size_cm: float = Form(10.0),
73
- confidence: float = Form(0.4)
 
74
  ):
75
  start = time.time()
76
 
@@ -78,7 +78,7 @@ async def detect(
78
  nparr = np.frombuffer(contents, np.uint8)
79
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
80
 
81
- # Try ArUco auto-calibration
82
  pixels_per_cm, aruco_corners = detect_aruco_scale(img, marker_size_cm)
83
  calibrated = pixels_per_cm is not None
84
 
@@ -86,54 +86,58 @@ async def detect(
86
  if calibrated:
87
  cv2.aruco.drawDetectedMarkers(img, aruco_corners)
88
 
89
- # Run YOLO
90
- results = model(img, conf=confidence)[0]
91
  detections = []
92
 
93
  for box in results.boxes:
94
  x1, y1, x2, y2 = map(int, box.xyxy[0])
95
  cls = results.names[int(box.cls[0])]
96
- conf = round(float(box.conf[0]), 3)
97
  w_px = x2 - x1
98
  h_px = y2 - y1
99
  color = CLASS_COLORS.get(cls, (0, 255, 0))
100
 
101
- w_cm = round(w_px / pixels_per_cm, 1) if calibrated else None
102
- h_cm = round(h_px / pixels_per_cm, 1) if calibrated else None
103
 
104
  # Draw bounding box
105
  cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
106
 
107
- # Label with cm if calibrated
108
  label = f"{cls} {conf:.2f}"
109
  if calibrated:
110
  label += f" | {w_cm}x{h_cm}cm"
111
- cv2.putText(img, label, (x1, y1 - 8),
112
- cv2.FONT_HERSHEY_SIMPLEX, 0.55, color, 2)
 
 
 
 
113
 
114
  detections.append({
115
  "class": cls,
116
- "confidence": float(conf),
117
  "bbox": [int(x1), int(y1), int(x2), int(y2)],
118
  "width_px": int(w_px),
119
  "height_px": int(h_px),
120
- "width_cm": float(w_cm) if w_cm is not None else None,
121
- "height_cm": float(h_cm) if h_cm is not None else None,
122
  })
123
 
124
  # Encode result image
125
- _, buf = cv2.imencode(".jpg", img)
126
- img_b64 = base64.b64encode(buf).decode()
127
 
128
  return {
129
- "success": True,
130
- "calibrated": bool(calibrated),
131
- "pixels_per_cm": float(round(pixels_per_cm, 2)) if calibrated else None,
132
- "marker_size_cm": float(marker_size_cm),
133
- "inference_time_s": float(round(time.time() - start, 3)),
134
- "total": int(len(detections)),
135
- "detections": detections,
136
- "image_base64": img_b64,
137
  }
138
 
139
  if __name__ == "__main__":
 
43
  corners, ids, _ = ARUCO_DETECTOR.detectMarkers(gray)
44
  if ids is None:
45
  return None, None
 
46
  marker_corners = corners[0][0]
47
  w_px = np.linalg.norm(marker_corners[0] - marker_corners[1])
48
  h_px = np.linalg.norm(marker_corners[1] - marker_corners[2])
49
  pixels_per_cm = (w_px + h_px) / 2 / marker_size_cm
50
+ return float(pixels_per_cm), corners
51
 
52
  @app.get("/")
53
  def root():
54
  return {
55
  "model": MODEL_FILE,
56
  "classes": list(CLASS_COLORS.keys()),
57
+ "calibration": "Auto via ArUco marker on hard hat (10cm x 10cm)",
58
  "endpoints": {
59
+ "POST /detect": "Send image → get detections in cm",
60
  "GET /health": "Health check"
61
  }
62
  }
 
69
  async def detect(
70
  file: UploadFile = File(...),
71
  marker_size_cm: float = Form(10.0),
72
+ confidence: float = Form(0.2),
73
+ iou: float = Form(0.3)
74
  ):
75
  start = time.time()
76
 
 
78
  nparr = np.frombuffer(contents, np.uint8)
79
  img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
80
 
81
+ # ArUco auto-calibration
82
  pixels_per_cm, aruco_corners = detect_aruco_scale(img, marker_size_cm)
83
  calibrated = pixels_per_cm is not None
84
 
 
86
  if calibrated:
87
  cv2.aruco.drawDetectedMarkers(img, aruco_corners)
88
 
89
+ # Run YOLO with lower confidence + iou for more detections
90
+ results = model(img, conf=confidence, iou=iou)[0]
91
  detections = []
92
 
93
  for box in results.boxes:
94
  x1, y1, x2, y2 = map(int, box.xyxy[0])
95
  cls = results.names[int(box.cls[0])]
96
+ conf = round(float(box.conf[0]), 2)
97
  w_px = x2 - x1
98
  h_px = y2 - y1
99
  color = CLASS_COLORS.get(cls, (0, 255, 0))
100
 
101
+ w_cm = round(float(w_px) / pixels_per_cm, 1) if calibrated else None
102
+ h_cm = round(float(h_px) / pixels_per_cm, 1) if calibrated else None
103
 
104
  # Draw bounding box
105
  cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
106
 
107
+ # Label
108
  label = f"{cls} {conf:.2f}"
109
  if calibrated:
110
  label += f" | {w_cm}x{h_cm}cm"
111
+
112
+ # Background for label text
113
+ (tw, th), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.55, 2)
114
+ cv2.rectangle(img, (x1, y1 - th - 10), (x1 + tw, y1), color, -1)
115
+ cv2.putText(img, label, (x1, y1 - 5),
116
+ cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 0, 0), 2)
117
 
118
  detections.append({
119
  "class": cls,
120
+ "confidence": conf,
121
  "bbox": [int(x1), int(y1), int(x2), int(y2)],
122
  "width_px": int(w_px),
123
  "height_px": int(h_px),
124
+ "width_cm": round(float(w_cm), 1) if w_cm is not None else None,
125
+ "height_cm": round(float(h_cm), 1) if h_cm is not None else None,
126
  })
127
 
128
  # Encode result image
129
+ _, buf = cv2.imencode(".jpg", img)
130
+ img_b64 = base64.b64encode(buf).decode()
131
 
132
  return {
133
+ "success": True,
134
+ "calibrated": bool(calibrated),
135
+ "pixels_per_cm": round(pixels_per_cm, 2) if calibrated else None,
136
+ "marker_size_cm": float(marker_size_cm),
137
+ "inference_time_s": round(float(time.time() - start), 3),
138
+ "total": int(len(detections)),
139
+ "detections": detections,
140
+ "image_base64": img_b64,
141
  }
142
 
143
  if __name__ == "__main__":