kyc_engine 0.0.1 copy "kyc_engine: ^0.0.1" to clipboard
kyc_engine: ^0.0.1 copied to clipboard

PlatformAndroidiOS
unlisted

A Flutter library for face verification and KYC processes.

KYC Engine πŸ” #

pub package License: MIT

A powerful Flutter package for face verification and KYC (Know Your Customer) processes using TensorFlow Lite. Perfect for identity verification, face matching, and secure authentication systems.

Flutter TensorFlow Firebase


✨ Features #

  • 🎯 Face Verification - Compare two face images with high accuracy (97%+)
  • πŸ†” ID Verification - Verify ID card photos against live selfies
  • πŸ“± On-Device ML - Privacy-first, all processing happens locally
  • ⚑ Fast Performance - 100-300ms inference time
  • πŸ”§ Configurable - Multiple presets for different use cases
  • πŸ”’ Secure - No data leaves the device
  • πŸ“¦ Firebase Integration - Auto-download and cache ML models
  • 🌍 Cross-Platform - Works on iOS and Android

πŸ“Έ Use Cases #

  • KYC/Identity Verification - Verify customer identity for financial services
  • Access Control - Secure building or system access
  • Duplicate Detection - Find duplicate accounts or users
  • Age Verification - Confirm user age matches ID
  • Authentication - Face-based login systems
  • Attendance Systems - Face recognition for check-in/check-out

πŸš€ Quick Start #

Installation #

Add to your pubspec.yaml:

dependencies:
  kyc_engine: ^0.0.1
  firebase_core: ^4.2.1  # Required for model distribution

Then run:

flutter pub get

Basic Usage #

import 'package:kyc_engine/kyc_engine.dart';
import 'dart:io';

// 1. Initialize the engine
final kycEngine = KYCEngine();
await kycEngine.initialize();

// 2. Verify two faces
final result = await kycEngine.verifyFaces(
  File('path/to/id_photo.jpg'),
  File('path/to/selfie.jpg'),
);

// 3. Check the result
if (result.isSamePerson) {
  print('βœ… Match! Confidence: ${result.confidencePercentage.toStringAsFixed(1)}%');
  print('Similarity Score: ${result.similarityScore}');
} else {
  print('❌ No match');
}

πŸ“‹ Setup Guide #

1. Firebase Configuration #

# Install FlutterFire CLI
dart pub global activate flutterfire_cli

# Configure Firebase for your project
flutterfire configure

Option B: Manual Setup

  1. Go to Firebase Console
  2. Create a new project or select existing one
  3. Add your app (Android/iOS)
  4. Download configuration files:
    • Android: google-services.json β†’ Place in android/app/
    • iOS: GoogleService-Info.plist β†’ Place in ios/Runner/

2. Upload TFLite Model to Firebase #

  1. Go to Firebase Console β†’ Machine Learning β†’ Custom Models
  2. Click "Add Custom Model"
  3. Upload your face_verification_model.tflite file
  4. Model name: face_model (important!)
  5. Click "Publish"

Note: For testing, you can use the default model from the example Firebase project.

3. Platform-Specific Setup #

iOS Setup

Update ios/Podfile:

platform :ios, '16.0'

Open your project in Xcode and set:

  • Deployment Target β†’ iOS 16.0
  • Add GoogleService-Info.plist to your project

Android Setup

Update android/app/build.gradle:

android {
    defaultConfig {
        minSdk 24  // Required for ML Kit
    }
}

Add to android/build.gradle:

dependencies {
    classpath 'com.google.gms:google-services:4.4.2'
}

Add to android/app/build.gradle (bottom):

apply plugin: 'com.google.gms.google-services'

4. Initialize Firebase in Your App #

import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  
  runApp(MyApp());
}

πŸ’» API Reference #

KYCEngine #

The main class for face verification operations.

Initialization

final kycEngine = KYCEngine();

// Initialize with default configuration
await kycEngine.initialize();

// Or with custom configuration
await kycEngine.initialize(FaceDetectionConfig.accurate());

Methods

verifyFaces()

Compare two face images and get detailed results.

Future<VerificationResult> verifyFaces(
  File image1,
  File image2, {
  double? customThreshold,
})

// Example
final result = await kycEngine.verifyFaces(
  File('id.jpg'),
  File('selfie.jpg'),
  customThreshold: 0.6,  // Optional: override default threshold
);
areSimilar()

Quick boolean check if two faces match.

Future<bool> areSimilar(File image1, File image2)

// Example
if (await kycEngine.areSimilar(photo1, photo2)) {
  print('Same person!');
}
getSimilarityScore()

Get raw similarity score without threshold comparison.

Future<double> getSimilarityScore(File image1, File image2)

