OcuPi is a real-time drowsiness/fatigue detection tool that watches a webcam feed and warns you when you look like you're falling asleep. It tracks eye closure and yawning via face-landmark analysis, computes a live drowsiness score, and fires audio alerts when you cross a threshold — with a calibration step that adapts to your own face rather than using fixed, one-size-fits-all thresholds.
It can run completely headless in the background, or with a Tkinter diagnostic dashboard showing live video, metrics, and controls.
NOTICE: The project is unmaintained and will not be updated in any significant manner after the initial release. Future use of the project without updates, adjustments, or any further improvements is NOT RECOMMENDED. The Linux components of the project is NOT INCLUDED in the repository. The developer and the authors of OcuPi DOES NOT ENTERTAIN informal requests for the research paper or any of its section without stating the requesting party's purpose and provision of academic assurance of which it is being requested, including but not limited to the methods, the sample demographics, etc., and WILL NOT ENTERTAIN any requests for the Linux disk image used to operate the OcuPi project on its hardware. The research paper was published inside the City of San Jose Del Monte National Science High School and could be acquired upon direct request and permission with the institution. Please be guided.
OcuPi has been recognized at multiple levels of academic science and technology competitions for its innovation and impact on public safety.
- Top Placer – School Science and Technology Fair (SSTF) – Innovation Category
- Champion – Division Science and Technology Fair (DSTF) – Innovation Category
- 4th Place – Regional Science and Technology Fair (RSTF) – Innovation Category
- Special Award for Public Safety – National Science and Engineering Fair (NSEF) – Experimental Category
- Face landmarks — MediaPipe Face Mesh locates facial landmarks in each frame.
- EAR (Eye Aspect Ratio) — computed from 6 landmarks per eye. Drops as the eye closes.
- MAR (Mouth Aspect Ratio) — computed from mouth landmarks. Rises when the mouth opens wide (yawning).
- Calibration (~4 seconds at startup) — a personal EAR/MAR baseline is captured while you keep your eyes open, mouth closed, and face the camera.
- Adaptive thresholds — once calibrated, an eye counts as "closed" once EAR drops below 70% of your baseline, and a yawn is flagged once MAR exceeds 1.8× your baseline (minimum 0.5).
- PERCLOS — percentage of frames with eyes closed over a rolling 10-second window (the standard fatigue metric used in driver-monitoring research).
- Drowsiness score (0–100%) — a weighted blend:
50% PERCLOS + 25% EAR deviation + 20% yawn fraction + 5% MAR deviation, smoothed with an exponential moving average. - Hysteresis — the "drowsy" flag turns on at a score of 60% and only turns back off below 45%, so the alert doesn't flicker on borderline readings.
- Alerts fire when: eyes stay closed for ~12 consecutive frames (~0.4s), the smoothed score stays above threshold for a sustained interval, or no face has been visible for ~10 frames (~0.33s).
- Headless mode (default) — auto-detects and connects to a camera, auto-calibrates on every startup, and runs detection in the background with no video window.
- GUI mode (
--gui) — Tkinter dashboard with a scrollable control panel, live annotated video feed, camera scan/connect/switch controls, calibration caching (reuses a saved baseline instead of recalibrating every run), volume slider, sound on/off and 5-second silence, manual recalibration, and live CPU/memory readouts. - Multi-backend camera scanning — probes V4L2 on Linux, DirectShow/MSMF on Windows, and AVFoundation on macOS, and can hot-switch between multiple detected cameras.
- Audio alerts — distinct sounds for drowsiness, no-face-detected, and calibration start/end, played via
pygame; falls back to a system beep ifpygameor the sound files aren't available. - Calibration persistence — baseline EAR/MAR values are saved to
ocupi_calibration.json(used in GUI mode; headless mode always recalibrates fresh on startup). - Session logging — every run writes a timestamped log to
OcuPi_BlackBox/containing session metadata, system info, calibration events, drowsiness state changes, alerts, and periodic EAR/MAR/score samples. - System resource monitoring — process and system-wide CPU/memory usage via
psutil.
opencv-python
mediapipe
numpy
psutil
pygame # optional — enables audio alerts; falls back to a system beep otherwise
pillow # required only for --gui mode (tkinter image display)
Tkinter itself must be available on the system Python (python3-tk on most Linux distros) for --gui mode; if it's missing, OcuPi prints a warning and falls back to headless mode automatically.
Optional sound files, placed in the same directory as the script:
| File | Alert |
|---|---|
alarm.wav |
Drowsiness detected |
NoFace.wav |
No face detected |
CalibStart.wav |
Calibration started |
CalibEnd.wav |
Calibration finished |
Missing files or a missing pygame install don't stop the app — it just falls back to a system beep.
# Headless mode: auto-connects to a camera, calibrates, and starts detecting
python OCUPI.py
# GUI mode: opens the Tkinter diagnostic dashboard
python OCUPI.py --guiOn startup, headless mode prints the available controls (silence, recalibrate, toggle video, switch camera, quit) to the console as a reference alongside the live log output.
ocupi_calibration.json— saved EAR/MAR baseline and calibration timestamp.OcuPi_BlackBox/ocupi_session_<timestamp>.log— full session log (system info, detection config, audio status, and a timestamped event/frame trail) written fresh each run.
- Detection always runs at a fixed 640×480 / 30fps camera configuration ("Full Computer Mode"); there is no reduced/optimized profile in this version.
- Calibration quality matters a lot — keep your eyes open, mouth closed, and face square to the camera during the ~4-second calibration window, since the whole threshold system is derived from that baseline.
- Headless mode recalibrates every time it starts; GUI mode reuses the last saved calibration unless you force a recalibration.
This project is released under the MIT License.
See the LICENSE file for more details.
Developed by Marc Lawrence D. Dizon
With support from J. Rodriguez & R. Punzalan, research project teammates.
Built with Python, OpenCV, MediaPipe, and Tkinter.
Dedicated to improving road safety through computer-based driver monitoring.