Spaces:
Sleeping
Sleeping
File size: 3,247 Bytes
04a5678 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
import gradio as gr
from PIL import Image
from typing import Tuple, Any, Dict, List
# Lazy imports to speed cold start
clf = None
yolo_severity = None
def _load_models():
global clf, yolo_severity
if clf is None:
from transformers import pipeline
# Image classification (damage types)
clf = pipeline("image-classification", model="beingamit99/car_damage_detection")
if yolo_severity is None:
from ultralytics import YOLO
# YOLOv8 severity detector (Light/Moderate/Severe)
yolo_severity = YOLO("nezahatkorkmaz/car-damage-level-detection-yolov8")
def analyze(img: Image.Image) -> Tuple[Dict[str, Any], Image.Image, Any]:
"""
Returns:
- JSON summary (gate + top labels + detections)
- Overlay image with boxes
- Raw YOLO JSON (string or dict)
"""
_load_models()
# --- Gate using classifier ---
# If model has a 'no_damage' label use it; otherwise treat max score < 0.5 as "no damage"
preds = sorted(clf(img), key=lambda x: x["score"], reverse=True)
top = preds[0] if preds else {"label": "unknown", "score": 0.0}
label_lower = top["label"].lower()
if "no" in label_lower and "damage" in label_lower:
gate = False
else:
gate = top["score"] >= 0.5
if not gate:
return {"gate": "No visible damage", "classification_top": top}, img, {"detections": []}
# --- Top-3 labels for type ---
top3 = [{"label": p["label"], "score": float(p["score"])} for p in preds[:3]]
# --- YOLO severity boxes ---
yres = yolo_severity.predict(img)
result = yres[0]
plotted = result.plot() # numpy array with drawn boxes
dets = []
if result.boxes is not None and len(result.boxes) > 0:
# class names if available
names = result.names if hasattr(result, "names") else {}
for i in range(len(result.boxes)):
b = result.boxes[i]
xyxy = b.xyxy[0].tolist()
conf = float(b.conf[0].item())
cls_id = int(b.cls[0].item())
cls_name = names.get(cls_id, str(cls_id))
dets.append({
"bbox_xyxy": [float(x) for x in xyxy],
"confidence": conf,
"class_id": cls_id,
"class_name": cls_name
})
summary = {"gate": "Damaged", "classification_top3": top3, "detections": dets}
try:
raw_json = result.tojson() # string
except Exception:
raw_json = {"error": "tojson failed"}
from PIL import Image as _Image
return summary, _Image.fromarray(plotted), raw_json
demo = gr.Interface(
fn=analyze,
inputs=gr.Image(type="pil", label="Upload a car photo"),
outputs=[
gr.JSON(label="Results (gate + top labels + detections)"),
gr.Image(label="Detections Overlay"),
gr.JSON(label="Raw YOLO JSON")
],
title="Car Damage Inspector",
description=(
"Fast, open-source car damage analysis.\n"
"- Step 1: Classify damage type (ViT).\n"
"- Step 2: Detect severity with YOLOv8 (boxes).\n"
"Models: beingamit99/car_damage_detection, nezahatkorkmaz/car-damage-level-detection-yolov8."
),
)
if __name__ == "__main__":
demo.launch()
|