DOT Android Face 8.0.0
This guide describes how to migrate DOT Android Face version 7.x to version 8.0. Only the most important changes are highlighted in this guide. For more details, see the Android Samples.
Migration Steps
Compatibility with DIS
When utilizing DIS for server-side evaluation, ensure compatibility between your DIS version and the corresponding SDK version. Refer to the DIS vs SDKs compatibility table for detailed compatibility information.
Face Detector component (FaceDetector)
FaceDetector.detect()
method now returns list ofFaceDetector.Face
data classes instead of list ofDetectedFace
interfaces.- Use
query: FaceDetectionQuery
argument of theFaceDetector.detect()
method in order to specify desired detection data.
Before
val faceDetector = FaceDetectorFactory.create()
val faceImage = FaceImageFactory.create(bgrRawImage, minFaceSizeRatio, maxFaceSizeRatio)
val detectedFaces = faceDetector.detect(
faceImage = faceImage,
maximumFaces = 1,
)
val detectedFace = detectedFaces.first()
val confidence = detectedFace.getConfidence()
val template = detectedFace.createTemplate()
val fullFrontalImage = detectedFace.createFullFrontalImage()
val faceAspects = detectedFace.evaluateFaceAspects()
val faceQualityQuery = FaceQualityQuery(
imageQuality = FaceImageQualityQuery(
isSharpness = true,
)
)
val faceQuality = detectedFace.evaluateFaceQuality(faceQualityQuery)
val passiveLiveness = detectedFace.evaluatePassiveLiveness()
After
val faceDetector = FaceDetectorFactory.create()
val faces = faceDetector.detect(
faceImage = FaceImage(bgrRawImage, faceSizeRatioInterval),
query = FaceDetectionQuery(
faceQuality = FaceQualityQuery(
imageQuality = FaceImageQualityQuery(
evaluateSharpness = true,
),
),
evaluatePassiveLiveness = true,
createFullFrontalImage = true,
createTemplate = true,
),
limit = 1,
)
val face = faces.first()
val confidence = face.confidence
val faceAspects = face.faceAspects
val faceQuality = face.faceQuality
val passiveLivenessFaceAttribute = face.passiveLivenessFaceAttribute
val fullFrontalBgrRawImage = face.fullFrontalBgrRawImage
val template = face.template
All UI components use a query in their configurations
- Use
query: FaceDetectionQuery
argument of the*Fragment.Configuration
data class in order to specify desired detection data of the result.
Before
// Example of a subclass of FaceAutoCaptureFragment
override fun onCaptured(result: FaceAutoCaptureResult) {
val detectedFace = result.detectedFace!!
val confidence = detectedFace.getConfidence()
val template = detectedFace.createTemplate()
val fullFrontalImage = detectedFace.createFullFrontalImage()
val faceAspects = detectedFace.evaluateFaceAspects()
val faceQualityQuery = FaceQualityQuery(
imageQuality = FaceImageQualityQuery(
isSharpness = true,
),
)
val faceQuality = detectedFace.evaluateFaceQuality(faceQualityQuery)
val passiveLiveness = detectedFace.evaluatePassiveLiveness()
}
After
// Example of a subclass of FaceAutoCaptureFragment
override fun provideConfiguration() = FaceAutoCaptureFragment.Configuration(
query = FaceDetectionQuery(
faceQuality = FaceQualityQuery(
imageQuality = FaceImageQualityQuery(
evaluateSharpness = true,
),
),
evaluatePassiveLiveness = true,
createFullFrontalImage = true,
createTemplate = true,
),
)
override fun onCaptured(result: FaceAutoCaptureResult) {
val face = result.face
val confidence = face.confidence
val faceAspects = face.faceAspects
val faceQuality = face.faceQuality
val passiveLivenessFaceAttribute = face.passiveLivenessFaceAttribute
val fullFrontalBgrRawImage = face.fullFrontalBgrRawImage
val template = face.template
}
Eye Gaze Liveness UI component (EyeGazeLivenessFragment)
- Replace usage of
EyeGazeLivenessFragment
. More details are in the integration manual and the API reference. The following points are the minimum changes required in order to migrate to version 8.0.0. - The
EyeGazeLivenessResult.content
property is a new addition that serves the same purpose as all other properties named*Result.content
found in other UI components. This property is intended for server-side evaluation. Support for theEyeGazeLivenessResult.content
property was introduced in DIS version 1.39.0. - Add callback
EyeGazeLivenessFragment.onProcessed()
. - Add callback
EyeGazeLivenessFragment.onCriticalFacePresenceLost()
. Before the component started again after the face presence was lost. Since version 8.0.0 there is an option to handle this kind of event via this callback. E.g. you can start over (as prior to version 8.0.0) by callingeyeGazeLivenessFragment.start()
method. - Replace
EyeGazeLivenessFragment.onFinished()
withEyeGazeLivenessFragment.onFinished()
. The new callback returns a new data classEyeGazeLivenessResult
. Score of the liveness check is present in theEyeGazeLivenessResult
only if this feature is enabled by the license. The score isnull
otherwise. - Replace
EyeGazeLivenessFragment.onNoMoreSegments()
withEyeGazeLivenessFragment.onAllCornersUsed()
. - Remove callback
EyeGazeLivenessFragment.onStateChanged()
. Since version 8.0.0 there is a new callbackEyeGazeLivenessFragment.onProcessed()
for handling the current state of the process. - Remove callback
EyeGazeLivenessFragment.onEyesNotDetected()
. CallbackEyeGazeLivenessFragment.onCriticalFacePresenceLost()
is used for this event (eyes are not clearly visible in the first corner). - Remove callback
EyeGazeLivenessFragment.onFaceTrackingFailed()
. This callback was not used in real use cases.
Before
override fun onStateChanged(eyeGazeLivenessState: EyeGazeLivenessState) {
// Handle callback
}
override fun onFinished(score: Float, segmentImages: List<SegmentImage>) {
// Handle callback
}
override fun onNoMoreSegments() {
// Handle callback
}
override fun onEyesNotDetected() {
// Handle callback
}
override fun onFaceTrackingFailed() {
// Handle callback
}
After
override fun onProcessed(detection: FaceAutoCaptureDetection) {
// Handle callback
}
override fun onFinished(result: EyeGazeLivenessResult) {
// Handle callback
}
override fun onAllCornersUsed() {
// Handle callback
}
override fun onCriticalFacePresenceLost() {
// Handle callback
}
Passing Eye Gaze Liveness configuration to EyeGazeLivenessFragment
- Replace data class
EyeGazeLivenessConfiguration
withEyeGazeLivenessFragment.Configuration
. - Replace interface
SegmentsGenerator
and implementationRandomSegmentsGenerator
withCornersGenerator
and factoryCornersGeneratorFactory
. - Replace property
Segment.durationMillis
withEyeGazeLivenessFragment.Configuration.transitionDurationMillis
. - Instead of passing the configuration as a fragment argument, override
EyeGazeLivenessFragment.provideConfiguration()
method.
Before
val segmentCount = 8
val segmentDurationMillis = 800
val segments = RandomSegmentsGenerator().generate(segmentCount, segmentDurationMillis)
val configuration = EyeGazeLivenessConfiguration.Builder(segments)
.minFaceSizeRatio(0.1)
.maxFaceSizeRatio(0.3)
.transitionType(EyeGazeLivenessConfiguration.TransitionType.MOVE)
.build()
val bundle = bundleOf(EyeGazeLivenessFragment.CONFIGURATION to configuration)
findNavController().navigate(R.id.action, bundle)
After
private val cornersGenerator = CornersGeneratorFactory.create()
...
override fun provideConfiguration() = Configuration(
corners = cornersGenerator.generate(count = 8),
faceSizeRatioInterval = IntervalDouble(min = 0.1, max = 1.3),
transitionDurationMillis = 800,
transitionType = Configuration.TransitionType.MOVE,
)