Skip to content

Enable face/eye analysis

The closed-eyes / blink and facing/smile cull signals come from the face/eye provider. Like every heavy provider it's off by default — cull still runs blur, exposure and dedup without it. Turn it on to add the eye signals.

Turn it on

Set face.enabled in your config, either in the config file:

face:
  enabled: true

or via an environment variable:

export KRITES_FACE_ENABLED=true

On the next cull, krites fetches and checksum-verifies the pinned ONNX models and the ONNX Runtime library itself (once each), then runs them on-device — nothing leaves your machine. There's no runtime to install or path to set: the library is bundled in the macOS app and fetched from the signed artefact channel elsewhere (onnxruntime.library_path is an optional override; see the config reference).

Apple Silicon

Run the models on the CoreML execution provider (falls back to CPU if unavailable):

face:
  execution_provider: coreml

Trained expression (smile ↔ frown)

By default the smile signal is a geometric mouth-curvature estimate — cheap but weak. For a trained read of smile, frown, and a grumpy ↔ happy valence, switch to the MediaPipe strategy:

face:
  enabled: true
  strategy: mediapipe

UltraFace still finds the faces; two extra ONNX models (MediaPipe FaceMesh + blendshapes) run on each face to score its expression. The studio's diverging Expression axis then reflects the scene's real mood — a single unsmiling guest no longer drags a whole group shot to "grumpy", and a genuinely frowning face reads negative rather than merely "not smiling". Re-cull after switching. Details and the tunable Duchenne / brow weights are in the config reference and the default mediapipe strategy.

Unlike the other models (fetched from third-party hosts and pinned by checksum), these two are published as a signed krites-models release we control. On first use krites downloads the release manifest and verifies its OpenPGP signature against a key embedded in the binary (pinned by fingerprint), confirms each model's checksum against that signed manifest, and asserts its provenance (source + Apache-2.0 licence) — before a single model byte is trusted. A failure at any step refuses the model rather than using it. See the model licensing note.

Tune the thresholds

The eye/smile/facing cutoffs are starting points. For example, to treat eyes as closed more readily, raise face.ear.closed. All keys and their defaults are in the configuration reference; the reasoning is in Why the heavy providers are opt-in.

Then re-cull to apply:

krites cull --shoot ~/Pictures/smith-wedding