FaceKit
Pure Dart Offline Facial Recognition Engine — for Dart & Flutter (iOS, Android, Web, Desktop, & Server)
Built by Innoartive Labs · Zero Dependencies
Why Pure Dart?
Developing facial recognition applications on Flutter often involves fighting native build toolchain failures (C++ CMake, Android NDK, iOS CocoaPods, TFLite/ONNX runtime version mismatches).
FaceKit takes a different approach by running 100% pure Dart:
- Zero Native Dependencies: No C/C++ bindings, no external ML runtimes (no TensorFlow, no TFLite, no OpenCV, no ONNX, no MediaPipe).
- 100% Cross-Platform: Runs identically across iOS, Android, Web, macOS, Windows, Linux, and Dart CLI.
- Tiny Footprint: Entire engine and model footprint is $\approx 130\text{ KB}$ (compared to 15MB–100MB native models).
- Architectural Tradeoff: Designed as a lightweight, fast CPU engine for on-device applications rather than a heavy GPU deep neural network.
Key Features
- 100% Offline Biometrics: Zero cloud APIs, zero remote network calls, complete user data sovereignty.
- Fast Local Execution: Sub-15ms end-to-end latency on Desktop and Mobile CPU engines.
- Multi-Scale Spatial Descriptor Engine: Spatial LBP & HOG feature grid descriptor projecting faces onto a 128-dimensional L2 unit hypersphere.
- Custom Binary Persistence: Compact
.facebinary format serialization (CRC32-checked) and JSON export/import adapters.
🔒 Privacy & Architecture Alignment
FaceKit is designed to support GDPR/HIPAA-aligned privacy architectures by ensuring all biometric data remains strictly on-device:
- Complete Data Sovereignty: Landmark extraction, feature embedding, and face matching occur 100% locally in device memory.
- Zero Remote Telemetry: No network dependencies, no cloud endpoints, and no remote data collection.
- Multi-Tenancy Isolation: Every application runs an isolated in-memory registry instance. Registered data is never shared across apps or organizations.
- Compliance Note: While
FaceKitprovides total technical data sovereignty, overall GDPR/HIPAA compliance depends on your host application's user consent flows, retention policies, and security controls.
Technical Specifications Summary
- Detector: Multi-scale image pyramid ($24 \times 24$ sliding window) with IoU Non-Maximum Suppression and adaptive contrast fallback.
- Landmarks: 68 primary facial keypoints and 468 dense 3D mesh points with pupil intensity minimum search.
- Alignment: Similarity transformation leveling eye roll angle ($\theta = \arctan2(\Delta y, \Delta x)$) and normalizing to canonical $112 \times 112$ format.
- Feature Extractor: Multi-cell spatial LBP + HOG gradient descriptor projecting onto a 128-dimensional L2-normalized vector ($|\mathbf{v}|_2 = 1.0$).
Quick Example
import 'package:facekit/facekit.dart';
void main() async {
final facekit = FaceKit();
// Register a subject
await facekit.register(
image: faceImage,
personId: "EMP001",
name: "John Doe",
);
// Recognize subject from query image
final result = await facekit.recognize(queryImage);
if (result.matched) {
print('Matched Person ID: ${result.personId}');
print('Name: ${result.name}');
print('Confidence: ${(result.confidence * 100).toStringAsFixed(1)}%');
}
}
External Database Integration & Persistence
FaceKit makes it easy to persist and synchronize face records across external databases such as SQLite, MySQL, MariaDB, PostgreSQL, Supabase, Firebase, Hive, Isar, or MongoDB:
// 1. Extract raw 128D embedding vector bytes (512 bytes)
final Uint8List rawBytes = record.embedding.values.buffer.asUint8List();
// 2. Save into SQLite / PostgreSQL BLOB column:
await db.insert('persons', {
'person_id': record.personId,
'name': record.name,
'embedding_blob': rawBytes,
});
// 3. Load from database and populate FaceKit anytime:
final rows = await db.query('persons');
for (final row in rows) {
final Uint8List blob = row['embedding_blob'];
facekit.matcher.addRecord(
PersonRecord(
personId: row['person_id'],
name: row['name'],
embedding: FaceEmbedding(Float32List.view(blob.buffer)),
),
);
}
// 4. Recognize instantaneously (<0.1 ms in-memory search)
final result = await facekit.recognize(queryImage);
Persistence Formats
- Compact
.faceBinary Buffer:exportPersonBinary('EMP001')generates a CRC32-checksummed binary buffer (~550 bytes) perfect for BLOB columns or REST APIs. - Full JSON Database Export/Import:
exportDatabaseJson()andimportDatabaseJson()convert the entire face registry to/from JSON strings for NoSQL stores like Firebase Cloud Firestore or MongoDB.
⚠️ Known Limitations & Design Tradeoffs
To ensure correct developer expectations pre-launch:
- Pose Sensitivity: Best suited for frontal and semi-frontal faces ($\le \pm 30^\circ$ yaw/pitch angle).
- Illumination Requirements: Requires reasonable ambient lighting. Includes auto-contrast enhancement pass, but extreme darkness degrades resolution.
- Model Footprint vs Deep Networks: Designed as a lightweight CPU spatial feature engine ($\approx 130\text{ KB}$ footprint) rather than a heavy GPU deep neural network (e.g. 100MB FaceNet).
- Liveness Detection: Liveness anti-spoofing (blink/motion detection) is currently on the development roadmap and not included in v1.0.0.
Performance Benchmarks Summary
Benchmarked on Intel Core i7 / AMD Ryzen 7, Windows 11, Dart SDK 3.10.8 JIT/AOT mode:
- End-to-End Registration Latency: $14.90\text{ ms}$ / subject
- End-to-End Recognition Query Latency: $14.30\text{ ms}$ / query
.faceBinary Format Throughput: $0.068\text{ ms}$ / operation
For complete hardware details, JIT vs AOT benchmarks, and evaluation metrics, read doc/BENCHMARKS.md.
Documentation Links
- Technical Architecture Specification
- Performance & Metric Benchmarks
- API Reference Guide
- Future Development Roadmap
License & Credits
Developed and maintained by Innoartive Labs.
Released under the MIT License.
Libraries
- facekit
- Pure Dart offline facial recognition engine.