Android face detection library using RetinaFace model compatible with Ver-ID SDK.
The FaceDetectionRetinaFace class implements the FaceDetection interface from the Ver-ID common types library, making it simple to use with Ver-ID SDK components.
Add the dependency in your build.gradle.kts file:
dependencies {
implementation(platform("com.appliedrec:verid-bom:2025-08-00"))
implementation("com.appliedrec:face-detection-retinaface")
// To convert between Android bitmaps and Ver-ID images
implementation("com.appliedrec:verid-serialization")
}The face detector is primarily meant to rapidly capture one face for face recognition but the API allows for up to 100 faces to be requested. You can set the limit in the limit parameter.
class MyActivity : ComponentActivity() {
// Detect face in a bitmap and draw the image with the face in an image view
fun detectFaceInImage(
bitmap: Bitmap,
imageView: ImageView
) = lifecycleScope.launch {
// Create face detection instance
FaceDetectionRetinaFace.create(applicationContext).use { faceDetection ->
// Convert bitmap to Ver-ID image
val image = Image.fromBitmap(bitmap)
// Detect one face
faceDetection.detectFacesInImage(image, 1).firstOrNull()
}?.let { face ->
// If face detected create a copy of the input bitmap
val annotated = bitmap.copy(Bitmap.Config.ARGB_8888, true)
// Wrap the bitmap in a canvas
val canvas = Canvas(annotated)
// Define paint for the face outline
val paint = Paint().apply {
color = Color.GREEN
style = Paint.Style.STROKE
strokeWidth = bitmap.width.toFloat() / 100f
isAntiAlias = true
}
// Draw the face boundary on the canvas
canvas.drawRect(face.bounds, paint)
// Switch to UI thread
withContext(Dispatchers.Main) {
// Draw the bitmap in the image view
imageView.setImageBitmap(annotated)
}
} ?: run {
// No face detected, draw the original bitmap in the image view
withContext(Dispatchers.Main) {
imageView.setImageBitmap(bitmap)
}
}
}
}Note that the FaceDetectionRetinaFace.create function runs a calibration to determine which variant of the face detection model performs best on the device. This calibration can take a few seconds to run. The result of the calibration is stored in shared preferences and the calibration is not rerun unless the FaceDetectionRetinaFace.create's parameter forceCalibrate is set to true.
If, for some reason, you want to avoid the calibration you can call the FaceDetectionRetinaFace class constructor directly with the model file variant and NNAPI options. For example, to run inference on non-quantised model without using NNAPI, you can construct the face detection instance like this:
FaceDetectionRetinaFace(context, SessionConfiguration.FP32)However, be careful. Not all configurations are supported on all devices and the constructor may throw an exception.
The use function is similar to how Closeable works with try-with-resources but the body of the function runs in a coroutine scope.
This:
val faces = FaceDetectionRetinaFace.create(context).use { faceDetection ->
faceDetection.detectFacesInImage(image, 1)
}is equivalent of this:
val faceDetection = FaceDetectionRetinaFace.create(context)
try {
val faces = faceDetection.detectFacesInImage(image, 1)
} finally {
faceDetection.close()
}