DOT Android Face 4.0.0

This guide describes how to migrate DOT Android Face version 3.x to version 4.0.0. Only the most important changes are highlighted in this guide. For more details, see the Android sample.

Migration Steps

Update build.gradle file

  • Set minSdkVersion to 21 or higher.
  • Change the dependency to the DOT Android Face. Follow steps in the Integration Manual, section Distribution / Maven Repository.

Proguard

For applications that use Proguard, add new rule to Proguard configuration file:

-keep class com.innovatrics.dot.face.*.*Module { *; }

Basic Setup

  • Replace DotFaceParameters with DotFaceConfiguration.
  • Replace initAsync() method with initializeAsync() method.
  • Replace closeAsync() method with deinitializeAsync() method.

Before

DotFaceParameters dotFaceParameters = new DotFaceParameters.Builder().build();
DotFace.getInstance().initAsync(context, licenseBytes, dotFaceParameters, listener);
...
DotFace.getInstance().closeAsync(listener);

After

List<DotFaceModule> modules = Arrays.asList(
        DotFaceDetectionModule.of(),
        DotFaceVerificationModule.of(),
        DotFaceEyeGazeLivenessModule.of(),
        DotFacePassiveLivenessModule.of()
);
DotFaceConfiguration configuration = new DotFaceConfiguration.Builder(context, licenseBytes, modules).build();
DotFace.getInstance().initializeAsync(configuration, listener);
...
DotFace.getInstance().deinitializeAsync(listener);

For more details, see the Integration Manual, section Basic Setup.


FaceDetector component

  • Replace FaceDetector constructor call with FaceDetectorFactory.
  • Replace detectFaces() method with detect() method.

Before

FaceDetector faceDetector = new FaceDetector();
List<DetectedFace> detectedFaces = faceDetector.detectFaces(faceImage, maximumFaces);

After

FaceDetector faceDetector = FaceDetectorFactory.create();
List<DetectedFace> detectedFaces = faceDetector.detect(faceImage, maximumFaces);

DetectedFace interface

  • Replace createFullImage() method with getImage() method.
  • Replace createCroppedImage() method with createFullFrontalImage() method.
  • Replace getEyeDistance(), createFaceAttributes() and createIcaoAttributes() methods with evaluateFaceAspects(), evaluateFaceQuality() and evaluatePassiveLiveness() methods.

Before

Bitmap imageBitmap = detectedFace.createFullImage();
Bitmap fullFrontalImageBitmap = detectedFace.createCroppedImage();
float eyeDistancePixels = detectedFace.getEyeDistance();
Map<FaceAttributeId, FaceAttribute> faceAttributes = detectedFace.createFaceAttributes(Arrays.asList(FaceAttributeId.values())); // Includes Passive Liveness and Glass Status
Map<IcaoAttributeId, IcaoAttribute> icaoAttributes = detectedFace.createIcaoAttributes(Arrays.asList(IcaoAttributeId.values()));

After

BgrRawImage bgrRawImage = detectedFace.getImage();
Bitmap imageBitmap = BitmapFactory.create(bgrRawImage);
BgrRawImage fullFrontalBgrRawImage = detectedFace.createFullFrontalImage();
Bitmap fullFrontalImageBitmap = BitmapFactory.create(fullFrontalBgrRawImage);
FaceAspects faceAspects = detectedFace.evaluateFaceAspects(); // Includes Eye Distance in pixels
FaceQuality faceQuality = detectedFace.evaluateFaceQuality();
FaceAttribute passiveLiveness = detectedFace.evaluatePassiveLiveness();

TemplateMatcher component

  • Replace TemplateVerifier with TemplateMatcher.
  • Replace TemplateVerifier constructor call with TemplateMatcherFactory.
  • Replace result of type float with TemplateMatcher.Result.

Before

TemplateVerifier templateVerifier = new TemplateVerifier();
float score = templateVerifier.match(referenceTemplateBytes, probeTemplateBytes);

After

TemplateMatcher templateMatcher = TemplateMatcherFactory.create();
TemplateMatcher.Result result = templateMatcher.match(referenceTemplateBytes, probeTemplateBytes);

