Spaces:
Sleeping
Sleeping
| import os | |
| import time | |
| from typing import Any, Dict, List | |
| import cv2 | |
| import numpy as np | |
| from fastapi import FastAPI, File, UploadFile, HTTPException | |
| from huggingface_hub import hf_hub_download | |
| from ultralytics import YOLO | |
| MODEL_REPO_ID = os.getenv("MODEL_REPO_ID", "HudatersU/road_maintanance") | |
| MODEL_FILENAME = os.getenv("MODEL_FILENAME", "pothole_best2.pt") #pothole_best2.pt | |
| CONF_THRES = float(os.getenv("CONF_THRES", "0.45")) | |
| app = FastAPI(title="Road Maintenance Detection API") | |
| model = None | |
| def load_model(): | |
| global model | |
| model_path = hf_hub_download( | |
| repo_id=MODEL_REPO_ID, | |
| filename=MODEL_FILENAME, | |
| ) | |
| model = YOLO(model_path) | |
| def root(): | |
| return { | |
| "status": "ok", | |
| "model_repo": MODEL_REPO_ID, | |
| "model_file": MODEL_FILENAME, | |
| "endpoints": ["/health", "/predict"], | |
| } | |
| def health(): | |
| return { | |
| "status": "ok", | |
| "model_loaded": model is not None, | |
| } | |
| async def predict(file: UploadFile = File(...)) -> Dict[str, Any]: | |
| if model is None: | |
| raise HTTPException(status_code=503, detail="Model is not loaded yet") | |
| image_bytes = await file.read() | |
| np_arr = np.frombuffer(image_bytes, np.uint8) | |
| image = cv2.imdecode(np_arr, cv2.IMREAD_COLOR) | |
| if image is None: | |
| raise HTTPException(status_code=400, detail="Invalid image") | |
| h, w = image.shape[:2] | |
| start = time.time() | |
| infer_image = cv2.resize(image, (640, 480)) | |
| results = model.predict(infer_image, conf=CONF_THRES, imgsz=640, verbose=False) | |
| elapsed_ms = round((time.time() - start) * 1000, 2) | |
| detections: List[Dict[str, Any]] = [] | |
| for r in results: | |
| if r.boxes is None: | |
| continue | |
| for i, box in enumerate(r.boxes): | |
| x1, y1, x2, y2 = box.xyxy[0].tolist() | |
| conf = float(box.conf[0]) | |
| cls_id = int(box.cls[0]) | |
| cls_name = model.names.get(cls_id, str(cls_id)) | |
| det = { | |
| "class_id": cls_id, | |
| "class_name": cls_name, | |
| "confidence": conf, | |
| "box": [x1, y1, x2, y2], | |
| } | |
| if r.masks is not None and r.masks.xy is not None and i < len(r.masks.xy): | |
| det["polygon"] = r.masks.xy[i].tolist() | |
| detections.append(det) | |
| return { | |
| "image": { | |
| "width": w, | |
| "height": h, | |
| }, | |
| "inference_ms": elapsed_ms, | |
| "detections": detections, | |
| } |