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.
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.txt — ultralytics,opencv-python, requests, torch, torchvisionpython -m venv .venv
.venvScriptsActivate.ps1 # Windows PowerShell
pip install -r requirements.txt
(On macOS/Linux use source .venv/bin/activate.)
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:
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 ~--latencyseconds behind live. Raise
--resync-thresholdfor 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).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]
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.)
Detection is restricted to four COCO classes:
| Index | Class |
|---|---|
| 1 | bicycle |
| 2 | car |
| 3 | motorcycle |
| 5 | bus |
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)
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.
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.
Licensed under the Apache License, Version 2.0 — Copyright 2026 Samuel Armstrong.
See LICENSE for the full text.
Imported from gh:Kentucky-Open-Science/TrafficStream2026. Source last updated 2026-06-18. Synced 2026-07-27.
Source code on GitHub.