YOLOv8-OBB powered parking occupancy detection — full-stack, production-ready.
A full-stack computer vision system that detects parking spaces from overhead lot images and classifies each space as available or occupied using a YOLOv8 oriented bounding box model. Includes a FastAPI inference backend, React dashboard, batch processing, model evaluation views, and live API runtime metrics.
| Detection Page | Batch Results |
|---|---|
![]() |
![]() |
Model: YOLOv8m-OBB · Dataset: PKLot · mAP50: 99.48% · mAP50-95: 99.47%
- Upload JPEG, PNG, BMP, or WEBP parking-lot images
- Detect rotated parking spaces via YOLOv8-OBB
- Classify each space as available or occupied
- View total spots, available, occupied, occupancy %, and inference time
- Annotated output image with per-space overlays
- Batch detection across multiple images
- Model evaluation page with confusion matrix and per-class metrics
- Live API runtime metrics (request count, avg inference time, last request)
- Configurable confidence, IoU, image size, and enhanced tiled scan via sliders
Evaluated on 1,863 test images from the PKLot dataset.
| Metric | Score |
|---|---|
| Precision | 99.90% |
| Recall | 99.90% |
| mAP50 | 99.48% |
| mAP50-95 | 99.47% |
| Layer | Tools |
|---|---|
| Backend | Python 3.10+, FastAPI, Uvicorn, Pydantic |
| ML / Vision | YOLOv8-OBB (Ultralytics), PyTorch, OpenCV, NumPy, Shapely |
| Frontend | React 18, Vite, Axios, Recharts, Tailwind CSS |
| Training | Modal (cloud GPU), PKLot dataset |
.
├── backend/
│ ├── api/
│ │ └── routes.py # FastAPI route definitions
│ ├── core/
│ │ └── config.py # Environment-driven config (Pydantic Settings)
│ ├── models/
│ │ └── schemas.py # Request/response Pydantic schemas
│ ├── services/
│ │ └── inference.py # YOLOv8 inference + post-processing logic
│ ├── utils/
│ │ └── image_utils.py # Image decode, encode, annotation helpers
│ └── main.py # App factory, lifespan, CORS
├── frontend/
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Detection, Evaluation, Metrics pages
│ │ ├── services/ # Axios API client
│ │ ├── App.jsx
│ │ ├── index.css
│ │ └── main.jsx
│ ├── .env.example
│ ├── package.json
│ └── vite.config.js # Dev proxy: /api → http://localhost:8000
├── models/
│ └── .gitkeep # Placeholder — place best.pt here
├── training/
│ ├── train_modal.py # Modal cloud training script
│ └── test_modal.py # Modal evaluation script
├── .env.example
├── requirements.txt
└── README.md
| Dependency | Version |
|---|---|
| Python | 3.10+ |
| Node.js | 18+ |
| npm | bundled with Node |
| CUDA (optional) | Any CUDA-capable GPU; falls back to CPU automatically |
The trained model checkpoint (models/best.pt) is not committed to this repository due to file size. See Model Checkpoint below.
git clone https://github.com/BasuPatil09/Smart-Parking-System.git
cd Smart-Parking-SystemCreate and activate a virtual environment:
# Windows
python -m venv venv
venv\Scripts\activate
# Linux / macOS
python -m venv venv
source venv/bin/activateInstall Python dependencies:
pip install -r requirements.txtConfigure environment:
# Windows
copy .env.example .env
# Linux / macOS
cp .env.example .envBackend environment variables (.env):
CHECKPOINT_PATH=models/best.pt
DEVICE=auto # auto | cpu | cuda | mps
ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
HOST=0.0.0.0
PORT=8000
EXPOSE_API_DOCS=true # Set false in productionStart the backend:
uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000| Endpoint | URL |
|---|---|
| API | http://localhost:8000 |
| Swagger UI | http://localhost:8000/docs |
| Health Check | http://localhost:8000/health |
cd frontend
npm installConfigure environment:
# Windows
copy .env.example .env
# Linux / macOS
cp .env.example .envFrontend environment variables (frontend/.env):
VITE_API_BASE_URL=/apiStart the development server:
npm run devOpen: http://localhost:5173
The Vite dev server proxies all
/apirequests to the backend athttp://localhost:8000.
The trained checkpoint is not committed to this repository (137 MB binary). Download it from the v1.0.0 Release and place it at models/best.pt.
Download best.pt:
# Linux / macOS
curl -L https://github.com/BasuPatil09/Smart-Parking-System/releases/download/v1.0.0/best.pt \
-o models/best.pt
# Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/BasuPatil09/Smart-Parking-System/releases/download/v1.0.0/best.pt `
-OutFile models\best.ptThe backend starts without it, but POST /predict-image returns 503 Model not loaded until the file is present.
To train your own checkpoint from scratch, see Training.
The PKLot test set (1,863 images across UFPR04, UFPR05, and PUCPR lots) used for model evaluation is available as a release asset.
Download Test-Images.zip (550 MB):
# Linux / macOS
curl -L https://github.com/BasuPatil09/Smart-Parking-System/releases/download/v1.0.0/Test-Images.zip \
-o Test-Images.zip
unzip Test-Images.zip -d data/test
# Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/BasuPatik09/Smart-Parking-System/releases/download/v1.0.0/Test-Images.zip `
-OutFile Test-Images.zip
Expand-Archive -Path Test-Images.zip -DestinationPath data\testOr download manually from the v1.0.0 Release.
Use these images with the batch detection feature or to run training/test_modal.py for full evaluation.
Returns backend liveness status.
Returns model load status, active device, and server uptime.
Returns runtime metrics: request count, average inference time, last request timestamp.
Returns stored evaluation metrics displayed on the Evaluation page.
Multipart form upload. Accepts JPEG, PNG, BMP, or WEBP.
| Parameter | Type | Default | Description |
|---|---|---|---|
image |
file | — | Parking lot image (form field) |
conf |
float | 0.15 |
Detection confidence threshold |
iou |
float | 0.55 |
NMS IoU threshold |
imgsz |
int | 1600 |
YOLO inference image size (px) |
max_det |
int | 1000 |
Maximum detections returned |
augment |
bool | true |
Enable enhanced tiled scan for dense lots |
Response fields:
{
"total_spots": 28,
"available": 2,
"occupied": 26,
"occupancy_pct": 92.9,
"inference_ms": 573.6,
"spots": [...],
"annotated_image_b64": "<base64-encoded PNG>"
}Example (curl):
curl -X POST "http://localhost:8000/predict-image?conf=0.15&iou=0.55&imgsz=1600&max_det=1000&augment=true" \
-F "image=@parking_lot.jpg"Training and evaluation scripts use Modal for cloud GPU execution against the PKLot dataset.
Run training:
modal run training/train_modal.pyRun test evaluation:
modal run training/test_modal.pyThe scripts train a YOLOv8m-OBB model and produce a best.pt checkpoint. Copy the output checkpoint to models/best.pt before starting the backend.
cd frontend
npm run buildPreview the production build locally:
npm run previewThe compiled output is written to frontend/dist/. Serve it via a static host or configure FastAPI to mount it directly.
Set
EXPOSE_API_DOCS=falsein.envbefore deploying the backend to production.
503 Model not loaded
The checkpoint is missing. Place best.pt at models/best.pt and restart the backend.
Frontend cannot reach backend
Confirm the backend is running on port 8000 and VITE_API_BASE_URL=/api is set in frontend/.env.
PowerShell blocks npm
npm.cmd run dev
npm.cmd run buildbest.pt not found after cloning
Download it from the v1.0.0 Release and place it at models/best.pt. The file is 137 MB and is not committed to the repository.
Slow inference (CPU)
The status bar in the UI shows the active device. CPU inference on large images (1600px) typically takes 500–800 ms. Enable CUDA by ensuring PyTorch with CUDA support is installed and DEVICE=auto is set.
The following are excluded from version control:
venv/ # Python virtualenv
__pycache__/ # Python bytecode
frontend/node_modules/
frontend/dist/ # Frontend build output
.env # Local secrets
frontend/.env
data/ # Dataset files
reports/ logs/ runs/
*.pt *.pth *.onnx *.engine # Model checkpoints
Committed files include .env.example, requirements.txt, package.json, package-lock.json, models/.gitkeep, and all source code.
MIT License — Copyright (c) 2026 Basu Patil

