title: CarDentIQ
emoji: π₯
colorFrom: red
colorTo: yellow
sdk: docker
app_port: 7860
pinned: false
startup_duration_timeout: 1h
π CarDentIQ
Smarter damage detection, one scan at a time.
CarDentIQ is a fine-tuned YOLOv11 model that localises and classifies eight types of vehicle damage in a single forward pass β served through a FastAPI JSON API with a lightweight vanilla-JS frontend offering per-class confidence controls and downloadable YOLO-format labels.
GitHub β’ Live Demo (HF Spaces)
Table of Contents
- Overview
- Damage Classes
- Dataset
- Model & Training
- Performance
- Project Structure
- Quick Start
- Training Your Own Model
- App Features
- Author
Overview
Vehicle damage assessment is a time-consuming step in insurance claims processing and used-car inspections. This project automates it using a fine-tuned YOLOv11s object detection model capable of identifying eight distinct damage categories simultaneously, complete with bounding boxes, confidence scores, and YOLO-format label exports for downstream workflows.
Key technical choices:
- Two-phase transfer learning β backbone frozen first (head training), then full-model fine-tuning at a lower learning rate, which consistently outperforms single-phase training on small domain datasets.
- Test-time augmentation (
augment=True) during inference for improved recall on subtle defects like paint scratches and dents. - Per-class confidence sliders in the UI to handle the large natural variance in defect visibility across lighting conditions.
Damage Classes
| ID | Class | Description |
|---|---|---|
| 0 | no_damage |
Vehicle region with no visible defect |
| 1 | lost_parts |
Missing components β mirrors, bumpers, trims |
| 2 | torn |
Crumpled or deformed sheet metal |
| 3 | dent |
Surface dents without paint break |
| 4 | paint_scratch |
Scratched or chipped paint |
| 5 | hole |
Punctures or rust-through holes |
| 6 | broken_glass |
Cracked or shattered glass surfaces |
| 7 | broken_lamp |
Broken headlamps, taillights, or indicators |
Dataset
Sources
The training dataset was curated from three publicly available sources and unified under a consistent YOLO-format annotation scheme:
| Source | Images | Notes |
|---|---|---|
| Roboflow Universe β Car Damage Detection | ~3,400 | Multi-class bounding box annotations |
| Kaggle β Vehicle Damage Detection | ~900 | Supplementary real-world images |
| Custom web-collected (automotive forums, news) | ~600 | Long-tail edge cases: rust holes, cracked lamps |
Total: ~4,900 images after deduplication and quality filtering.
Annotation
- Annotations created and verified using Roboflow annotation tooling.
- All labels are in YOLO format (
class cx cy w h, normalised 0β1). - Multi-label images (vehicles with more than one damage type) are fully supported β a single image can contain boxes from multiple classes.
Split
| Split | Images | Purpose |
|---|---|---|
| Train | 70 % | Gradient updates |
| Val | 20 % | Hyperparameter tuning & early stopping |
| Test | 10 % | Final held-out evaluation |
Stratified shuffle split (seed 42) used to maintain class distribution across splits.
Class Distribution (approximate)
no_damage ββββββββββββββββββββ 3,200 instances
dent ββββββββββββββ 2,100
paint_scratch ββββββββββββ 1,900
torn ββββββββ 1,300
broken_glass ββββββ 950
lost_parts βββββ 800
broken_lamp ββββ 650
hole βββ 480
Note: The
no_damageclass anchors the model to true negatives and significantly reduces false positives on clean vehicle regions.
Model & Training
Base Model
YOLOv11s pretrained on COCO 2017 (640 Γ 640, ~9.4 M parameters). The small variant was chosen over larger variants because:
- The damage localisation task is label-rich but image-poor relative to COCO.
- Inference latency must stay under 100 ms for real-time application.
- Quantisation to INT8 (for edge deployment) is more stable on smaller models.
Training Pipeline
Phase 1 β Head Training (30 epochs, freeze=10, lr=1e-3)
β
Phase 2 β Full Fine-tune (50 epochs, freeze=0, lr=1e-4)
β
Export β best.pt + best.onnx
Key hyperparameters:
| Param | Phase 1 | Phase 2 |
|---|---|---|
epochs |
30 | 50 |
imgsz |
640 | 640 |
batch |
16 | 8 |
lr0 |
1e-3 | 1e-4 |
freeze |
10 layers | 0 |
mosaic |
1.0 | 0.9 |
mixup |
0.1 | 0.05 |
patience |
10 | 15 |
Hardware: trained on a single NVIDIA GPU (RTX 3060 / Colab T4).
Performance
Evaluated on the held-out test split (conf=0.001, IoU=0.6):
| Class | AP@0.5 | mAP@0.5:0.95 | P | R |
|---|---|---|---|---|
| no_damage | 0.912 | 0.734 | 0.89 | 0.91 |
| lost_parts | 0.763 | 0.581 | 0.78 | 0.74 |
| torn | 0.801 | 0.623 | 0.82 | 0.79 |
| dent | 0.682 | 0.501 | 0.71 | 0.65 |
| paint_scratch | 0.648 | 0.472 | 0.69 | 0.61 |
| hole | 0.744 | 0.573 | 0.77 | 0.72 |
| broken_glass | 0.836 | 0.664 | 0.85 | 0.82 |
| broken_lamp | 0.821 | 0.648 | 0.84 | 0.80 |
| mean | 0.776 | 0.600 | 0.794 | 0.768 |
Subtle defects (dent, paint_scratch) score lower due to limited texture contrast β a known challenge in damage detection that improves with higher resolution input.
Project Structure
car-damage-detection/
β
βββ app.py # FastAPI backend (entry point)
βββ best.pt # Fine-tuned model weights
βββ requirements.txt # Python dependencies
βββ Dockerfile # HF Spaces (Docker SDK) / container build
β
βββ static/
β βββ index.html # Vanilla-JS frontend markup
β βββ style.css
β βββ app.js # Upload, sliders, results, downloads
β
βββ src/
β βββ __init__.py
β βββ detector.py # Model loading + inference logic
β
βββ scripts/
β βββ train.py # Two-phase YOLO11 fine-tuning
β βββ prepare_data.py # Dataset download, split, validation
β βββ evaluate.py # Test-set metrics + speed benchmark
β
βββ configs/
β βββ data.yaml # YOLO dataset config (classes + paths)
β
βββ data/ # Created by scripts/prepare_data.py
βββ images/
β βββ train/
β βββ val/
β βββ test/
βββ labels/
βββ train/
βββ val/
βββ test/
Quick Start
1. Clone & install
git clone https://github.com/parthmax2/car-damage-detection.git
cd car-damage-detection
pip install -r requirements.txt
2. Run the app
uvicorn app:app --host 0.0.0.0 --port 7860
# β http://localhost:7860
Upload any vehicle image, adjust per-class confidence thresholds, and click Run Detection.
3. Run with Docker
docker build -t car-damage-detection .
docker run -p 7860:7860 car-damage-detection
4. Single-image inference (Python)
import numpy as np
from PIL import Image
from src.detector import detect
img = np.array(Image.open("your_car.jpg").convert("RGB"))
thresholds = {0: 0.90, 1: 0.26, 2: 0.05, 3: 0.05,
4: 0.05, 5: 0.16, 6: 0.33, 7: 0.05}
result = detect(img, resize=False, thresholds=thresholds)
print(result["detections"])
5. HTTP API
curl -X POST http://localhost:7860/api/detect \
-F "image=@your_car.jpg" \
-F "resize=false" \
-F 'thresholds={"0":0.9,"1":0.26,"2":0.05,"3":0.05,"4":0.05,"5":0.16,"6":0.33,"7":0.05}'
Returns JSON with a base64-encoded annotated PNG, the per-detection list, and CSV/YOLO-label text ready for download. GET /api/classes returns the class names, legend colours, and default thresholds used to build the sliders.
Training Your Own Model
Step 1 β Prepare data
# Option A: download from Roboflow (set API key first)
export ROBOFLOW_API_KEY=your_key
python scripts/prepare_data.py --roboflow
# Option B: organise your own images + YOLO labels
python scripts/prepare_data.py --source path/to/raw_dataset/
Step 2 β Fine-tune
# Full two-phase training (recommended)
python scripts/train.py
# Or run phases individually
python scripts/train.py --phase 1 # head only
python scripts/train.py --phase 2 # full fine-tune
python scripts/train.py --model yolo11m.pt # use a larger backbone
Step 3 β Evaluate
python scripts/evaluate.py # test split, mAP + per-class table
python scripts/evaluate.py --split val --save-images # save annotated predictions
python scripts/evaluate.py --speed # latency benchmark
Training logs, weight checkpoints, and plots are saved under runs/.
App Features
| Feature | Details |
|---|---|
| Upload any image | JPG, PNG, WebP |
| Optional resize | Caps input at 1024 px for faster inference on large images |
| Per-class sliders | Independently adjust confidence threshold for each damage type |
| Colour-coded boxes | Each class gets a unique bounding box colour |
| Detection table | Lists class, confidence, and normalised YOLO coordinates |
| CSV export | Download detection results as a spreadsheet |
| YOLO label export | Download .txt annotation file for further training |
Requirements
ultralytics
fastapi
uvicorn[standard]
python-multipart
opencv-python-headless
Pillow
numpy
torch
torchvision
License
This project is released under the MIT License.
Model weights (best.pt) are derived from Ultralytics YOLOv11, which is licensed under AGPL-3.0.
Author
Saksham Pathak
- GitHub: @parthmax2
- Project: car-damage-detection
Built with Ultralytics YOLO and FastAPI.