An intelligent traffic monitoring system that uses YOLOv8 for vehicle detection, sensorless automated perspective calibration (no roadside IoT sensors), and automated violation processing with OCR-based license plate recognition using Google Gemini Vision API. The system records evidence, uploads to Azure Blob Storage, and sends violations to a backend API for processing. The calibration pipeline is a first-class feature: it can auto-compute homography from video alone, validate scale, and publish calibration without external hardware.
NTCS-CALIBRATION/
β
βββ src/ # Backend Python application
β βββ calib_server.py # Flask server for calibration & monitoring
β βββ track.py # YOLOv8 tracking and speed detection
β βββ violation_recorder.py # Violation processing & evidence recording
β βββ perspective_calibration.py # Manual perspective calibration
β βββ auto_homography.py # Automatic homography calculation
β βββ gemini_lines.py # Gemini-based line detection
β βββ tracked_vehicle_calibration.py # Auto calibration using tracked vehicles
β βββ vehicle_size_verification.py # Vehicle dimension verification
β βββ resources.py # Resource management utilities
β β
β βββ calib/ # Calibration data storage
β βββ models/ # YOLO model files
β βββ temp/ # Temporary files and evidence
β β
β βββ Dockerfile # Production Docker image
β βββ Dockerfile.gpu # GPU-enabled Docker image
β βββ docker-compose.yml # Local development setup
β βββ requirements.txt # Python dependencies
β
βββ frontend/ # React frontend
β
β
βββ README.md # This file
- Real-time Vehicle Detection: YOLOv8-based object detection and tracking
- Speed Measurement: Perspective-calibrated speed calculation using dual-line detection
- Violation Detection: Automated overspeed violation detection with configurable thresholds
- License Plate OCR: Google Gemini Vision API for accurate plate recognition (90%+ confidence filter)
- Evidence Recording: H.264 video segments with atomic writes and remuxing
- Cloud Storage: Azure Blob Storage integration for evidence archival
- API Integration: RESTful API for violation reporting to backend system
- Sensorless Calibration: Compute camera calibration purely from video (tracked vehicles and AI-detected lines) instead of roadside IoT sensors
- Manual Calibration: Point-and-click perspective calibration
- Auto Calibration: Tracked vehicle-based distance calculation
- Gemini-Assisted: AI-powered line detection and homography
The Gemini integration is built around vision-first calibration and OCR, with strict JSON-only responses to keep parsing reliable. All Gemini calls are optional and guarded by the GEMINI_API_KEY environment variable.
- File:
src/gemini_lines.py - Input: A masked road image with polygon overlay (base64-encoded).
- Prompt goal: Return
{line_A_y, line_B_y, road_width_m, note}with lines inside the road polygon and wide separation. - Post-processing:
- Auto-swap if
line_A_y >= line_B_y. - Clamp unrealistic
road_width_m(min 3m, max 50m, default 10m).
- Auto-swap if
- Model:
gemini-3-flash-preview
- File:
src/tracked_vehicle_calibration.py - Input: Two annotated frames of the same vehicle at Line A and Line B, with both lines and the speed-zone trapezoid visible.
- Prompt goal: Estimate real-world distance using geometry and vehicle sizing (JSON-only).
- Why it is robust: The same vehicle is measured at both locations, minimizing variance across vehicle types.
- Model:
gemini-3-flash-preview
- File:
src/perspective_calibration.py - Input: Single vehicle crop with overlay annotations.
- Output: Vehicle type, orientation, primary dimension, confidence.
- Usage: Supports fallback calibration if homography is missing.
- File:
src/vehicle_size_verification.py - Input: Two vehicle crops near Line A and Line B.
- Output: Distance estimate and confidence to cross-check homography.
- Usage: Provides hybrid calibration when both LLM and homography are available.
- File:
src/violation_recorder.py - Input: Cropped vehicle/license plate image.
- Output: Plate text + confidence, filtered at 90%+.
- Behavior: If
GEMINI_API_KEYis missing, OCR is skipped and the system continues.
βββββββββββββββββββ
β Video Stream β
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β YOLOv8 Tracker β β Vehicle detection & tracking
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Speed Calc β β Perspective transform + dual-line timing
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Violation? β β Speed > Limit?
ββββββββββ¬βββββββββ
β YES
v
βββββββββββββββββββ
β Wait Middle Lineβ β Capture at optimal moment
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Record Segment β β 10-sec rolling buffer (H.264)
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Trim Clip (5s) β β FFmpeg re-encode with remux
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Gemini OCR β β License plate recognition
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Upload Azure β β Video + Images to Blob Storage
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β POST Violation β β Send to Backend API
βββββββββββββββββββ
ββββββββββββββββββββ
β Sample Video In β β Live stream or cached clip
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β Gemini Lines β β Gemini-assisted detection of start/end lines
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β YOLO Tracks β β Track same vehicle at both lines
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β Gemini Distance β β Gemini infers real-world gap using vehicle dimensions
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β DeepLabV3 Road β β Road segmentation β polygon
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β Homography Solve β β Use lines + polygon to compute H
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β Publish Calib β β Lines, polygon, scale, fps
βββββββββββ¬βββββββββ
β
v
ββββββββββββββββββββ
β Backend / API β β Served to speed/violation engine
ββββββββββββββββββββ
| Endpoint | Method | Description |
|---|---|---|
/api/status |
GET | Get system status |
/api/cameras |
GET | List all cameras |
/api/set_video_source |
POST | Set video stream source |
/api/load_calibration/:cameraId |
GET | Load calibration for camera |
/api/start_speed |
POST | Start speed detection |
/api/stop_speed |
POST | Stop speed detection |
/video_feed |
GET | Raw video stream |
/speed_feed |
GET | Annotated speed detection stream |
Endpoint: POST https://nextgen-fv1h.onrender.com/api/violations
Payload:
{
"eventId": "EVT-XXXXX",
"cameraId": "CAM-JAL-007",
"capturedAt": "2025-11-16T18:17:44",
"evidence": {
"imageOriginalUrl": "https://...",
"imageEnhancedUrl": "https://...",
"videoClipUrl": "https://..."
},
"violation": {
"type": "OVERSPEED",
"measured": 76.4,
"limit": 60.0
},
"vehicle": {
"vehicleClass": "CAR",
"plate": {
"text": "7AC3391",
"confidence": 0.99
}
}
}For a step-by-step localhost guide, see LOCALHOST_SETUP.md.
- Python 3.11+
- Docker (for containerized deployment)
- FFmpeg (installed in Docker image)
- Azure Storage Account
- Google Gemini API Key
- Backend API endpoint
- Clone the repository
git clone https://github.com/SidhaarthShree07/NTCS-CALIBRATION.git
cd NTCS-CALIBRATION- Set up Python environment
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r src/requirements.txt- Configure environment variables
Create .env file in project root (use .env.example as a template):
# Gemini API
GEMINI_API_KEY=your_gemini_api_key
# Azure Storage
AZURE_STORAGE_CONNECTION_STRING=your_connection_string
AZURE_CONTAINER_NAME=traffic-violations
# Backend API
HMAC_SECRET=your_hmac_secret- Download YOLO models
# Place in src/models/
yolov8l.pt
yolov8l.onnx- Run the server
cd src
python calib_server.pyServer will start at http://localhost:5001
Build Image
cd src
docker build -t ntcs-backend:latest .Run Container
docker run -d \
-p 5001:5001 \
-e GEMINI_API_KEY=your_key \
-e AZURE_STORAGE_CONNECTION_STRING=your_string \
-e AZURE_CONTAINER_NAME=traffic-violations \
-e HMAC_SECRET=your_secret \
--name ntcs-backend \
ntcs-backend:latestLogin to ACR
az acr login --name ntcscalibrationBuild and Push
cd src
docker build -t ntcscalibration.azurecr.io/ntcs-backend:v7.10 .
docker push ntcscalibration.azurecr.io/ntcs-backend:v7.10Update Container App
az containerapp update \
--name ntcs-backend \
--resource-group ntcs-rg \
--image ntcscalibration.azurecr.io/ntcs-backend:v7.10cameras:
- id: CAM-JAL-007
location: Tribune Chowk
stream_url: https://traffic-stream.vercel.app/stream
speed_limit: 60Speed Detection:
- Segment Duration: 10 seconds (250 frames @ 25 FPS)
- Violation Clip: 5 seconds (trimmed around violation)
- Confidence Threshold: 90% (OCR)
- Cooldown: 30 seconds per vehicle
Video Recording:
- Codec: H.264 (libx264)
- Container: MP4 with faststart
- FPS: 25
- Resolution: 3840x2160 (4K)
- CPU: 4 cores
- RAM: 8 GB
- Storage: 50 GB SSD
- Network: 10 Mbps upload
- CPU: 8 cores
- RAM: 16 GB
- Storage: 100 GB SSD
- Network: 50 Mbps upload
- NVIDIA GPU with CUDA 11.8+
- 8 GB VRAM minimum
- Use
Dockerfile.gpufor build
If trimmed videos are tiny (< 1KB) or corrupt:
# Remux all MP4 files in proof directory
Get-ChildItem temp\proof -Filter *.mp4 | ForEach-Object {
$src = $_.FullName
$out = "$($src).remux.mp4"
ffmpeg -y -i $src -c copy -movflags +faststart $out
Move-Item $out $src -Force
}- Ensure vehicle bbox is properly detected
- Check lighting conditions
- Verify Gemini API key is valid
- Review cropped vehicle images in
temp/proof/
- Verify connection string is correct
- Check container exists and has public read access
- Ensure blob name format is valid
| Variable | Description | Required |
|---|---|---|
GEMINI_API_KEY |
Google Gemini Vision API key | Yes |
AZURE_STORAGE_CONNECTION_STRING |
Azure Storage connection string | Optional |
AZURE_CONTAINER_NAME |
Blob container name | Optional |
HMAC_SECRET |
HMAC signature secret | Yes |
This project is proprietary software developed for NTCS Traffic Management System.
- Developer: Sidhaarth Shree
For issues or questions, please open an issue in the GitHub repository or contact the development team.
Version: 1.1
Last Updated: February 2026
Status: Production