Skip to content

Custom Face Detector with Quality Function

You can create your own face detector with a quality function if you don't want to use the default LocalFaceDetector and wish to use it together with IadCameraController.

Creating a Custom Face Detector

A custom face detector should implement the AutocaptureFaceDetector<Jpeg, *> interface. In this example, we use GoogleFaceDetector:

// Copied from the official Google repository:
// https://github.com/googlesamples/mlkit/blob/master/android/vision-quickstart/app/src/main/java/com/google/mlkit/vision/demo/kotlin/facedetector/FaceDetectorProcessor.kt
class GoogleFaceDetector : AutocaptureFaceDetector<Jpeg, List<Face>>, AutoCloseable {

    private val uiHandler = Handler(Looper.getMainLooper())
    var onDetectionResultListener: OnDetectionResultListener? = null

    private val detector = FaceDetection.getClient(
        FaceDetectorOptions.Builder()
            .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
            .build(),
    )

    private var cachedFaces: List<Face> = listOf()

    override fun detect(image: Jpeg): List<Face> {
        val bitmap = BitmapFactory.decodeByteArray(
            image.content,
            0,
            image.content.size,
        )

        val task = detector.process(
            InputImage.fromBitmap(bitmap, image.imageInfo.rotationDegrees),
        )

        val latch = CountDownLatch(1)
        task.addOnSuccessListener { facesList ->
            cachedFaces = facesList
            latch.countDown()
        }

        task.addOnFailureListener {
            throw it
            latch.countDown()
        }

        task.addOnCanceledListener {
            latch.countDown()
        }

        latch.await()

        uiHandler.post {
            onDetectionResultListener?.onDetectionResult(cachedFaces)
        }

        return cachedFaces
    }

    override fun isLastImageSuitableForCapturing(): Boolean {
        // Determine whether the latest image satisfies the conditions for automatic capturing.
        // This will be used by IadCameraController to trigger photo capture.
        // Important note: There is no guarantee that returning `true` will result in an actual capture.
        // The IadCameraController will attempt to capture only if the other internal conditions allow it.
        return (cachedFaces.firstOrNull()?.smilingProbability ?: 0f) >= 0.5f
    }

    override fun close() {
        detector.close()
    }
}

Integrating the Custom Face Detector

Simply replace LocalFaceDetector with your custom face detector in the constructor of IadCameraController:

val faceDetector = GoogleFaceDetector(),
val cameraController = IadCameraController(faceDetector, previewView, lifecycleOwner)

More Information

You can find an example of this functionality in the idlive-face-capture-android-X.X.X-release/iad-example folder.