FaceMatcher component

  • Replace FaceImageVerifier with FaceMatcher.
  • Replace FaceImageVerifier constructor call with FaceMatcherFactory.
  • Replace result of type float with FaceMatcher.Result.

Before

FaceImageVerifier faceImageVerifier = new FaceImageVerifier();
float score = faceImageVerifier.match(referenceFaceImage ,probeFaceImage);

After

FaceMatcher faceMatcher = FaceMatcherFactory.create();
FaceMatcher.Result result = faceMatcher.match(referenceFaceImage, probeFaceImage);

Face Auto Capture Fragment

  • Replace FaceCaptureFragment with FaceAutoCaptureFragment.
  • Remove onCameraInitFailed() callback.
  • Remove onCameraAccessFailed() callback.
  • Remove onAutoCaptureReady() callback. The process is started implicitly as soon as possible.
  • Replace onCaptureStateChange() callback with onStepChanged() callback.
  • Replace onCaptureSuccess() callback with onCaptured() callback.

Create Face Auto Capture Fragment instance

  • Replace configuration DTO FaceCaptureArguments with FaceAutoCaptureConfiguration.
  • Replace bundle key FaceCaptureFragment.ARGUMENTS with FaceAutoCaptureFragment.CONFIGURATION.

Before

FaceCaptureArguments faceCaptureArguments = new FaceCaptureArguments.Builder().build();

Bundle arguments = new Bundle();
arguments.putSerializable(FaceCaptureFragment.ARGUMENTS, faceCaptureArguments);

Fragment fragment = new DemoFaceCaptureFragment();
fragment.setArguments(arguments);

After

FaceAutoCaptureConfiguration faceAutoCaptureConfiguration = new FaceAutoCaptureConfiguration.Builder().build();

Bundle arguments = new Bundle();
arguments.putSerializable(FaceAutoCaptureFragment.CONFIGURATION, faceAutoCaptureConfiguration);

Fragment fragment = new DemoFaceAutoCaptureFragment();
fragment.setArguments(arguments);

Face Simple Capture Fragment

  • Replace FaceCaptureSimpleFragment with FaceSimpleCaptureFragment.
  • Remove onCameraInitFailed() callback.
  • Remove onCameraAccessFailed() callback.
  • Replace onCapture() callback with onCaptured() callback.
  • Replace requestPhoto() method with requestCapture() method.

Create Face Simple Capture Fragment instance

  • Replace configuration DTO FaceCaptureSimpleArguments with FaceSimpleCaptureConfiguration.
  • Replace bundle key FaceCaptureSimpleFragment.ARGUMENTS with FaceSimpleCaptureFragment.CONFIGURATION.

Before

FaceCaptureSimpleArguments faceCaptureSimpleArguments = new FaceCaptureSimpleArguments.Builder().build();

Bundle arguments = new Bundle();
arguments.putSerializable(FaceCaptureSimpleFragment.ARGUMENTS, faceCaptureSimpleArguments);

Fragment fragment = new DemoFaceCaptureSimpleFragment();
fragment.setArguments(arguments);

After

FaceSimpleCaptureConfiguration faceSimpleCaptureConfiguration = new FaceSimpleCaptureConfiguration.Builder().build();

Bundle arguments = new Bundle();
arguments.putSerializable(FaceSimpleCaptureFragment.CONFIGURATION, faceSimpleCaptureConfiguration);

Fragment fragment = new DemoFaceSimpleCaptureFragment();
fragment.setArguments(arguments);

Eye Gaze Liveness Fragment

  • Replace LivenessCheckFragment with EyeGazeLivenessFragment.
  • Remove onCameraInitFailed() callback.
  • Remove onCameraAccessFailed() callback.
  • Remove onNoFrontCamera() callback.
  • Remove onCameraReady() callback. If you want to start the process as soon as possible, call start() method in onCreate() callback.
  • Replace onLivenessStateChange() callback with onStateChanged() callback.
  • Replace onLivenessCheckDone() callback with onFinished() callback.
  • Replace onLivenessCheckFailedNoMoreSegments() callback with onNoMoreSegments() callback.
  • Replace onLivenessCheckFailedEyesNotDetected() callback with onEyesNotDetected() callback.
  • Replace onLivenessCheckFailedFaceTrackingFailed() callback with onFaceTrackingFailed() callback.

