Empirical calibration for DJL face_feature (ArcFace/FaceNet 512-d) embeddings: cosine distance bands, piecewise confidence formula, enrollment quality targets. Replaces the dlib-based jbaruch/face-recognition-calibration tile for Kotlin/JVM pipelines.
81
86%
Does it follow best practices?
Impact
100%
2.17xAverage score across 2 eval scenarios
Passed
No known issues
When working with DJL face_feature (PyTorch engine, ArcFace-derived, 512-d L2-normalized embeddings, cosine distance):
face-recognition-confidence-djl skill)d ≤ 0.30 → 1.0 (strong)d ≥ 0.65 → 0.0 (reject)conf = (0.65 - d) / 0.351 - d / tolerance formula. With tolerance = 0.6 and a strong match at d ≈ 0.30, that returns 0.50 — strong matches compress into the middle "yellow" band of any UI built on top.d = 1 - cos(θ), so d ∈ [0, 2].| Band | Distance | Interpretation | Bulb behavior |
|---|---|---|---|
| strong | 0.18 – 0.40 | known person, normal pose | identity color, conf = 1.0 |
| borderline | 0.40 – 0.60 | known person, off-angle / blur | identity color, conf 0.14–0.71 |
| reject | > 0.65 | unknown person (or no enrollment match) | white / "unknown" |
| garbage | > 0.85 | Haar false-positive face, not a real face | drop the detection entirely |
Image.Flag.COLOR returns RGB tensors. The bundled face_feature model was trained on this convention. Do not swap to BGR unless you specifically validated that. Stage 2 in this repo runs RGB → strong matches at d≈0.20. Swapping to BGR makes everything > 0.6.face-recognition-enrollment)<0.15 = overfit; >0.45 = loose cloud (likely bad photos).The Haar cascade that works fine for runtime (scaleFactor=1.2, minNeighbors=4, minSize=60×60) sometimes fails on enrollment JPGs (different pose, lighting). For enrollment ONLY, use a fallback chain:
val attempts = listOf(
Triple(1.2, 4, 60), // strict (matches live runtime)
Triple(1.1, 3, 60),
Triple(1.05, 3, 40),
Triple(1.05, 2, 30) // very loose
)Return the largest face from whichever attempt fires first. Never use these loose params at runtime — they produce false-positive faces that pollute the recognition pipeline.
face-recognition-persistence)iot-actuator-patterns-kotlin is actuator-side. They compose.~/.djl.ai/cache/ ahead of demo time. Don't trust conference Wi-Fi.face_feature model URL is https://resources.djl.ai/test-models/pytorch/face_feature.zip (used in DJL examples). It downloads ~100MB on first model load.Full skill reference: skills/face-recognition-confidence-djl/SKILL.md.