Search by

olorunda / laravel-rekognition-face

olorunda

Biometric face comparison and real human face verification using Amazon Rekognition for Laravel and PHP

Package info

github.com/olorunda/laravel-rekognition-face

pkg:composer/olorunda/laravel-rekognition-face

Statistics

Installs: 14

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-09-24 07:49 UTC

This package is auto-updated.

Last update: 2026-09-24 08:16:50 UTC


README

Latest Version PHP Version License: MIT

Production-ready Laravel & standalone PHP package to compare two human face images for biometric identity matching and verify whether an image contains a genuine, high-quality, real human face using Amazon Rekognition.

๐ŸŒŸ Key Features

  1. Biometric Face Comparison (CompareFaces):

    • Compares two faces and computes biometric similarity percentage (0% to 100%).
    • Configurable similarity threshold (e.g. 80% default).
    • Returns bounding boxes, confidence scores, matched landmarks, and unmatched faces in target photo.
  2. Real Human Face & Quality Verification (DetectFaces):

    • Human Face Detection Confidence: Verifies Rekognition detects a human face with high confidence (e.g. โ‰ฅ 95%).
    • Single Face Enforcement: Ensures exactly one human face is present (flags multi-face or crowded photos for KYC / ID verification).
    • Image Sharpness & Blur Filter: Rejects motion-blurred, out-of-focus, or low-resolution spoof images.
    • Brightness & Exposure Validation: Ensures balanced lighting (rejects pitch black or washed-out photocopies).
    • 3D Head Pose Orientation: Checks Yaw (turning), Pitch (tilting up/down), and Roll (sideways tilt) to enforce frontal portrait alignment.
    • Open Eyes & Liveness Heuristics: Detects closed eyes (flags sleeping/passive photo spoofing).
    • Occlusion & Mask Detection: Rejects sunglasses and facial coverings that conceal biometric landmarks.
    • Composite Quality Score: Generates a normalized score (0โ€“100) and actionable diagnostic checklist.
  3. Combined Verification Pipeline (verifyAndCompare):

    • Verifies that both images are real human faces first.
    • Compares the two faces and checks similarity.
    • Returns a comprehensive audit trail with pass/fail status and specific violation reasons.
  4. AWS Rekognition Face Liveness Session:

    • Helpers to generate AWS Face Liveness sessions (createLivenessSession) and fetch results (getLivenessResults) for frontend camera SDKs (Amplify FaceLivenessDetector).
  5. Universal Image Input Support:

    • Local file paths (/path/to/selfie.jpg)
    • Raw binary bytes (file_get_contents(...))
    • Base64 strings & Data URIs (data:image/jpeg;base64,...)
    • Remote HTTP / HTTPS URLs (auto-downloaded securely)
    • Amazon S3 objects (['bucket' => '...', 'key' => '...'])
    • Laravel Illuminate\Http\UploadedFile instances ($request->file('avatar'))
  6. Artisan CLI Tools:

    • php artisan face:compare {source} {target}
    • php artisan face:verify {image}
  7. Framework Flexibility:

    • Fully integrated with Laravel (Service Provider, Facade, Config publishing, Artisan CLI).
    • Can also be instantiated directly in standalone PHP without Laravel.

๐Ÿ“ฆ Installation

Install via Composer:

composer require olorunda/laravel-rekognition-face

In Laravel, the Service Provider and RekognitionFace Facade are registered automatically.

Publish the configuration file:

php artisan vendor:publish --tag="rekognition-face-config"

โš™๏ธ Configuration & Environment

Add your AWS credentials to your .env file:

AWS_ACCESS_KEY_ID=your-aws-access-key-id
AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key
AWS_DEFAULT_REGION=us-east-1

# Optional overrides:
REKOGNITION_SIMILARITY_THRESHOLD=80.0
REKOGNITION_MIN_FACE_CONFIDENCE=95.0
REKOGNITION_STRICT_SINGLE_FACE=true
REKOGNITION_MIN_SHARPNESS=20.0
REKOGNITION_MIN_BRIGHTNESS=15.0
REKOGNITION_MAX_BRIGHTNESS=95.0
REKOGNITION_REQUIRE_EYES_OPEN=true
REKOGNITION_DISALLOW_SUNGLASSES=true
REKOGNITION_DISALLOW_OCCLUSION=true

# Test & Simulation Mode (Run without real AWS keys!):
REKOGNITION_TEST_MODE=false
REKOGNITION_SIMULATE_SCENARIO=match # match, no_match, blurry, closed_eyes, multiple_faces, occluded, not_human
REKOGNITION_SIMULATE_SIMILARITY=96.5
REKOGNITION_SIMULATE_CONFIDENCE=99.8

๐Ÿš€ Usage

1. Compare Two Faces (Biometric Matching)

Compare an ID card photo and a selfie to see if they belong to the same person:

use Olorunda\RekognitionFace\Facades\RekognitionFace;

// Compare local files, URLs, base64 strings, or UploadedFiles
$result = RekognitionFace::compare(
    sourceImage: '/storage/id_card.jpg',
    targetImage: '/storage/selfie.jpg',
    similarityThreshold: 85.0 // Optional override
);

