SAll projects
fr
All projects

Computer vision · Real-time systems

Intelligent Traffic Monitoring

Vehicle detection, tracking, plate capture and homography-based speed estimation from video.

A containerised traffic monitoring service that watches uploaded video and reports what actually happened on the road: which vehicles, how fast, and which of them broke the limit for their class.

0FPS sustained
98.6%speed estimation accuracy
0point homography calibration

Problem

A speed measured in pixels is not a speed, and detection alone loses a vehicle the moment it passes behind a larger one. Without identity across frames and a mapping from the camera view to real distance, none of the numbers a traffic operator needs can be trusted.

Objectives

  • Keep vehicle identity stable across frames so every measurement belongs to a specific vehicle.
  • Produce speeds in real-world units rather than pixels per frame.
  • Capture one good, readable plate image per vehicle instead of hundreds of unusable ones.
  • Flag violations against speed limits that differ by vehicle type.
  • Make system and model behaviour visible to an operator while a job is still running.

Implementation

  • YOLOv8 detects cars, trucks, buses, motorcycles and bicycles; ByteTrack assigns a track ID and holds it through occlusion.
  • A second YOLOv8 model detects plates within each vehicle crop, running alongside tracking rather than as a separate pass over the video.
  • A quality assessor scores each plate crop on sharpness, brightness and size, and the store keeps only the strongest image per track.
  • A nine-point homography maps the road plane onto real-world coordinates, and outlier rejection discards measurements the geometry cannot support.
  • A FastAPI backend runs processing as a background job and pushes frame-level updates to a Streamlit dashboard over WebSocket.
  • Prometheus collects frame latency, detection rate, inference time and violation counts; Grafana renders them. The whole stack runs under Docker Compose.

Architecture

Ingest
  • video upload
  • FastAPI
  • Redis queue
  • Celery workers
Detect
  • YOLOv8 vehicles
  • ByteTrack
Plates
  • YOLOv8 plate detector
  • quality assessor
  • best-shot storage
Measure
  • 9-point homography
  • outlier rejection
  • per-class speed limits
Observe
  • Prometheus
  • Grafana
  • MLflow
Present
  • Streamlit
  • WebSocket updates

Technologies

  • YOLOv8
  • ByteTrack
  • Supervision
  • FastAPI
  • WebSocket
  • Redis
  • Celery
  • Streamlit
  • Prometheus
  • Grafana
  • MLflow
  • Docker
  • pytest

Challenges & solutions

Challenge

Detection alone double-counts vehicles and loses them behind larger ones, which corrupts every number downstream.

Solution

ByteTrack maintains identity across frames, so counts, speeds and plate images attach to one vehicle rather than to isolated frames.

Challenge

Perspective means the same pixel displacement represents different real distances at different depths, so pixel-based speed is meaningless.

Solution

A nine-point homography calibration maps the road plane to real-world coordinates, with outlier rejection to drop implausible readings.

Challenge

Saving a plate crop from every frame produces thousands of mostly unreadable images.

Solution

A quality assessor scores sharpness, brightness and size, and only the best crop per vehicle is written to disk.

Challenge

A long video job leaves the operator with no feedback until it finishes.

Solution

Processing runs as a background job and streams progress, tracks and violations to the dashboard over WebSocket.

Results

  • Speed estimation reaches 98.6% accuracy, computed through a nine-point homography calibration with outlier rejection rather than from pixel movement.
  • A quality assessor scores every plate crop for sharpness, brightness and size, so one readable image per vehicle is kept instead of hundreds of poor ones.
  • The pipeline sustains 30 FPS while detecting, tracking, reading plates and checking violations.
  • Prometheus and Grafana expose frame latency, detection rates and violation counts, while a Streamlit dashboard streams results over WebSocket as the job runs.

Lessons learned

  • Tracking, not detection, is what makes a vision pipeline useful: identity is what every downstream metric depends on.
  • Calibration is the difference between a number and a measurement. The homography mattered more to accuracy than the choice of model.
  • Deciding what not to store turned out to be as valuable as deciding what to detect.