Work / Lab
EyeOS
Webcam eye tracking as an input device: MediaPipe gaze moves the Windows cursor behind a four-gate safety model.
- Python
- OpenCV
- MediaPipe Face Mesh
- pywin32
- websockets
- TypeScript
- Vite
- three.js
TL;DR
- EyeOS explores a plain webcam as an OS input device: gaze moves the Windows cursor like a joystick.
- The design centres on safety. The cursor moves only when four independent gates all pass.
- It’s a design-stage prototype: it never ran end to end, so calibration and latency are unmeasured.
The design
A Python daemon runs MediaPipe Face Mesh with iris landmarks and turns the iris’s offset from the eye corners into a gaze vector, plus a blink signal from the eye aspect ratio. The vector is smoothed with a dead zone, an exponential moving average and dwell detection, then drives the cursor through Win32 SendInput.
The four gates: an explicit Ctrl+Alt+E opt-in, an ESC kill switch, the daemon’s own window holding focus, and an ACTIVE status. A localhost WebSocket feeds the same gaze stream to a three.js scene built to steer its camera with your eyes.
Four gates instead of one toggle → an input device that moves the cursor for you has to be trivially stoppable → more states to get right, and every one of them has to be tested.
Next
Run it end to end, replace the stub calibration step with a real one, and measure how steady the cursor is before anything else.
Verified numbers
| Metric | Value | Source |
|---|---|---|
| Blink threshold (eye aspect ratio) | < 0.18 | local: eyeos/daemon/gaze.py:83 |
| Cursor safety gates | 4 | local: eyeos/daemon/state.py:76-84 |