if ($result->isMatch()) {
    echo "Faces match! Similarity: {$result->getSimilarity()}%\n";
    echo "Detection confidence: {$result->getConfidence()}%\n";
} else {
    echo "Not a match. Similarity was {$result->getSimilarity()}%\n";
}

// Inspect details
$matchedFace = $result->getMatchedFace();
echo "Face pitch: {$matchedFace->pitch}ยฐ, yaw: {$matchedFace->yaw}ยฐ\n";
echo "Unmatched faces in target image: {$result->getUnmatchedCount()}\n";

2. Verify If An Image Is A Real Human Face

Inspect an image for authenticity, quality, pose, and absence of spoofs or occlusions:

use Olorunda\RekognitionFace\Facades\RekognitionFace;

$realness = RekognitionFace::verifyRealHumanFace('/storage/selfie.jpg');

if ($realness->isRealHumanFace()) {
    echo "Genuine human face verified!\n";
    echo "Quality Score: {$realness->getQualityScore()} / 100\n";
    echo "Detection Confidence: {$realness->getConfidence()}%\n";
} else {
    echo "Verification failed! Issues:\n";
    foreach ($realness->getViolations() as $violation) {
        echo " - {$violation}\n";
    }
}

// Checklist breakdown
$checks = $realness->getChecks();
/*
[
    'human_detected'    => true,  // Rekognition detected human face >= 95%
    'single_face'       => true,  // Exactly 1 face found in image
    'sharpness_ok'      => true,  // Not blurry (sharpness >= 20)
    'brightness_ok'     => true,  // Balanced exposure
    'pose_frontal'      => true,  // Facing camera (yaw/pitch/roll within bounds)
    'eyes_open'         => true,  // Open eyes detected
    'no_occlusion'      => true,  // No sunglasses or masks
    'min_face_size_ok'  => true,  // Face is prominent in the frame
]
*/

Customizing checks on the fly:

$realness = RekognitionFace::verifyRealHumanFace($image, [
    'strict_single_face' => false, // Allow photos with multiple people
    'min_sharpness'      => 40.0,  // Require higher sharpness
    'require_eyes_open'  => false, // Permit closed eyes
]);

3. Complete End-to-End Pipeline (verifyAndCompare)

Runs both real face checks on the source and target images before comparing them:

use Olorunda\RekognitionFace\Facades\RekognitionFace;

$verification = RekognitionFace::verifyAndCompare(
    sourceImage: $request->file('id_card'),
    targetImage: $request->file('selfie'),
    options: ['threshold' => 80.0]
);

if ($verification->passed()) {
    echo "Verification SUCCESS!\n";
    echo "Similarity: {$verification->getSimilarity()}%\n";
} else {
    echo "Verification FAILED!\n";
    foreach ($verification->getFailureReasons() as $reason) {
        echo " - {$reason}\n";
    }
}

4. AWS Rekognition Face Liveness Session

For active 3D liveness detection using AWS Amplify web or mobile SDK:

use Olorunda\RekognitionFace\Facades\RekognitionFace;

// 1. Create a session for the mobile/web frontend
$sessionId = RekognitionFace::createLivenessSession();

// 2. Pass $sessionId to client app running AWS Amplify FaceLivenessDetector

// 3. Retrieve results once client completes the test
$results = RekognitionFace::getLivenessResults($sessionId);

if ($results['Status'] === 'SUCCEEDED' && $results['Confidence'] >= 90.0) {
    echo "Liveness check passed with confidence {$results['Confidence']}%\n";
}

5. ๐Ÿงช Test & Simulation Mode (Run Without AWS Keys)

You can develop, test, and run biometric verification without supplying real AWS credentials. This is ideal for local development, CI/CD, staging, and demo environments.

A. Enable via .env:

REKOGNITION_TEST_MODE=true
REKOGNITION_SIMULATE_SCENARIO=match # Options: match, no_match, blurry, closed_eyes, multiple_faces, occluded, not_human

B. Runtime Simulation (Mocking like Http::fake()):

use Olorunda\RekognitionFace\Facades\RekognitionFace;

// Turn on test mode on the fly
RekognitionFace::fake();

// Switch test scenarios:
RekognitionFace::fakeScenario('match');          // Matches with high similarity (96.5%)
RekognitionFace::fakeScenario('no_match');       // Valid faces, but different people (38.4% similarity)
RekognitionFace::fakeScenario('blurry');         // Fails sharpness quality filter
RekognitionFace::fakeScenario('closed_eyes');    // Fails eyes open liveness check
RekognitionFace::fakeScenario('multiple_faces'); // Multiple people in image (fails strict single-face)
RekognitionFace::fakeScenario('occluded');       // Face wearing sunglasses or mask
RekognitionFace::fakeScenario('not_human');      // No human face found

// Custom simulation parameters:
RekognitionFace::fake([
    'similarity' => 92.0,
    'is_match'   => true,
    'confidence' => 99.9,
]);

// Check status or turn off:
RekognitionFace::isTestMode(); // true
RekognitionFace::enableTestMode(false);

