This is an architecture reference, not a tutorial. For integration guidance, see rPPG In A Browser App and rppg-web Getting Started.
Summary
The rPPG system extracts heart rate and optional ocular features from camera video, then produces calibrated, probabilistic bandpower proxies with confidence scores. A hybrid model keeps capture and vision in JS or native code, while DSP and metrics live in shared Rust/WASM/FFI modules.Goals
- Single processing core for web, iOS, Android, and desktop
- On-device processing (no raw video leaves the device)
- Stable metrics with explicit confidence and quality gating
- Clear separation between capture/vision and DSP
Non-Goals
- Replacing clinical EEG or producing diagnostic-grade signals
- Reconstructing full multi-channel EEG from webcam
- Shipping training pipelines in production builds
High-Level Pipeline
- Camera capture via
getUserMedia(web) or native camera APIs - Face/ROI tracking using MediaPipe tasks
- ROI pixel stats extracting average RGB and green channel values
- rPPG DSP core with bandpass filtering, temporal normalization, and HR/HRV estimation
- Optional fusion combining ocular features with rPPG signals
- Metrics + confidence for app consumption
Components
Capture and ROI (Platform-Specific)
| Platform | Capture | Face Detection |
|---|---|---|
| Web | getUserMedia | MediaPipe tasks (face/landmarks) |
| iOS / Android | Native camera APIs | Native MediaPipe |
rPPG DSP Core (Shared Rust Module)
The core Rust module consumes{timestamp, intensity} samples and runs:
- Temporal normalization
- Bandpass filtering (0.7-4.0 Hz for heart rate)
- Periodogram HR estimation with ACF fallback and harmonic checks
bpm, confidence, signal_quality, and optional debug data.
Ocular Features (Optional)
Optional capture-side features used for fatigue and arousal fusion:- Blink rate and PERCLOS (percentage of eye closure)
- Gaze stability
- Pupil dynamics
Fusion and Sentiment (Optional, Modular)
A separate module consuming rPPG + ocular features to produce coarse indices:fatigue_indexarousal_scorefocus_proxy
Distribution Strategy
| Target | Approach | Package |
|---|---|---|
| Web | Rust to WASM via the internal elata-rppg-wasm crate, wrapped by rppg-web for a stable TS API | @elata-biosciences/rppg-web |
| Native | Rust to FFI via the internal elata-rppg-ffi crate | Internal binding crate |
| Compatibility | Constructors also available through the internal elata-eeg-wasm / elata-eeg-ffi crates | @elata-biosciences/eeg-web |
Quality, Calibration, and Uncertainty
- Always publish a signal quality index (SQI)
- Require per-user baseline (60-120 seconds) for proxy metrics
- Emit confidence or prediction intervals for proxy metrics
- Gate app behavior on SQI and confidence
Benchmarking
- Use pyVHR offline for algorithm validation and regression tests
- Compare HR error under motion, lighting, and elevated HR conditions
- Use strict splits (leave-one-subject/context out)
Next
rPPG Getting Started
Install and use the rPPG package
Calibration and Fusion
Muse PPG calibration models
rPPG Camera Integration
End-to-end webcam pipeline
Frame Sources
MediaPipe face detection