4.1 KiB
RTSP Windowed People Flow Design
Date: 2026-04-08
Goal: Extend the existing people-flow project with an RTSP mode that samples one frame per second from a live stream, computes people-flow and demographics, and writes a JSON summary every 30 minutes while preserving the existing offline video and batch modes.
Scope
- Keep the existing
videoandbatchcommands unchanged. - Add a new
rtspcommand for continuous live-stream processing. - Sample one frame per second based on wall-clock time instead of processing every decoded frame.
- Maintain a 30-minute independent counting window.
- Write one timestamped JSON file per finished window.
- Refresh a
latest.jsonfile on every window flush. - Do not save annotated RTSP video by default.
- Back up the current project before implementation.
Approach
The current codebase already has reusable counting and attribute aggregation logic. The least risky change is to keep the offline pipeline as-is and add a dedicated RTSP processing path that reuses the same LineCrossCounter and AttributeAggregator components.
The RTSP path will:
- Open an RTSP stream with OpenCV.
- Read frames continuously.
- Run inference only when at least one second has elapsed since the last processed frame.
- Accumulate counts inside the current 30-minute window.
- Flush a window summary to JSON when the window boundary is reached.
- Reset all per-window state and continue into the next window.
- Retry the stream connection when the RTSP source drops.
Data Flow
Command Layer
main.pyadds anrtspsubcommand with an--inputRTSP URL.- Existing global arguments such as
--config,--output-dir,--line, and--deviceremain shared. - RTSP mode disables video writing by default unless explicitly enabled in config later.
Configuration
Add a new RTSP config section with:
sample_interval_secondswindow_secondsreconnect_delay_secondsstream_open_timeout_secondsidle_sleep_secondsoutput_subdir
This keeps timing and output behavior configurable without changing code.
Processing Loop
Each processed frame will:
- Pass through YOLO tracking.
- Extract
persontrack observations. - Optionally run DeepFace sampling on eligible tracks.
- Update the line-cross counter.
- Check whether the active 30-minute window should be flushed.
Skipped frames are decoded only to keep the stream current; they do not go through YOLO or DeepFace.
Window Boundaries
Each window starts when the RTSP pipeline starts or right after the previous flush. The summary payload includes:
source_typesourcewindow_indexwindow_startwindow_endwindow_duration_secondstotal_peopleage_countsgender_countsunknown_attributestracks
After flushing:
- The timestamped JSON is written under
windows/. latest.jsonis overwritten with the same payload.- The counting and attribute state is reset.
Output Layout
For --output-dir /path/output, the RTSP outputs live under:
/path/output/rtsp_stream//path/output/rtsp_stream/latest.json/path/output/rtsp_stream/windows/stats_YYYY-MM-DD_HH-MM-SS.json
The timestamp in the filename is the window end time.
Error Handling
- If the RTSP stream cannot be opened, retry after a configurable delay.
- If frame reads fail mid-stream, release the capture and reconnect.
- If DeepFace analysis fails on a crop, treat that sample as unknown and keep running.
- If a window has zero crossings, still write a valid JSON payload with zero counts so downstream consumers can distinguish inactivity from pipeline failure.
Compatibility
videomode still writes annotated video and a final JSON after full processing.batchmode still writes a final CSV summary.- Existing config keys remain valid.
Testing Strategy
- Validate CLI parsing for the new
rtspcommand. - Validate config loading with the new RTSP section.
- Validate that RTSP mode writes windowed JSON payloads and refreshes
latest.json. - Validate that 30-minute windows reset counts instead of accumulating indefinitely.
- Keep offline mode behavior intact by running
--helpand Python compile checks.