// Example
final score = await kycEngine.getSimilarityScore(photo1, photo2);
print('Similarity: ${(score * 100).toStringAsFixed(1)}%');

Configuration Presets #

Fast Mode

Optimized for speed with minimal accuracy trade-off.

FaceDetectionConfig.fast()

Accurate Mode (Default)

Balanced accuracy and speed.

FaceDetectionConfig.accurate()

Strict Mode

Higher threshold, fewer false positives.

FaceDetectionConfig.strict()

Lenient Mode

Lower threshold, fewer false negatives.

FaceDetectionConfig.lenient()

Custom Configuration

FaceDetectionConfig(
  similarityThreshold: 0.65,
  performanceMode: FaceDetectorMode.accurate,
  enableLandmarks: true,
  enableClassification: true,
  firebaseModelName: 'custom_model_name',
)

VerificationResult #

Result object containing verification details.

Properties

class VerificationResult {
  final double similarityScore;        // 0.0 to 1.0
  final bool isSamePerson;             // Match based on threshold
  final double confidencePercentage;   // Similarity as percentage
  final double threshold;              // Threshold used
  final int? processingTimeMs;         // Processing time in milliseconds
}

Example Usage

final result = await kycEngine.verifyFaces(img1, img2);

print('Score: ${result.similarityScore}');           // 0.8542
print('Match: ${result.isSamePerson}');              // true
print('Confidence: ${result.confidencePercentage}'); // 85.42%
print('Time: ${result.processingTimeMs}ms');         // 245ms

🎯 Threshold Guidelines #

Choose the right threshold for your use case:

Threshold Use Case Description
0.7 - 0.8 High Security Banking, government ID verification
0.5 - 0.7 KYC/Standard General identity verification
0.4 - 0.5 Social Apps Friend tagging, duplicate detection
0.3 - 0.4 Lenient Finding similar faces in large datasets

Interpreting Scores #

  • 0.85 - 1.0: Very high confidence - definitely same person
  • 0.7 - 0.85: High confidence - likely same person
  • 0.5 - 0.7: Moderate confidence - probably same person
  • 0.3 - 0.5: Low confidence - uncertain
  • 0.0 - 0.3: Very low - different persons

πŸ›‘οΈ Error Handling #

try {
  final result = await kycEngine.verifyFaces(image1, image2);
  
  if (result.isSamePerson) {
    // Handle successful match
  } else {
    // Handle no match
  }
} on ServiceNotInitializedException {
  // Engine not initialized - call initialize() first
  print('Please initialize the engine before use');
  
} on NoFaceDetectedException catch (e) {
  // No face found in one or both images
  print('No face detected: ${e.message}');
  
} on MultipleFacesDetectedException catch (e) {
  // Multiple faces detected (only single face supported)
  print('Found ${e.faceCount} faces. Please use single-face images.');
  
} on InvalidImageException catch (e) {
  // Image file is corrupted or unreadable
  print('Invalid image: ${e.message}');
  
} on ModelInitializationException catch (e) {
  // Failed to download or load ML model
  print('Model error: ${e.message}');
  
} on KYCException catch (e) {
  // General KYC engine error
  print('Error: ${e.message}');
}

πŸ“± Complete Example #

import 'package:flutter/material.dart';
import 'package:kyc_engine/kyc_engine.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';

class FaceVerificationPage extends StatefulWidget {
  @override
  _FaceVerificationPageState createState() => _FaceVerificationPageState();
}

class _FaceVerificationPageState extends State<FaceVerificationPage> {
  final KYCEngine _kycEngine = KYCEngine();
  final ImagePicker _picker = ImagePicker();
  
  File? _idPhoto;
  File? _selfie;
  VerificationResult? _result;
  bool _isInitialized = false;
  bool _isProcessing = false;

  @override
  void initState() {
    super.initState();
    _initializeEngine();
  }

