Skip to content

Latest commit

 

History

History
139 lines (106 loc) · 4.08 KB

File metadata and controls

139 lines (106 loc) · 4.08 KB

Usage

All examples assume composer require banguncode/php-dp and require 'vendor/autoload.php';.

Quick start: enroll a finger from 4 samples

use Dp\Fmd;
use Dp\RawSample;

$fmd = new Fmd(); // resolves libdpfj.so / libdpfpdd.so via ldconfig

// $rawJsonSamples = 4 WebSDK-style Raw JSON strings from the SAME finger
$raws = [];
$width = $height = $dpi = 0;
foreach ($rawJsonSamples as $json) {
    $sample = RawSample::fromWebSdkJson($json);
    $raws[]  = $sample['raw'];
    $width   = $sample['width'];
    $height  = $sample['height'];
    $dpi     = $sample['dpi'];
}

$templateBase64 = $fmd->enrollFourToBase64($raws, $width, $height, $dpi);
// -> store $templateBase64 (e.g. in your database)

Enroll from PNG/JPEG images instead (requires ext-gd)

$templateBase64 = $fmd->enrollFourImagesToBase64([
    base64_encode(file_get_contents('finger-1.png')),
    base64_encode(file_get_contents('finger-2.png')),
    base64_encode(file_get_contents('finger-3.png')),
    base64_encode(file_get_contents('finger-4.png')),
], dpi: 500); // DPI can't be read from the image — use your scanner's real DPI

Verify a live sample against a stored template

use Dp\RawSample;

$sample = RawSample::fromWebSdkJson($probeJson);
$storedTemplateBinary = base64_decode($storedTemplateBase64, true);

$result = $fmd->verify(
    $sample['raw'],
    $sample['width'],
    $sample['height'],
    $storedTemplateBinary,
    $sample['dpi']
);

if ($result['match']) {
    echo "Match! score={$result['score']} (threshold={$result['threshold']})\n";
} else {
    echo "No match. score={$result['score']}\n";
}

Control the match sensitivity via the target False Accept Rate:

$fmd = new Fmd(far: 1_000_000); // stricter: 1 false accept in a million

Comparing two raw FMDs directly

$result = $fmd->compare($enrollmentFmdBytes, $probeFmdBytes);

By default this assumes $enrollmentFmdBytes is FmdFormat::REGISTRATION (the output of enrollFour()/enrollMany()) and $probeFmdBytes is FmdFormat::VERIFICATION (the default output of fmdFromRaw()/fmdFromImage()). Override both if you're comparing standard ISO/ANSI interchange templates instead:

use Dp\FmdFormat;

$result = $fmd->compare($isoTemplateA, $isoTemplateB, FmdFormat::ISO, FmdFormat::ISO);

Lower-level API (mirrors DPUruNet.dll's static classes)

If you want finer control than the Fmd facade gives you (e.g. you're managing your own enrollment sample count instead of a fixed 4), the lower-level classes are available directly:

use Dp\NativeMethods;
use Dp\FeatureExtraction;
use Dp\Enrollment;
use Dp\Comparison;
use Dp\FmdFormat;

$native = new NativeMethods(); // loads libs + selects the matcher engine

// Pass raw samples straight through — Enrollment::createEnrollmentFmd()
// extracts each sample's FMD *inside* the active enrollment session.
// Building them beforehand (outside the session) causes
// dpfj_create_enrollment_fmd() to fail with ENROLLMENT_NOT_READY even
// after every sample was accepted — see docs/troubleshooting.md.
$enrollmentFmd = Enrollment::createEnrollmentFmd($native, $rawSamples, $width, $height, $dpi);

$probeFmd = FeatureExtraction::createFmdFromRaw(
    $native, $probeRaw, $width, $height, $dpi, FmdFormat::VERIFICATION
);

$result = Comparison::compare($native, $enrollmentFmd, FmdFormat::REGISTRATION, $probeFmd, FmdFormat::VERIFICATION);

$fmd->native() also exposes the same NativeMethods instance if you constructed via the Fmd facade and want to drop down for one call.

Error handling

Every native failure throws Dp\SDKException, which carries a typed Dp\ResultCode enum:

use Dp\SDKException;
use Dp\ResultCode;

try {
    $fmd->enrollFourToBase64($raws, $width, $height, $dpi);
} catch (SDKException $e) {
    if ($e->resultCode === ResultCode::TOO_SMALL_AREA) {
        // ask the user to re-scan, cover more of the sensor
    }
    throw $e;
}

Input validation errors (wrong array counts, malformed JSON, raw length mismatches) throw plain \InvalidArgumentException, not SDKException — they never reach the native library at all.