Spaces:
Sleeping
Sleeping
FocusGuard
Webcam-based focus detection: MediaPipe face mesh β 17 features (EAR, gaze, head pose, PERCLOS, etc.) β MLP or XGBoost for focused/unfocused. React + FastAPI app with WebSocket video.
Project layout
βββ data/ collected_<name>/*.npz
βββ data_preparation/ loaders, split, scale
βββ notebooks/ MLP/XGB training + LOPO
βββ models/ face_mesh, head_pose, eye_scorer, train scripts
βββ checkpoints/ mlp_best.pt, xgboost_*_best.json, scalers
βββ evaluation/ logs, plots, justify_thresholds
βββ ui/ pipeline.py, live_demo.py
βββ src/ React frontend
βββ static/ built frontend (after npm run build)
βββ main.py, app.py FastAPI backend
βββ requirements.txt
βββ package.json
Setup
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
To rebuild the frontend after changes:
npm install
npm run build
mkdir -p static && cp -r dist/* static/
Run
Web app: Use the venv and run uvicorn via Python so it picks up your deps (otherwise you get ModuleNotFoundError: aiosqlite):
source venv/bin/activate
python -m uvicorn main:app --host 0.0.0.0 --port 7860
Then open http://localhost:7860.
OpenCV demo:
python ui/live_demo.py
python ui/live_demo.py --xgb
Train:
python -m models.mlp.train
python -m models.xgboost.train
Data
9 participants, 144,793 samples, 10 features, binary labels. Collect with python -m models.collect_features --name <name>. Data lives in data/collected_<name>/.
Model numbers (15% test split)
| Model | Accuracy | F1 | ROC-AUC |
|---|---|---|---|
| XGBoost (600 trees, depth 8) | 95.87% | 0.959 | 0.991 |
| MLP (64β32) | 92.92% | 0.929 | 0.971 |
Pipeline
- Face mesh (MediaPipe 478 pts)
- Head pose β yaw, pitch, roll, scores, gaze offset
- Eye scorer β EAR, gaze ratio, MAR
- Temporal β PERCLOS, blink rate, yawn
- 10-d vector β MLP or XGBoost β focused / unfocused
Stack: FastAPI, aiosqlite, React/Vite, PyTorch, XGBoost, MediaPipe, OpenCV.