Crowd risk estimation through spatial intelligence.
Disperse is a research tool for urban designers, event planners, and safety analysts. Select any location on a live satellite map, annotate crowd obstructions, and receive an AI-generated heatmap estimating pedestrian flow and density risk — without sensors, surveys, or on-the-ground data.
The analysis pipeline runs in three stages:
- Satellite extraction — A high-resolution 512×512 satellite tile is pulled from the Mapbox API for the selected location.
- Road segmentation — A Keras model identifies walkable road surfaces in the image and produces a binary road mask.
- Crowd prediction — A second Keras model takes the road mask combined with user-drawn annotations (focal points, vehicles, barriers) and outputs a crowd density heatmap, overlaid on the original satellite image.
Annotations encode three types of real-world crowd dynamics:
| Annotation | Colour | Effect on model |
|---|---|---|
| Focal Point | Red | Marks crowd attraction zones (stages, entrances, exits) |
| Vehicle | Yellow | Partial obstruction — reduces road walkability by 50% |
| Barrier | Green | Full obstruction — blocks road segment entirely |
Disperse/
├── backend/ # FastAPI server
│ ├── main.py # API routes, model inference, image pipeline
│ └── requirements.txt # Python dependencies
│
├── frontend/ # React + Vite dashboard
│ ├── src/
│ │ ├── App.jsx # Full application (landing, map, analysis)
│ │ └── assets/ # Logo and background image
│ ├── .env # Local environment variables (not committed)
│ ├── .env.example # Variable template
│ └── package.json
│
├── data/ # Runtime-generated image data (not committed)
│ ├── images/ # Downloaded satellite tiles
│ ├── masks/ # User annotation masks
│ ├── segmentation/ # Road segmentation outputs
│ └── output/ # Final crowd heatmap overlays
│
├── models/ # Trained Keras models (not committed)
│ ├── segmentation.keras # Road segmentation model
│ └── crowd.keras # Crowd density prediction model
│
├── .env.example # Root-level env variable reference
├── .gitignore
├── PRD.md
└── README.md
- Python 3.10+
- Node.js 18+
- A Mapbox account and public access token
- Trained model files:
segmentation.kerasandcrowd.kerasplaced inmodels/
cd backend
# Create and activate a virtual environment
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS / Linux
# Install dependencies
pip install -r requirements.txt
# Start the API server
uvicorn main:app --reload --host 127.0.0.1 --port 8000The API will be available at http://127.0.0.1:8000.
Interactive docs (Swagger UI) at http://127.0.0.1:8000/docs.
Note: The backend loads both Keras models at startup. Allow 10–30 seconds on first run depending on hardware.
cd frontend
# Install dependencies
npm install
# Configure environment
cp .env.example .env
# Open .env and fill in your VITE_MAPBOX_TOKENEdit frontend/.env:
VITE_MAPBOX_TOKEN=pk.your_mapbox_token_here
VITE_API_BASE_URL=http://127.0.0.1:8000# Start the dev server
npm run devThe dashboard will be available at http://localhost:5173 (or the next available port).
| Variable | Service | Description |
|---|---|---|
VITE_MAPBOX_TOKEN |
frontend | Mapbox public access token — used for the satellite map and static tile API |
VITE_API_BASE_URL |
frontend | Base URL for the backend API (default: http://127.0.0.1:8000) |
See .env.example at the project root for the full reference. Never commit frontend/.env.
| Method | Endpoint | Description |
|---|---|---|
POST |
/save-satellite-image |
Downloads and saves a satellite tile by URL and image ID |
POST |
/get-segmentation |
Runs road segmentation on a saved image, returns base64 PNG |
POST |
/save-mask |
Saves user annotation shapes as a colour-coded mask image |
POST |
/run-crowd |
Runs crowd prediction using the road mask and annotation mask, returns base64 heatmap |
Both models are Keras .keras format and must be placed in the models/ directory at the project root before starting the backend.
| File | Task | Input | Output |
|---|---|---|---|
segmentation.keras |
Semantic segmentation | 512×512 RGB satellite image | Binary road mask |
crowd.keras |
Crowd density estimation | 512×512 RGB composite (attraction, obstruction, walkability channels) | Normalised density heatmap |
The crowd model input is a physically-constructed RGB image:
- R channel — focal attraction strength
- G channel — obstruction presence (vehicles + barriers)
- B channel — walkable road area (after applying obstructions)
Models are excluded from version control due to file size. Use Git LFS if you need to track them in the repository.
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite 7, Mapbox GL JS, React Konva |
| Backend | FastAPI, Uvicorn |
| ML Inference | TensorFlow / Keras |
| Image Processing | OpenCV, Pillow, NumPy |
| Map Data | Mapbox Satellite API |