Create Eye Gaze Liveness Fragment instance

  • Replace configuration DTO LivenessCheckArguments with EyeGazeLivenessConfiguration.
  • Replace bundle key LivenessCheckFragment.ARGUMENTS with EyeGazeLivenessFragment.CONFIGURATION.
  • In the case of customizing the moving or fading object on the screen, remove LivenessCheckArguments.dotColorResId() and LivenessCheckArguments.dotSize() methods and override the drawable resource res/drawable/eye_gaze_liveness_object.xml.

Before

List<SegmentConfiguration> segments = createSegments(); // custom implementation

LivenessCheckArguments livenessCheckArguments = new LivenessCheckArguments.Builder()
        .segmentList(segments)
        .dotColorResId(dotColorResId)
        .dotSize(dotSize)
        .build();

Bundle arguments = new Bundle();
arguments.putSerializable(LivenessCheckFragment.ARGUMENTS, livenessCheckArguments);

Fragment fragment = new DemoLivenessCheckFragment();
fragment.setArguments(arguments);

After

SegmentsGenerator segmentsGenerator = new RandomSegmentsGenerator();
int segmentCount = 8;
int segmentDurationMillis = 800;
List<Segment> segments = segmentsGenerator.generate(segmentCount, segmentDurationMillis);

EyeGazeLivenessConfiguration eyeGazeLivenessConfiguration = new EyeGazeLivenessConfiguration.Builder(segments).build();

Bundle arguments = new Bundle();
arguments.putSerializable(EyeGazeLivenessFragment.CONFIGURATION, eyeGazeLivenessConfiguration);

Fragment fragment = new TestEyeGazeLivenessFragment();
fragment.setArguments(arguments);

Liveness Detection 2 component

Liveness Detection 2 was removed. In order to achieve similar functionality, a client can combine FaceAutoCaptureFragment and EyeGazeLivenessFragment.


Image Conversion

New DOT Document API uses BgrRawImage DTO as an image representation.

Create BgrRawImage from Bitmap:

BgrRawImage bgrRawImage = BgrRawImageFactory.create(bitmap);

Create Bitmap from BgrRawImage:

Bitmap bitmap = BitmapFactory.create(bgrRawImage);

Create FaceImage instance

Before

FaceImage faceImage = FaceImage.create(bitmap);

After

FaceImage faceImage = FaceImage.of(bgrRawImage);

Score and confidence values

All score and confidence values are normalized to interval [0.0, 1.0] by means of linear mapping. For example, Passive Liveness score 5000.0 from interval [-10000.0 - 10000.0] in version 3.x is mapped to value 0.75 from interval [0.0 - 1.0] in version 4.0.0. See how intervals are mapped in the mapping table.

AttributeVersion 3.xVersion 4.0.0
Face Confidence[0.0 - 10000.0][0.0 - 1.0]
Position[-1.0 - 1.0][0.0 - 1.0]
Proximity[-1.0 - 1.0][0.0 - 1.0]
Glass Status[-10000.0 - 10000.0][0.0 - 1.0]
Background Uniformity[-10000.0 - 10000.0][0.0 - 1.0]
Eye Status[-10000.0 - 10000.0][0.0 - 1.0]
Mouth Status[-10000.0 - 10000.0][0.0 - 1.0]
Light[-1.0 - 1.0][0.0 - 1.0]
Brightness[-10000.0 - 10000.0][0.0 - 1.0]
Contrast[-10000.0 - 10000.0][0.0 - 1.0]
Shadow[-10000.0 - 10000.0][0.0 - 1.0]
Sharpness[-10000.0 - 10000.0][0.0 - 1.0]
Unique Intensity Levels[-10000.0 - 10000.0][0.0 - 1.0]
Matching Score[0.0 - 100.0][0.0 - 1.0]
Eye Gaze (Active) Liveness[0.0 - 1.0][0.0 - 1.0]
Passive Liveness[-10000.0 - 10000.0][0.0 - 1.0]