An open API service indexing awesome lists of open source software.

https://github.com/25thr/blinkd

Real-time blink detection engine turning blinks into actions for games, accessibility, and next-gen interfaces.
https://github.com/25thr/blinkd

assistive-technology computer-vision eye-tracking game-engine godot opencv unity3d unreal-engine video-game

Last synced: 2 months ago
JSON representation

Real-time blink detection engine turning blinks into actions for games, accessibility, and next-gen interfaces.

Awesome Lists containing this project

README

          

**Real-time blink detection engine turning blinks into actions for games, accessibility, and next-gen interfaces.**

`blinkd` is essentially a **low-level, hardware-agnostic, eye-blink input layer**, like a **"blink driver"** for real-time interactions.

**Note for builders**

*`blinkd` is a low-level input system. It does one thing well: turn eyelid signals into clean events. Designed to be real-time and input-source neutral. If you're building with it, you're building from the metal up.*

### Get Ollo SDK

For production-grade eye-tracking, the **[Ollo SDK](https://ollosdk.com/)** offers a complete, high-performance solution with:

* **Plug-and-play tracking** for reliable detection out of the box
* **Low-latency, high-performance pipelines** with platform-specific optimizations
* **High-reliability blink and eye tracking** for demanding applications
* **Native bindings** for popular game engines: Unity, Unreal, and Godot 3/4
* **C++ API with asynchronous pipelines** for flexible integration
* **Cross-platform packaging** for Windows, macOS and Linux
* **Secure on-device processing** to protect user data
* **GPU acceleration** for maximum performance

> **[![Beta Free](https://img.shields.io/badge/Beta-Free-brightgreen)](https://ollosdk.com/) Exciting news:** As of now, the Beta version of **[Ollo SDK](https://ollosdk.com/)** is [available](https://ollosdk.com/) for **evaluation use at no cost**.

> Get early access and be among the first to supercharge your game dev projects with cutting-edge eye tracking!

**[Ollo SDK](https://ollosdk.com/)** delivers a full computer-vision pipeline with ML-based eye tracking, enabling robust, production-ready solutions while keeping integration seamless.

This could become foundational tech for:

* **Games**
* **Accessibility**
* **AR/VR**
* **Biometric interfaces** _(fatigue detection, attentiveness)_
* **Expression-based UI** _(hands-free UI control)_

We're building a **real-time eye input system**, which:

1. Ingests camera data
2. Processes it into a clean binary event stream (`BLINK`, `LONG_BLINK`, `WINK_LEFT`, etc.)
3. Exposes that stream via standard IPC (UDP, shared memory)
4. Can be extended as a **system input driver**

## Features

The C implementation which is language-agnostic comes with,

- **Simple**: Not super accurate by design
- Works out-of-the-box
- **Real-time detector**: EMA-based adaptive thresholds + hysteresis + refractory
- Handles **one or two eyes**: Emits `BLINK`, `LONG_BLINK`, `DOUBLE_BLINK`, `WINK_LEFT`, `WINK_RIGHT`
- **IPC built-in**: UDP JSON events for game engines (Unreal Engine, Godot, Unity), plus an _optional POSIX shared-memory ring buffer_ for high-rate pipelines
- **O(1)** per sample: No external deps for the core

## Usage

For developers interested in seeing **Blinkd** in action with **Godot 4**, we provide a minimal demo in a separate repository: [**blinkd-godot-demo**](https://github.com/25thr/blinkd-godot-demo).

This demo showcases a single scene where blink events drive gameplay.

* **3D sphere flashes** when a blink is detected
* **UI label updates** with blink count and timing
* Serves as a **reference for integrating Blinkd** into your own Godot projects
* Lightweight and easy to run

Demonstrates **real-time blink-driven input** without complex camera setups.

## Architecture


Architecture diagram

## Blinkd vs Ollo SDK

| Feature | Blinkd | Ollo SDK |
|--------|------------|------------|
| Core detector | EMA + FSM | Native landmark pipeline |
| Accuracy | ⭐⭐☆☆☆ | ⭐⭐⭐⭐⭐ |
| EAR input | external only | Baked-in |
| Head pose | ❌ | Advanced head-pose correction algorithms |
| Eye landmarks | ❌ | 6 / 468 / 478 landmark sets |
| Backends | ❌ | Enterprise + Dlib (as fallback) |
| FPS | 30-60 (depends on source) | 60-120 (optimized) |
| Game engines support | via UDP | native bindings |
| IPC | UDP + POSIX shm | Direct API events |
| Intended for | Hobbyists, testing | Game development, VR/AR, interactive real-time experiences |

### Feeding

Provide _openness_ in `[0..1]` per eye at ~120-240 Hz. Map any upstream signal to that range, e.g.:

- **Eye Aspect Ratio (EAR)**: normalize per-user to `[0..1]`
- **Iris/eyelid distance** or **segmentation % open**
- **IR camera "eye open probability"** from a ML model
- The detector handles baseline drift and noise adaptively.

### IPC for engines

* **UDP JSON** (zero dependencies):
`{"t_ms":123456,"type":"blink","dur_ms":132,"flags":3}`

We can also expose a local WebSocket API _(to be implemented)_,

```bash
ws://localhost:8765
```

#### Shared-memory IPC support (POSIX only)

* It creates a named shared memory region (`/blinkdring`) that both producer (camera pipeline) and consumer (game engine or monitor tool) can map.
* Each slot is a `BlinkdSample` (timestamp + two openness floats).
* The ring uses simple head/tail pointers with `__sync_synchronize()` memory barrier.
* You can push samples at 200 Hz safely from one process and consume from another with minimal overhead.

**Usage example (producer):**

```c
BlinkShm* shm = blink_shm_open("/blinkdring", 4096);
while(1){
float L = 0.9f, R = 0.8f;
uint32_t t = (uint32_t)(clock()*1000/CLOCKS_PER_SEC);
blink_shm_push(shm, t, L, R);
usleep(5000);
}
blink_shm_close(shm);
```

The consumer (another process) can map the same `/blinkdring` and read in a loop.

### Tuning

The `blinkd` SDK provides several configuration options to fine-tune blink detection based on camera quality, user behavior, or latency tolerance. You can adjust sensitivity, detection timing, and noise rejection using the tuning API.

### Default behavior

When you create a `BlinkdHandle` via `blinkd_create()`, it initializes with **default balanced parameters**:

```c
blinkd_set_thresholds(h, 2.5f, 1.5f); // close_k, open_k
blinkd_set_timing(h, 40, 400, 800, 300, 60); // min, long, max, dbl_gap, refractory
```

#### Thresholds

These control how tightly the system defines a "closed" or "open" eye, relative to baseline noise:

```c
void blinkd_set_thresholds(BlinkdHandle* h, float close_k, float open_k);
```

* `close_k`: How many deviations below baseline to consider "closed"
* `open_k`: How many deviations below baseline to consider "open"

Lower values increase sensitivity; higher values are more conservative.

#### Timing

```c
void blinkd_set_timing(BlinkdHandle* h,
uint32_t min_blink_ms,
uint32_t long_blink_ms,
uint32_t max_blink_ms,
uint32_t double_gap_ms,
uint32_t refractory_ms);
```

* `min_blink_ms`: Minimum duration to count as a blink
* `long_blink_ms`: Threshold for long blinks
* `max_blink_ms`: Max duration before ignoring as noise
* `double_gap_ms`: Time window for detecting double blinks
* `refractory_ms`: Cooldown time after a blink before accepting another

#### EMA

```c
void blinkd_set_ema_alpha(BlinkdHandle* h, float alpha); // default: 0.01
void blinkd_set_noise_alpha(BlinkdHandle* h, float alpha); // default: 0.02
```

These control how quickly the algorithm adapts to baseline changes or noise. Smaller = smoother, but slower.

#### Wink detection

```c
void blinkd_set_wink_min(BlinkdHandle* h, uint32_t wink_min_ms);
```

This sets the **minimum duration** for a one-eye blink to qualify as a wink.

#### Presets

To simplify tuning, you can use one of the built-in presets:

```c
void blinkd_set_preset(BlinkdHandle* h, BlinkdPreset preset);
```

Available presets:

* `BLINKD_PRESET_LOW`: For noisy input (e.g. low-res cams, shaky face)
* `BLINKD_PRESET_HIGH`: For clean input, fast detection
* `BLINKD_PRESET_BALANCED` *(default)*: Safe middle ground

### Example: Custom configuration

```c
BlinkdHandle* h = blinkd_create(init_open);
blinkd_set_thresholds(h, 2.8f, 1.4f);
blinkd_set_timing(h, 50, 300, 750, 250, 50);
blinkd_set_ema_alpha(h, 0.02f);
blinkd_set_noise_alpha(h, 0.03f);
blinkd_set_wink_min(h, 70);
```

## Build & run

```bash
cmake --build . --config Release
# Stream samples via stdin (time_ms openL openR), broadcast to localhost:7777
./blinkdctl
```

Clients (apps, game engines, etc.) can easily consume them.

## Limitations

**Blinkd** focuses on being tiny and dependency-free.

- No advanced processing pipeline or fallbacks
- No advanced head-pose correction techniques, smoothing filters and algorithms
- No customer support

**All of these features are available in the [Ollo SDK](https://ollosdk.com/).**

## Upgrading to Ollo SDK

If you outgrow the basic EAR-only detector, **[Ollo SDK](https://ollosdk.com/)** offers better performance and seamless migration from the Blinkd SDK, letting you scale to production with **minimal changes**.