Traffic Reducer is built from two cooperating Python modules:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Xander44-4/traffic_reducer/llms.txt
Use this file to discover all available pages before exploring further.
video_processor.py, which owns the TrafficCamera class and all computer-vision work, and app.py, a Flask application that exposes a REST API and streams annotated video to the browser. Together they form a closed loop — raw camera pixels enter one end and green-light decisions come out the other, updated multiple times per second without blocking the web server.
High-level data flow
Every processed frame travels through the following stages before the dashboard updates:Component breakdown
TrafficCamera class (video_processor.py)
TrafficCamera is the heart of the system. At construction time it loads the YOLOv8 model, defines the four directional zone polygons, and allocates a ThreadPoolExecutor(max_workers=1) for asynchronous inference. A single background daemon thread — started by camera.start() — runs _process_stream() in an infinite loop, handling three operating modes:
| Mode | Source | Notes |
|---|---|---|
idle | None | Displays a placeholder frame; no inference |
youtube | YouTube live URL via yt-dlp + FFmpeg subprocess | Targets 25 FPS at 854 × 480 |
local | Local MP4 file via cv2.VideoCapture | Playback speed controlled by local_speed multiplier |
traffic_state is a plain dict protected by a threading.Lock:
camera.get_counts() and camera.get_frame(), which both acquire the lock, copy the data, and release — keeping I/O threads independent of the inference thread.
Flask app (app.py)
The Flask application is thin by design. It instantiates one TrafficCamera at module load time and exposes the following REST surface:
| Method | Endpoint | Purpose |
|---|---|---|
GET | / | Renders templates/index.html (Jinja2) |
GET | /video_feed | Streams MJPEG from generate_frames() |
GET | /stats | Returns live counts, phase, priority, emergency flag |
POST | /predict | Runs majority-rule decision; optionally reads live counts |
GET | /simulate | Returns random counts 0–80 for UI testing |
POST | /set_source | Switches camera mode (youtube / local) |
POST | /set_speed | Adjusts local video playback speed multiplier |
GET | /source_status | Reports active mode and local-file availability |
generate_frames() generator yields MJPEG boundary-delimited JPEG bytes directly from traffic_state['frame'], keeping the stream latency under one frame.
Web dashboard (templates/index.html + static/script.js)
The browser dashboard never holds server-side state. It polls two endpoints on fixed timers:
/statsevery 1 500 ms — updates the per-direction vehicle counts, pedestrian count, emergency indicator, and intersection graphic./predictevery 2 000 ms (live mode only) — fetches the current green-light decision and animates the signal display. In manual mode, the frontend calls/predictimmediately whenever a slider value changes.
Threading model
Traffic Reducer runs three concurrent execution contexts at all times:_process_stream draws the overlay using last_yolo_data (the most recently completed result) and skips submitting a new job until the executor is free. This prevents unbounded queue growth under high frame rates.
Frame caching
For local video playback,_process_stream keeps a yolo_cache dict keyed by cv2.CAP_PROP_POS_FRAMES (the integer frame index returned by OpenCV):
set_mode().
Explore the concepts
Vehicle Detection
How YOLOv8 detects vehicles, assigns them to directional zones, and draws the annotated overlay.
Signal Decision
The majority-rule algorithm that picks which lane gets the green light each cycle.
Priority System
Pedestrian and emergency-vehicle overrides that supersede normal signal decisions.
Architecture
You are here — the full system architecture and threading model.