Files
managed-portal/managed/people_flow_project/README.md
2026-04-27 10:04:36 +08:00

3.9 KiB

People Flow Project

People flow analysis for street videos using YOLO tracking and face-based demographic estimation.

What it does

  • Counts unique people when they cross a configured line
  • Estimates one age bucket per counted track: minor, adult, or senior
  • Estimates one gender bucket per counted track: male or female
  • Writes an annotated output video, per-video JSON, and batch summary CSV

Pipeline

  1. Detect and track person objects with Ultralytics YOLO.
  2. Assign a stable track_id with BoT-SORT or ByteTrack.
  3. Count each track once when it crosses the configured line.
  4. Sample person crops for each track and run DeepFace age/gender analysis.
  5. Use track-level voting so each counted person lands in only one age bucket and one gender bucket.

Project Layout

  • main.py: CLI entrypoint
  • src/people_flow/: application modules
  • configs/default_config.yaml: default runtime settings
  • outputs/: generated result files
  • docs/plans/: design and implementation notes
  • Linux
  • NVIDIA GPU with CUDA
  • Python 3.10 or 3.11

deepface and its transitive dependencies are not a good fit for Python 3.14, so do not build this environment on the current local interpreter version.

Install

python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

Single Video

python main.py video \
  --input "/path/to/video.mp4" \
  --line "0.1,0.55,0.9,0.55"

Batch Directory

python main.py batch \
  --input-dir "/path/to/videos" \
  --line "0.1,0.55,0.9,0.55"

RTSP Stream

python main.py --output-dir outputs rtsp \
  --input "rtsp://user:password@host:554/stream"

RTSP mode behaves differently from offline video mode:

  • The stream is sampled at one processed frame per second
  • Statistics are isolated into 30-minute windows
  • Each completed window writes one JSON file
  • latest.json is overwritten on every completed window
  • RTSP mode does not save annotated video by default

Output Files

Each processed video produces:

  • outputs/<video_stem>/<video_stem>.annotated.mp4
  • outputs/<video_stem>/<video_stem>.json

Batch mode also produces:

  • outputs/batch_summary.csv

RTSP mode produces:

  • outputs/rtsp_stream/latest.json
  • outputs/rtsp_stream/windows/stats_YYYY-MM-DD_HH-MM-SS.json

Docker On Ubuntu 24.04 x86_64

The project can be packaged for an x86_64 NVIDIA host with Docker. The expected weight layout is:

  • weights/yolo11n.pt
  • weights/deepface/age_model_weights.h5
  • weights/deepface/gender_model_weights.h5
  • weights/deepface/retinaface.h5

Build the image:

docker build -t people-flow-project:test .

The Docker image uses requirements-docker.txt so the container installs opencv-python-headless instead of the desktop OpenCV wheel.

The image bakes in all runtime weights and copies the DeepFace .h5 files into ~/.deepface/weights during build.

Run the management API container:

docker run -d \
  --name people-flow-project \
  --restart unless-stopped \
  --gpus all \
  --shm-size 1g \
  -p 18082:18082 \
  -e RTSP_URL="rtsp://user:password@host:554/stream" \
  -v /path/to/config:/opt/people-flow/config \
  -v /path/to/outputs:/opt/people-flow/outputs \
  people-flow-project:test

Or use Compose:

docker compose up --build people-flow-project

Container behavior:

  • Seeds config/local.yaml from config/config.example.yaml when needed
  • Writes RTSP updates through the child API to runtime.rtsp_url
  • Exposes GET /api/manage/health on http://127.0.0.1:18082
  • Persists config and outputs through mounted ./config and ./outputs

Notes

  • minor means age < 18
  • adult means age 18-59
  • senior means age >= 60
  • Tracks without a reliable face result are counted only in total_people and unknown_attributes