Usage examples#
Applies to LUNA ID for Android only.
Basic example: Face capture and verification#
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// SDK initialization
val config = LunaConfig.create(
livenessType = LivenessType.Offline,
bestShotsCount = 1
)
LunaID.initEngine(
context = applicationContext,
lunaConfig = config
)
// Waiting for the initialization
lifecycleScope.launch {
LunaID.engineInitStatus
.filter { it is LunaID.EngineInitStatus.Success }
.first()
// Camera launch
val params = ShowCameraParams(
checkSecurity = true,
minFaceSideToMinScreenSide = 0.3f
)
val interactions = Interactions.Builder()
.addInteraction(BlinkInteraction(timeoutMs = 5000))
.build()
LunaID.showCamera(
context = this@MainActivity,
params = params,
interactions = interactions
)
}
// Result handling
lifecycleScope.launch {
LunaID.bestShot.collect { bestShotFound ->
bestShotFound?.let {
val bestShot = it.bestShot
// Performing verification
verifyUser(bestShot)
}
}
}
}
private fun verifyUser(bestShot: BestShot) {
val apiV6 = LunaID.apiHuman?.apiV6 ?: return
val query = VerifyQuery(
userId = "user123",
warp = true,
photo = bestShot.image.toByteArray()
)
apiV6.verify(query) { result ->
when (result) {
is Result.Success -> {
val verified = result.data.images
.flatMap { it.detections.faceDetections }
.flatMap { it.verifications }
.any { it.status }
if (verified) {
// The user has been verified
} else {
// Verification failed
}
}
is Result.Error -> {
// Error handling
}
}
}
}
}
Example: Registering a new user#
private fun registerUser(bestShot: BestShot) {
val apiV6 = LunaID.apiHuman?.apiV6 ?: return
val query = ExtractQuery(
userData = "John Doe",
externalId = "user123",
warp = true,
photo = bestShot.image.toByteArray()
)
apiV6.extract(query) { result ->
when (result) {
is Result.Success -> {
val personId = result.data.personId
// User registered with ID = personId
}
is Result.Error -> {
// Handling registration error
}
}
}
}
Example: User identification#
private fun identifyUser(bestShot: BestShot) {
val apiV6 = LunaID.apiHuman?.apiV6 ?: return
val query = IdentifyQuery(
warp = true,
photo = bestShot.image.toByteArray()
)
apiV6.identify(query) { result ->
when (result) {
is Result.Success -> {
val candidates = result.data.images
.flatMap { it.detections.faceDetections }
.flatMap { it.identifications }
.flatMap { it.candidates }
.sortedByDescending { it.similarity }
if (candidates.isNotEmpty()) {
val bestMatch = candidates.first()
// Found user with ID = bestMatch.personId
// Similarity = bestMatch.similarity
} else {
// User not found
}
}
is Result.Error -> {
// Error handling
}
}
}
}
Example: OneShotLiveness estimation with multiple frames#
private fun checkLiveness(bestShots: List<BestShot>) {
val apiV6 = LunaID.apiHuman?.apiV6 ?: return
val photos = bestShots.map { it.image.toByteArray() }
val query = PredictLivenessQuery(
photos = photos,
aggregate = true
)
apiV6.liveness(query) { result ->
when (result) {
is Result.Success -> {
val aggregate = result.data.aggregateEstimation
val isAlive = aggregate?.predictionResult?.prediction == 1
val probability = aggregate?.predictionResult?.estimations?.probability ?: 0f
if (isAlive && probability > 0.8f) {
// The user is alive, high probability
} else {
// Liveness estimation failed
}
}
is Result.Error -> {
// Error handling
}
}
}
}
Example: Process all events#
private fun setupEventHandlers() {
lifecycleScope.launch {
LunaID.eventChannel.consumeAsFlow().collect { event ->
when (event) {
is LunaID.Event.Started -> {
Log.d("LunaID", "Camera launched")
}
is LunaID.Event.LivenessCheckStarted -> {
Log.d("LunaID", "Liveness estimation started")
}
is LunaID.Event.InteractionStarted -> {
val message = Interaction.message(
context = this@MainActivity,
type = event.type
)
Log.d("LunaID", "Interaction started: $message")
// Show hint to a user
}
is LunaID.Event.InteractionEnded -> {
Log.d("LunaID", "Interaction completed")
}
is LunaID.Event.InteractionTimeout -> {
Log.w("LunaID", "Interaction timeout expired")
// Show an error message
}
is LunaID.Event.BestShotFound -> {
Log.d("LunaID", "Best shot found")
handleBestShot(event.bestShot)
}
is LunaID.Event.LivenessCheckFailed -> {
Log.w("LunaID", "Liveness estimation failed")
}
is LunaID.Event.SecurityCheck.Success -> {
Log.d("LunaID", "Liveness estimation passed")
}
is LunaID.Event.SecurityCheck.Failure -> {
Log.e("LunaID", "Security check failed")
}
is LunaID.Event.FatalError -> {
Log.e("LunaID", "Critical error", event.e)
}
else -> { /* other events */ }
}
}
}
}