C. Available Simulation Scenarios:

Scenario Real Face Result Comparison Result Typical Use Case
match (default) Pass (Quality: ~94) Match (Similarity: 96.5%) Happy path testing
no_match Pass No Match (Similarity: 38.4%) Testing rejection of non-matching IDs
blurry Fail (Sharpness: 8.5 < 20) Match Testing low-quality camera uploads
closed_eyes Fail (Eyes closed) Match Testing sleeping/photo liveness spoof
multiple_faces Fail (2 faces found) Match Testing anti-crowd / multiple person photo
occluded Fail (Sunglasses detected) Match Testing mask/sunglasses rejection
not_human Fail (0 faces found) Throws Exception Testing object or pet photos

6. Flexible Image Inputs

The package accepts any of the following formats interchangeably:

// Local file path
RekognitionFace::compare('/path/to/photo.jpg', '/path/to/selfie.png');

// Laravel UploadedFile from form request
RekognitionFace::compare($request->file('id_document'), $request->file('webcam_capture'));

// Base64 Data URI from HTML5 webcam
RekognitionFace::verifyRealHumanFace('data:image/jpeg;base64,/9j/4AAQSkZJRg...');

// Raw binary bytes
RekognitionFace::compare($rawJpegBytes1, $rawJpegBytes2);

// Remote HTTP / HTTPS URL
RekognitionFace::compare('https://mycdn.com/id.jpg', 'https://mycdn.com/selfie.jpg');

// AWS S3 Object reference
RekognitionFace::compare(
    ['bucket' => 'my-private-bucket', 'key' => 'users/123/passport.jpg'],
    ['bucket' => 'my-private-bucket', 'key' => 'users/123/live_capture.jpg']
);

7. Artisan CLI Commands

Compare Two Face Images

# Standard mode (with AWS keys):
php artisan face:compare /path/to/id.jpg /path/to/selfie.jpg --threshold=85

# Test mode (without AWS keys):
php artisan face:compare /path/to/id.jpg /path/to/selfie.jpg --simulate --scenario=match

Output:

Comparing faces using AWS Rekognition...
Source: /path/to/id.jpg
Target: /path/to/selfie.jpg

 MATCH DETECTED!
+----------------------------+-----------+
| Metric                     | Value     |
+----------------------------+-----------+
| Is Match                   | YES       |
| Similarity Score           | 96.5%     |
| Required Threshold         | 85%       |
| Detection Confidence       | 99.8%     |
| Unmatched Faces in Target  | 0         |
+----------------------------+-----------+

Verify a Real Human Face

# Standard mode:
php artisan face:verify /path/to/selfie.jpg --strict

# Test mode:
php artisan face:verify /path/to/selfie.jpg --simulate --scenario=blurry

Output:

Analyzing image for real human face...
Image: /path/to/selfie.jpg

 REAL HUMAN FACE VERIFIED
+-------------------------+-----------+
| Metric                  | Value     |
+-------------------------+-----------+
| Is Real Human Face      | YES       |
| Detection Confidence    | 99.9%     |
| Composite Quality Score | 94.2 / 100|
| Faces Detected          | 1         |
| Passed All Checks       | YES       |
+-------------------------+-----------+

Validation Checklist:
+-------------------+--------+
| Check             | Status |
+-------------------+--------+
| Human Detected    | PASS   |
| Single Face       | PASS   |
| Sharpness Ok      | PASS   |
| Brightness Ok     | PASS   |
| Pose Frontal      | PASS   |
| Eyes Open         | PASS   |
| No Occlusion      | PASS   |
| Min Face Size Ok  | PASS   |
+-------------------+--------+

8. Standalone PHP Usage (Without Laravel)

require_once __DIR__ . '/vendor/autoload.php';

use Olorunda\RekognitionFace\Services\RekognitionFaceService;

$service = new RekognitionFaceService([
    'region' => 'us-east-1',
    'credentials' => [
        'key'    => 'YOUR_AWS_KEY',
        'secret' => 'YOUR_AWS_SECRET',
    ],
    'comparison' => [
        'default_threshold' => 80.0,
    ],
]);

$result = $service->compare('id.jpg', 'selfie.jpg');

if ($result->isMatch()) {
    echo "Matched! Similarity: " . $result->getSimilarity() . "%\n";
}

๐Ÿ”’ Required AWS IAM Policy

Your AWS IAM user or role must have the following permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RekognitionFacePermissions",
            "Effect": "Allow",
            "Action": [
                "rekognition:CompareFaces",
                "rekognition:DetectFaces",
                "rekognition:CreateFaceLivenessSession",
                "rekognition:GetFaceLivenessSessionResults"
            ],
            "Resource": "*"
        }
    ]
}

(If using S3 object references directly, also ensure s3:GetObject permission on the target buckets).

๐Ÿงช Testing

Run PHPUnit tests:

composer test

All unit and feature tests use the AWS SDK MockHandler to run offline without hitting AWS or incurring costs.

๐Ÿ“„ License

The MIT License (MIT). Please see LICENSE.md for more information.