DOT iOS Face 4.0.0

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

Migration Steps

Update iOS Deployment Target

Minimal deployment target was changed to iOS 11.0.

Basic Setup

  • Renamed DOTHandler to DotFace, DotFace is singleton.

Before

import DOT

let license = try License(path: path)
DOTHandler.initialize(with: license, faceDetectionConfidenceThreshold: 1000)
...
DOTHandler.deinitialize()

After

import DotFaceCore
import DotFacePassiveLiveness
import DotFaceVerification
import DotFaceEyeGazeLiveness
import DotFaceDetection

let license = try! Data(contentsOf: licenseUrl)
let configuration = DotFaceConfiguration(license: license,
                                         modules: [
                                            DotFacePassiveLivenessModule.shared,
                                            DotFaceVerificationModule.shared,
                                            DotFaceEyeGazeLivenessModule.shared,
                                            DotFaceDetectionModule.shared],
                                         faceDetectionConfidenceThreshold: 1000)
DotFace.shared.setDelegate(self)
DotFace.shared.initialize(configuration: configuration)
...
DotFace.shared.deinitialize()

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


FaceMatcher component

  • Renamed FaceImageVerifier to FaceMatcher.
  • Matching an array of probe face images is handled by the client.

Before

let faceImageVerifier = FaceImageVerifier()

After

let faceMatcher = FaceMatcher()

TemplateMatcher component

  • Renamed TemplateVerifier to TemplateMatcher.

Before

let templateVerifier = TemplateVerifier()

After

let templateMatcher = TemplateMatcher()

DetectedFace class

  • Face, DetectedFace, CaptureCandidate API was moved to DetectedFace API.
  • Use DetectedFace to: get face image, create template, evaluate face attributes, evaluate passive liveness.

Before

// get face image
let originalFaceImage: UIImage = detectedFace.image.image
let croppedFaceImage: UIImage = detectedFace.cropedFace

// create template
let template = detectedFace.template

// evaluate face attributes
let confidenceScore = detectedFace.face.attributeScore(.confidence)?.value

// evaluate passive liveness
let passiveLivenessScore = face.attributeScore(.passiveLiveness)?.value
let passiveLivenessScore = detectedFace.face.attributeScore(.passiveLiveness)?.value
let passiveLivenessScore = captureCandidate.passiveLivenessScore

After

// get face image
let originalFaceImage: BgrRawImage = detectedFace.image
let croppedFaceImage: BgrRawImage = try? detectedFace.createFullFrontalImage()

// create template
let template = try? detectedFace.createTemplate()

// evaluate face attributes
let faceQuality = try? detectedFace.evaluateFaceQuality()

// evaluate passive liveness
let passiveLivenessScore = try? detectedFace.evaluatePassiveLiveness().score

FaceAutoCaptureViewController component

  • Renamed FaceCaptureController to FaceAutoCaptureViewController.
  • Use quality providers to configure quality attributes: MatchingQualityProvider, PassiveLivenessQualityProvider, IcaoQualityProvider.
  • Component starts and stops implicitly on viewWillAppear() and viewWillDisappear() (It also stops when capture process is finished).
  • Update FaceAutoCaptureViewControllerDelegate method signatures and arguments.
  • DetectedFace is returned as a result.

Before

let configuration = FaceCaptureConfiguration(qualityAttributePreset: .passiveLiveness)
let viewController = FaceCaptureController.create(configuration: configuration, style: .init())

After

let provider = PassiveLivenessQualityProvider()
let configuration = try! FaceAutoCaptureConfiguration(qualityAttributes: provider.getQualityAttributes())
let viewController = FaceAutoCaptureViewController.create(configuration: configuration, style: .init())

FaceSimpleCaptureViewController component

  • Renamed FaceCaptureSimpleController to FaceSimpleCaptureViewController
  • Update FaceSimpleCaptureViewControllerDelegate method signatures and arguments.
  • DetectedFace is returned as a result.

Before

let viewController = FaceCaptureSimpleController.create(configuration: .init(), style: .init())

After

let viewController = FaceSimpleCaptureViewController.create(configuration: .init(), style: .init())

EyeGazeLivenessViewController component

  • Renamed LivenessCheckController to EyeGazeLivenessViewController
  • Update EyeGazeLivenessViewControllerDelegate method signatures and arguments.

Before

let configuration = LivenessConfiguration(transitionType: .move) {
   $0.segments = [DOTSegment(targetPosition: .bottomRight, duration: 500),
                  DOTSegment(targetPosition: .bottomLeft, duration: 500),
                  DOTSegment(targetPosition: .topRight, duration: 500),
                  DOTSegment(targetPosition: .bottomRight, duration: 500),
                  DOTSegment(targetPosition: .topLeft, duration: 500),
                  DOTSegment(targetPosition: .bottomLeft, duration: 500),
                  DOTSegment(targetPosition: .topRight, duration: 500)]
   $0.minValidSegmentsCount = 5
}
let viewController = LivenessCheckController.create(configuration: configuration, style: .init())

After

// static segments
let configuration = try! EyeGazeLivenessConfiguration(
   transitionType: .move,
   segments: [Segment(targetCorner: .bottomRight, durationMillis: 500),
              Segment(targetCorner: .bottomLeft, durationMillis: 500),
              Segment(targetCorner: .topRight, durationMillis: 500),
              Segment(targetCorner: .bottomRight, durationMillis: 500),
              Segment(targetCorner: .topLeft, durationMillis: 500),
              Segment(targetCorner: .bottomLeft, durationMillis: 500),
              Segment(targetCorner: .topRight, durationMillis: 500)],
   minValidSegmentCount: 5
)
let viewController = EyeGazeLivenessViewController.create(configuration: configuration, style: .init())

// random segments
let generator = RandomSegmentsGenerator()
let segmentCount = 6
let segmentDurationMillis = 1000
let segments = generator.generate(segmentCount: segmentCount, segmentDurationMillis: segmentDurationMillis)
let configuration = try! EyeGazeLivenessConfiguration(transitionType: transitionType,
                                                      segments: segments,
                                                      minValidSegmentCount: 4)
let viewController = EyeGazeLivenessViewController.create(configuration: configuration, style: .init())

LivenessCheck2Controller component

LivenessCheck2Controller was removed. In order to achieve similar functionality, client can combine FaceAutoCaptureViewController and EyeGazeLivenessViewController.


Image Conversion

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

Create BgrRawImage from CGImage:

let bgrRawImage = BgrRawImageFactory.create(cgImage: cgImage)

Create CGImage from BgrRawImage:

let cgImage = CGImageFactory.create(bgrRawImage: self)

FaceImage class

  • Init with BgrRawImage instead of UIImage.

Before

let uImage = UIImage(named: "test")
let faceImage = FaceImage(image: uImage)

After

let uImage = UIImage(named: "test")
let bgrRawImage = BgrRawImageFactory.create(cgImage: uImage.cgImage!)
let faceImage = FaceImage(image: 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]