Looking to hire Laravel developers? Try LaraJobs

laravel-rekognition-face maintained by olorunda

Description
Biometric face comparison and real human face verification using Amazon Rekognition for Laravel and PHP
Author
Olorunda
Last update
2026/09/24 09:49 (dev-main)
License
Downloads
13

Comments
comments powered by Disqus

Laravel AWS Rekognition Face Comparison & Real Face Verifier

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.