Skip to content

Kentucky-Open-Science/TrafficStream2026

Repository files navigation

TrafficStream

Real-time vehicle detection on the City of Lexington, KY public traffic cameras using the latest Ultralytics YOLO model. It identifies and counts bicycles, cars, motorcycles, and buses.

How it works

TrafficStream pulls the live camera map from Lexington's public traffic site and runs YOLO object detection in one of two modes:

Script Mode What it does
stream_camera.py Live Streams a single camera through YOLO in real time, showing an annotated video window with live per-class vehicle counts.
download_cams.py Batch Grabs one frame from every online camera, runs YOLO on the set, and prints the current vehicle density per camera.

Requirements

  • Python 3.8+
  • Dependencies in requirements.txtultralytics, opencv-python, requests, torch, torchvision
  • A CUDA GPU is optional. Inference auto-detects the device and runs on CPU if no GPU is available.
  • YOLO model weights download automatically on first run.

Setup

python -m venv .venv
.venv\Scripts\Activate.ps1        # Windows PowerShell
pip install -r requirements.txt

(On macOS/Linux use source .venv/bin/activate.)

Usage

Live: stream one camera

python stream_camera.py --list              # list available cameras
python stream_camera.py "Main St"           # stream the first camera matching "Main St"
python stream_camera.py --url <hls-or-rtsp> # stream any direct stream URL

Press q (or close the window) to quit.

The live viewer is built to play at real time and never freeze the machine. The City's live HLS feeds are delivered in bursts — OpenCV/FFmpeg decodes a couple of seconds of video almost instantly, then stalls until the next segment — so a naive "show the newest decoded frame" viewer fast-forwards through each burst and then freezes. Instead, the viewer:

  • tags every decoded frame with its presentation timestamp and holds it in a small, real-time playout buffer (JPEG-encoded so memory stays bounded at any resolution), then displays each frame on a wall-clock schedule — so video advances at 1× regardless of bursty delivery;
  • absorbs short network hiccups with the buffer, and on a genuine outage resyncs to the live edge with a forward skip instead of fast-forwarding through stale backlog;
  • reserves a CPU core for the OS/UI and decouples detection from display (cached boxes re-drawn every frame), so the window stays fluid even while the model runs.

A live FPS / inference-latency overlay shows headroom, and the resolved GPU name is printed at startup so you can confirm inference is on your GPU.

Startup: these feeds open behind the live edge with ~20 s of buffered backlog, so for the first ~20–30 s the viewer skips forward a few times to catch up to live; after that it plays smoothly ~--latency seconds behind live. Raise --resync-threshold for fewer, larger skips.

Performance tuning (knobs, with defaults):

  • --model (yolo26x.pt) — YOLO weights; extra-large by default (most accurate, ideal on a GPU). On a CPU-only machine pass --model yolo26n.pt (nano) to stay smooth. yolo26m.pt is a middle ground; yolo11n.pt is a fallback if your ultralytics predates YOLO26.
  • --imgsz (480) — inference resolution; lower to 320 for a big CPU win
  • --vid-stride (2) — run detection on every Nth frame (display stays fresh)
  • --max-det (50) — cap on detections per frame
  • --max-fps (15) — throttle the whole pipeline; lower to 10 for more OS headroom (0 = uncapped)
  • --device (auto) — auto (GPU if available else CPU), cpu, or a GPU index like 0. Explicitly requesting a GPU that has no CUDA now errors instead of silently using the CPU.

Real-time pacing (knobs, with defaults):

  • --latency (3.0) — seconds to sit behind the live edge (the playout-buffer depth). Larger rides through choppier networks more smoothly; smaller stays closer to live.
  • --resync-threshold (--latency + 4.0) — jump to live if playback drifts this far behind the live edge.
  • --buffer-cap (--latency + 8.0) — hard cap on buffered seconds (memory bound).
  • --clock (auto) — pacing clock source: auto/pts (timestamp-driven), fps (nominal frame rate), or legacy (no pacing, old newest-frame behavior).

Batch: vehicle density across all cameras

python download_cams.py

Saves a frame from each online camera into images/, runs YOLO, and prints a line like:

Traffic Density @ Main St & Broadway: 7 vehicle(s) [5 car, 1 bus, 1 bicycle]

Batch: classify saved images with the largest model

Run the heaviest, most accurate model (yolo26x.pt) over everything already in images/ and get a per-image report plus a grand total. Annotated copies are saved to runs/detect/ (gitignored).

python classify_images.py                 # largest model, vehicles only
python classify_images.py --all-classes   # detect every COCO class
python classify_images.py --imgsz 1280    # better on small/distant vehicles
python classify_images.py --no-save       # skip writing annotated images

(The large model is fine here because it's a one-shot batch, not a live loop — it still reserves a CPU core for the OS/UI while it runs.)

Vehicle classes

Detection is restricted to four COCO classes:

Index Class
1 bicycle
2 car
3 motorcycle
5 bus

Project layout

stream_camera.py     Live single-camera detection
download_cams.py     Batch snapshot + density report
classify_images.py   Batch-classify images/ with the largest model
check_cam_online.py  Fetches and caches the camera map (CheckCamOnline)
threaded_camera.py   Latest-frame threaded capture helper
requirements.txt     Python dependencies
data/                Cached camera map JSON   (generated, gitignored)
images/              Captured camera frames   (generated, gitignored)

Model

Uses the latest Ultralytics YOLO model (YOLO26), which auto-downloads on first run. If your installed ultralytics predates YOLO26, set the model to a yolo11 variant (e.g. yolo11n.pt) via --model or the MODEL_WEIGHTS constant.

Data source

Camera feeds come from the City of Lexington, KY public traffic map: https://trafficvid.lexingtonky.gov/publicmap/. Intended for personal and educational use — please respect the city's terms of service.

License

Licensed under the Apache License, Version 2.0 — Copyright 2026 Samuel Armstrong. See LICENSE for the full text.

About

Lex Traffic + YOLO

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages