shpark1234 commited on
Commit
ea02dea
·
verified ·
1 Parent(s): 13006dd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -0
app.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from typing import Any, Dict, List
4
+
5
+ import cv2
6
+ import numpy as np
7
+ from fastapi import FastAPI, File, UploadFile, HTTPException
8
+ from huggingface_hub import hf_hub_download
9
+ from ultralytics import YOLO
10
+
11
+
12
+ MODEL_REPO_ID = os.getenv("MODEL_REPO_ID", "HudatersU/road_maintanance")
13
+ MODEL_FILENAME = os.getenv("MODEL_FILENAME", "pothole_best2.pt")
14
+ CONF_THRES = float(os.getenv("CONF_THRES", "0.25"))
15
+
16
+ app = FastAPI(title="Road Maintenance Detection API")
17
+
18
+ model = None
19
+
20
+
21
+ @app.on_event("startup")
22
+ def load_model():
23
+ global model
24
+
25
+ model_path = hf_hub_download(
26
+ repo_id=MODEL_REPO_ID,
27
+ filename=MODEL_FILENAME,
28
+ )
29
+
30
+ model = YOLO(model_path)
31
+
32
+
33
+ @app.get("/")
34
+ def root():
35
+ return {
36
+ "status": "ok",
37
+ "model_repo": MODEL_REPO_ID,
38
+ "model_file": MODEL_FILENAME,
39
+ "endpoints": ["/health", "/predict"],
40
+ }
41
+
42
+
43
+ @app.get("/health")
44
+ def health():
45
+ return {
46
+ "status": "ok",
47
+ "model_loaded": model is not None,
48
+ }
49
+
50
+
51
+ @app.post("/predict")
52
+ async def predict(file: UploadFile = File(...)) -> Dict[str, Any]:
53
+ if model is None:
54
+ raise HTTPException(status_code=503, detail="Model is not loaded yet")
55
+
56
+ image_bytes = await file.read()
57
+
58
+ np_arr = np.frombuffer(image_bytes, np.uint8)
59
+ image = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
60
+
61
+ if image is None:
62
+ raise HTTPException(status_code=400, detail="Invalid image")
63
+
64
+ h, w = image.shape[:2]
65
+
66
+ start = time.time()
67
+ results = model.predict(image, conf=CONF_THRES, verbose=False)
68
+ elapsed_ms = round((time.time() - start) * 1000, 2)
69
+
70
+ detections: List[Dict[str, Any]] = []
71
+
72
+ for r in results:
73
+ if r.boxes is None:
74
+ continue
75
+
76
+ for i, box in enumerate(r.boxes):
77
+ x1, y1, x2, y2 = box.xyxy[0].tolist()
78
+ conf = float(box.conf[0])
79
+ cls_id = int(box.cls[0])
80
+ cls_name = model.names.get(cls_id, str(cls_id))
81
+
82
+ det = {
83
+ "class_id": cls_id,
84
+ "class_name": cls_name,
85
+ "confidence": conf,
86
+ "box": [x1, y1, x2, y2],
87
+ }
88
+
89
+ if r.masks is not None and r.masks.xy is not None and i < len(r.masks.xy):
90
+ det["polygon"] = r.masks.xy[i].tolist()
91
+
92
+ detections.append(det)
93
+
94
+ return {
95
+ "image": {
96
+ "width": w,
97
+ "height": h,
98
+ },
99
+ "inference_ms": elapsed_ms,
100
+ "detections": detections,
101
+ }