  Future<void> _initializeEngine() async {
    try {
      await _kycEngine.initialize(FaceDetectionConfig.accurate());
      setState(() => _isInitialized = true);
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Failed to initialize: $e')),
      );
    }
  }

  Future<void> _pickImage(bool isIdPhoto) async {
    final XFile? image = await _picker.pickImage(
      source: ImageSource.gallery,
      maxWidth: 1024,
      maxHeight: 1024,
    );
    
    if (image != null) {
      setState(() {
        if (isIdPhoto) {
          _idPhoto = File(image.path);
        } else {
          _selfie = File(image.path);
        }
        _result = null;
      });
    }
  }

  Future<void> _verify() async {
    if (_idPhoto == null || _selfie == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Please select both images')),
      );
      return;
    }

    setState(() => _isProcessing = true);

    try {
      final result = await _kycEngine.verifyFaces(_idPhoto!, _selfie!);
      setState(() {
        _result = result;
        _isProcessing = false;
      });
    } on KYCException catch (e) {
      setState(() => _isProcessing = false);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error: ${e.message}')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Face Verification')),
      body: Column(
        children: [
          // Image selection UI
          Row(
            children: [
              Expanded(
                child: GestureDetector(
                  onTap: () => _pickImage(true),
                  child: Container(
                    height: 200,
                    child: _idPhoto != null
                        ? Image.file(_idPhoto!, fit: BoxFit.cover)
                        : Center(child: Text('Select ID Photo')),
                  ),
                ),
              ),
              Expanded(
                child: GestureDetector(
                  onTap: () => _pickImage(false),
                  child: Container(
                    height: 200,
                    child: _selfie != null
                        ? Image.file(_selfie!, fit: BoxFit.cover)
                        : Center(child: Text('Select Selfie')),
                  ),
                ),
              ),
            ],
          ),
          
          // Verify button
          ElevatedButton(
            onPressed: _isInitialized && !_isProcessing ? _verify : null,
            child: Text(_isProcessing ? 'Processing...' : 'Verify'),
          ),
          
          // Result display
          if (_result != null) ...[
            Text(
              _result!.isSamePerson ? 'MATCH βœ…' : 'NO MATCH ❌',
              style: TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
                color: _result!.isSamePerson ? Colors.green : Colors.red,
              ),
            ),
            Text('Confidence: ${_result!.confidencePercentage.toStringAsFixed(1)}%'),
          ],
        ],
      ),
    );
  }

  @override
  void dispose() {
    _kycEngine.dispose();
    super.dispose();
  }
}

πŸ“Š Performance #

Metric Value
Model Size ~27.5 MB (unquantized)
Inference Time 100-300ms per comparison
Accuracy 97%+ on same-person verification
Memory Usage ~50-100 MB during inference
Supported Image Formats JPG, PNG
Recommended Image Size 512x512 to 1024x1024 pixels

πŸ”§ Requirements #

  • Flutter: β‰₯ 3.0.0
  • Dart: β‰₯ 3.0.0
  • iOS: β‰₯ 16.0
  • Android: minSdk β‰₯ 24
  • Firebase Project: Required for model distribution
  • Internet: Required for initial model download

πŸ› Troubleshooting #

Model Download Fails #

Problem: Model won't download from Firebase. Solution:

  • Check internet connection
  • Verify Firebase project is set up correctly
  • Ensure model is published in Firebase Console
  • Check Firebase model name matches (default: face_model)

No Face Detected #

Problem: Getting NoFaceDetectedException. Solution:

  • Ensure image has clear, frontal face
  • Check lighting conditions
  • Face should be at least 100x100 pixels
  • Avoid sunglasses, masks, or heavy occlusions

Low Accuracy #

Problem: Getting incorrect matches. Solution:

  • Use FaceDetectionConfig.accurate() or .strict()
  • Increase similarity threshold
  • Use higher quality images
  • Ensure good lighting in photos

iOS Build Fails #

Problem: Platform version error. Solution:

# In ios/Podfile
platform :ios, '15.0'

Android Build Fails #

Problem: MinSdk error. Solution:

// In android/app/build.gradle
defaultConfig {
    minSdk 24
}

πŸ“š Example App #

A complete example app is included in the /example folder demonstrating:

  • Firebase initialization
  • Camera integration
  • Gallery image selection
  • Real-time face verification
  • Error handling
  • Result visualization
  • Loading states

Run the example:

cd example
flutter pub get
flutter run

🀝 Contributing #

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Areas for Contribution #

  • Additional face quality checks
  • Liveness detection
  • Support for quantized models
  • Web platform support
  • Additional configuration options
  • Performance optimizations
  • Documentation improvements

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™ Acknowledgments #

Built with amazing open-source technologies:


πŸ“ž Support & Contact #


πŸ—ΊοΈ Roadmap #

v0.1.0 (Next Release) #

  • ❌ Quantized model support (reduce size to ~7MB)
  • ❌ Batch verification for multiple pairs
  • ❌ Face quality assessment
  • ❌ Custom training documentation

v0.2.0 #

  • ❌ Liveness detection
  • ❌ Face landmark visualization
  • ❌ Video frame processing
  • ❌ Web platform support

v0.3.0 #

  • ❌ Offline model bundling
  • ❌ Multi-face detection
  • ❌ Face clustering
  • ❌ Performance analytics dashboard

Built with ❀️ by Eric Atsu

If you find this package helpful, please give it a ⭐ on GitHub!

1
likes
140
points
16
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter library for face verification and KYC processes.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

firebase_core, firebase_ml_model_downloader, flutter, google_mlkit_face_detection, image, image_picker, path_provider, tflite_flutter

More

Packages that depend on kyc_engine