Skip to content

Using descriptors#

Descriptors are compact, binary data sets generated by the recognition system based on the analyzed facial characteristics. These descriptors serve as unique numerical representations of faces and are used for tasks such as face matching, verification, and identification.

LUNA ID uses the cnn60m_arm.plan file that contains a pre-trained neural network model that extracts these descriptors from source images. The file contains a compact set of properties and helper parameters necessary for efficient descriptor generation.

Using the cnn60m_arm.plan file to generate descriptors will increase the size of your application. To learn how to measure and manage the added size, see Measure LUNA ID size.

In LUNA ID for Android#

Required dependency#

Descriptor-related functionality is provided through the following package:

  • ai.visionlabs.lunaid:cnn60:X.X.X

The useDescriptors parameter controls whether descriptor-related functionality is enabled within the SDK, allowing you to optimize your app’s size and performance based on actual usage.

Set useDescriptors = true (default) if your application uses any of the following methods from the LunaUtils class:

  • LunaUtils.getDescriptorFromWarped()
  • LunaUtils.getDescriptor()
  • LunaUtils.matchDescriptors()

For details on the methods, see the Core methods section.

The useDescriptors parameter should be set during engine initialization as part of the LunaConfig:

val config = LunaConfig(
    // other parameters...
    useDescriptors = true // default value
)

LunaID.initEngine(applicationContext, config, apiHumanConfig, licenseFile)

If your application does not implement cnn60m_arm.plan or use descriptor functionality, you can set useDescriptors = false to reduce SDK overhead and optimize app performance.

Core methods#

To generate or compare descriptors, you can use methods from the LunaUtils class. Below are examples of the available methods:

    public fun getDescriptorFromWrapped(
    warp: Bitmap,
    @DescriptorVersion descriptorVersion: Int = V60
): ByteArray {
    // Returns a descriptor generated from a wrapped image
}

public fun getDescriptor(
    image: Bitmap,
    @DescriptorVersion descriptorVersion: Int = V60
): ByteArray {
    // Returns a descriptor generated from a raw image
}

public fun matchDescriptors(
    first: ByteArray,
    second: ByteArray,
    @DescriptorVersion descriptorVersion: Int = V60
): Float {
    // Compares two descriptors and returns a similarity score
}
Component Description
descriptorVersion Determines the model version used for descriptor generation or comparison.
getDescriptorFromWrapped Generates a descriptor from a preprocessed (wrapped) image.
getDescriptor Generates a descriptor directly from a raw image in Bitmap format.
matchDescriptors Compares two descriptors and returns a similarity score (Float) between 0 (no match) and 1 (perfect match).

Usage example#

Below is an example of extracting and comparing descriptors from two best shots.

Note: Descriptor extraction and comparison are not limited to best shots obtained through LUNA ID. You can also use any bitmap image containing a single face.

The process involves three main steps:

Step 1: Getting best shots for descriptor extraction#

To extract descriptors, first obtain the best shots using the LunaID.bestShot flow. The following code demonstrates how to collect and assign the best shots for two faces:

LunaID.bestShot.collect { result ->
    result?.let {
        when (searchingFace) {
            SearchingFace.FIRST -> bitmapOfFirstFace = result.bestShot.warp
            SearchingFace.SECOND -> bitmapOfSecondFace = result.bestShot.warp
        }
    }
}

Step 2: Extracting descriptors from bitmap images#

Once the best shots are obtained, use the LunaUtils.getDescriptor method to extract descriptors from the bitmap images. Specify the descriptor version as shown below:

val firstDescriptor = LunaUtils.getDescriptor(
    bitmapOfFirstFace,
    descriptorVersion = V60
)

val secondDescriptor = LunaUtils.getDescriptor(
    bitmapOfSecondFace,
    descriptorVersion = V60
)

Step 3: Comparing descriptors#

To compare the extracted descriptors, use the LunaUtils.matchDescriptors method. This method calculates a similarity score between the two descriptors, where 1 indicates a perfect match and 0 indicates no similarity:

val similarityScore = LunaUtils.matchDescriptors(
    firstDescriptor,
    secondDescriptor,
    descriptorVersion = V60
)
Log.d("FaceSimilarity", "Similarity score: $similarityScore")

The resulting similarityScore provides a quantitative measure of how similar the two faces are.

In LUNA ID for iOS#

To calculate descriptors, LUNA ID for iOS uses the cnn60m_arm.plan file.