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:
or via an environment variable:
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):
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:
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: