Vital-Sign
Read your heart rate straight from your phone camera — no wearable needed — so logging your vitals and staying on top of a fitness routine takes seconds.
You point your phone camera at your face and it reads your heart rate. No chest strap, no watch — just the camera you already carry. The idea came out of conversations with people at NRC Canada, where I first learned about rPPG (remote photoplethysmography). It stuck with me because of how much you can do with a plain camera, and I wanted something that made logging your vitals quick enough to actually keep up with alongside a fitness routine.
What it does
It measures your heart rate contactlessly, in real time, from a normal webcam or phone camera, and gives you live feedback on whether your lighting is good enough for a clean reading. Everything runs locally — frames are never stored or sent anywhere — so it stays private by default. The point is friction: a reading takes seconds, so checking in and keeping a log doesn't feel like a chore.
How it works
rPPG works off the tiny color changes in your skin as blood pulses through it — invisible to the eye, but a camera can pick them up. MediaPipe locks onto your face and tracks the regions that carry the cleanest signal, then I pull the green channel from those areas and run it through a signal-processing pipeline: detrending, a Butterworth bandpass filter (0.8–3.0 Hz, the physiological range), and Welch's spectral analysis to find the dominant frequency. The peak in that range is your heart rate. It's a Flask backend with a React frontend, containerized with Docker and covered by tests and CI.
What I learned and where it's going
Most of the work was in the signal, not the app — good lighting and a still head make a real difference, and a lot of the build was about getting a stable reading out of a noisy one. There's a lot of headroom here: I want to push the accuracy further, add heart-rate variability and respiratory rate, and eventually train a model to estimate vitals more robustly across conditions rather than relying purely on the classical pipeline. It's the project I most want to keep making better.