face_match_kit 0.1.0
face_match_kit: ^0.1.0 copied to clipboard
On-device face detection, guided enrollment, liveness challenges, and 1:1 verification for Flutter.
face_match_kit #
On-device face detection, guided three-pose enrollment, basic liveness, and 1:1 face verification for Flutter on Android and iOS. No Firebase, backend, or internet connection is required.
Beta:
0.1.0is for evaluation. The randomized blink/head-turn flow is a convenience barrier, not presentation-attack detection and not spoof-proof. Accuracy calibration and the physical Android/iOS test matrix are release gates documented in PUBLISHING.md.
What is bundled #
The package brings its own pinned, integrity-checked on-device stack:
- OpenCV YuNet 2023mar for face detection and five landmarks
- OpenCV SFace 2021dec INT8 for 128-dimensional embeddings
- the required MediaPipe face-landmark and blendshape models for guidance
- camera, image decoding, LiteRT, OpenCV, and hashing dependencies
Applications add only face_match_kit; pub resolves its transitive
dependencies and Flutter bundles the required native libraries and four model
assets into the app. The first OpenCV Android build can take several minutes.
Install #
dependencies:
face_match_kit: ^0.1.0
# Required by opencv_dart so its native build contains YuNet and SFace.
hooks:
user_defines:
dartcv4:
include_modules:
- imgproc
- dnn
- objdetect
The hook block is currently required in the consuming application's root
pubspec.yaml; Dart native-asset settings cannot be forced by a transitive
package. It does not add another dependency.
Android requires API 26 or later and camera permission:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.front" android:required="true" />
iOS 15.5 or later requires:
<key>NSCameraUsageDescription</key>
<string>We use the camera for on-device face verification.</string>
Ready-made UI #
FaceEnrollmentView(
onCompleted: (result) async {
if (result.isSuccess) await saveTemplate(result.template!.toJson());
},
);
FaceVerificationView(
template: FaceTemplate.fromJson(savedJson),
onCompleted: (result) {
if (result.isMatch) unlock();
},
);
The widgets own permission handling, camera preview, quality guidance, three-pose capture, basic liveness, retry, lifecycle recovery, and immediate automatic capture after the challenge. Text, colours, thresholds, liveness, callbacks, and the face overlay are customizable.
Capture flows (CaptureFlowPolicy):
guidedEnrollment— front plus both sides in randomized order for enrollment. Live readiness uses the same yaw windows the still-enrollment gate accepts (front ±12°, sides 10–42°).singleTurnVerification— legacy centre, turn, and return sequence.simpleVerification— one straight look only, for easy check-ins. The enrolled centroid already averages all three poses, so turns add friction without accuracy gain.
Successful enrollment also returns registrationImageBytes: a copy of the
front-pose JPEG for host-side review-photo upload (null on failure). The
widget zeroizes its own sample bytes afterwards, so the copy stays valid.
Low-level API #
final kit = await FaceMatchKit.create();
final detection = await kit.detect(jpegBytes);
final enrollment = await kit.enroll(samples: [
FaceSample(imageBytes: front, pose: FacePose.front),
FaceSample(imageBytes: left, pose: FacePose.slightLeft),
FaceSample(imageBytes: right, pose: FacePose.slightRight),
]);
final verification = await kit.verify(
imageBytes: probe,
template: enrollment.template!,
);
await kit.dispose();
Custom camera interfaces use the exported FaceCameraFrame adapter and
detectCameraFrame. Routine failures return typed results; corrupt model
assets or initialization failures throw.
Canonical pipeline and templates #
Encoded still images are size-checked, decoded in Dart, EXIF-oriented,
explicitly unmirrored, deterministically limited to 1600 pixels on the longest
side, converted from RGB to OpenCV BGR, detected with YuNet, aligned with
FaceRecognizerSF.alignCrop, embedded by SFace, and L2-normalized.
Schema-v2 FaceTemplate JSON contains a secure random template ID, exact
model/pipeline identity, three 128-value unit embeddings, their normalized
centroid, and creation time. Parsing rejects unknown fields, wrong lengths,
non-finite values, incompatible identities, non-unit vectors, and centroid
tampering. Every template made by the earlier 192-dimensional pipeline must be
re-enrolled; it cannot be converted safely.
Thresholds and accuracy #
The default cosine threshold 0.363 is only OpenCV's pairwise benchmark
starting point. Comparing against a three-sample centroid has a different score
distribution, and the enrollment-consistency threshold is also provisional.
Before production, calibrate representative genuine, impostor, and mixed-person
pairs. The release target is a measured FAR upper confidence bound at or below
0.1%, FRR at or below 5%, and at least 99.9% mixed-person enrollment rejection.
The JSON format is platform-portable, but equivalent Android/iOS embeddings and all four verification directions remain to be demonstrated on physical devices before a cross-platform accuracy claim.
Privacy and security #
Processing is local and the package makes no network calls. Camera widgets do not deliberately retain images and make a best-effort attempt to delete camera temporary files after reading them; managed memory is not guaranteed to be zeroized. Templates are sensitive biometric data. The host application owns consent, authenticated encryption, account/tenant binding, access control, retention, deletion, revocation, audit, and breach obligations.
See PRIVACY.md, SECURITY.md, MIGRATION.md, and MODEL_CARD.md.
Scope and licence #
Version 0.1 supports cooperative 1:1 verification on Android and iOS. It does not provide 1:N identification, web/desktop support, surveillance, or advanced anti-spoofing.
Package source is Apache-2.0 and may be used commercially subject to its terms and required notices. YuNet carries a separate MIT notice. Model licensing and remaining training-data provenance risk are documented in THIRD_PARTY_NOTICES.md and MODEL_CARD.md; commercial release requires legal acceptance of that remaining risk or authoritative clarification.
