Skip to content

Best shot estimations#

This topic describes estimations that LUNA ID performs to evaluate image quality and determine whether the given image is the best shot or not.

How it works#

LUNA ID searches for a face in each frame of a video stream recorded with your device's camera. The frame must contain only one face for LUNA ID to perform a series of estimations. Only frames with faces that pass these estimations are considered the best shots.

In LUNA ID for Android, the LunaID.allEvents() event (or more specialized LunaID.finishStates()) will emit the ResultSuccess event with the best shot found and an optional path to the recorded video.

In LUNA ID for iOS, the CameraUIDelegate.bestShot() callback receives the best shot.

If an estimation fails, the corresponding error message is returned.

In LUNA ID for Android, the best shot estimations are specified in LunaConfig.kt.

In LUNA ID for iOS, you can change values of best shot estimations' parameters in the LCLunaConfiguration structure.

Estimations#

LUNA ID performs the following estimations to determine whether an image is the best shot:

Face detection bounding box size#

Description#

The estimation determines that a bounding box size with the detected face corresponds to the specified size. The estimation helps to check if a face is far from the camera.

The minimum recommended size of the face bounding box is 200x200 pixels.

The default value is 200 pixels.

LUNA ID for Android LUNA ID for iOS
public const val DEFAULT_MIN_DETECT_FRAME_SIZE: Int = 200 LCLunaConfiguration → bestShotConfiguration → minDetSize = 200;

Implementation#

LUNA ID for Android LUNA ID for iOS
public val detectFrameSize: Int = DEFAULT_MIN_DETECT_FRAME_SIZE @property (nonatomic, assign) NSInteger minDetSize;

Frame edges offset#

Description#

The estimation determines the distance from the frame edges and is based on the face detection bounding box size estimation.

The minimal border distance for best shot estimation without further OneShotLiveness estimation is 0 pixels.

For OneShotLiveness estimation, the minimal border distance is 10 pixels.

The default value is 0 pixels in LUNA ID for Android and 10 pixels in LUNA ID for iOS.

Eye state#

Description#

The estimation determines an eye state: open, closed, occluded.

In LUNA ID for Android, a frame with a face with closed eyes can be considered to be the best shot. For details, see Getting the best shot with faces with closed eyes.

In LUNA ID for iOS, the frames in which one or both eyes are closed are skipped.

If Dynamic Liveness is enabled, all frames can be considered the best shots, despite the eyes status.

Implementation#

LUNA ID for Android LUNA ID for iOS
The estimation is performed only if eye interaction is enabled. @property (nonatomic, assign) BOOL checkEyes;
If set to true, the best shot with closed eyes will be skipped.

Head pose#

Description#

The estimation determines a person’s head rotation angles in 3D space, that is pitch, yaw, and roll.

The pitch rotation angle limits the head rotation along the X axis.

The yaw rotation angle limits the head rotation along the Y axis.

The roll rotation angle limits the head rotation along the Z axis.

Head pose

Acceptable angle ranges, in degrees, are 0-45.

The pitch, yaw, and roll values must be between the minimal and maximum valid head position values.

By default, all rotation angles are set to 25 degrees.

We recommend that you specify the following values for the rotation angles:

Angle LUNA ID for Android LUNA ID for iOS
Pitch public const val DEFAULT_HEAD_PITCH: Float = 15F LCLunaConfiguration → bestShotConfiguration → estimationThreshold → headPitch = 15;
Yaw public const val DEFAULT_HEAD_YAW: Float = 15F LCLunaConfiguration → bestShotConfiguration → estimationThreshold → headYaw = 15;
Roll public const val DEFAULT_HEAD_ROLL: Float = 15F LCLunaConfiguration → bestShotConfiguration → estimationThreshold → headRoll = 15;

Implementation#

Angle LUNA ID for Android LUNA ID for iOS
Pitch public val headPitch: Float = DEFAULT_HEAD_PITCH @property (nonatomic) CGFloat headPitch;
Yaw public val headYaw: Float = DEFAULT_HEAD_YAW @property (nonatomic) CGFloat headYaw;
Roll public val headRoll: Float = DEFAULT_HEAD_ROLL @property (nonatomic) CGFloat headRoll;

AGS (Approximate Garbage Score)#

Description#

The estimation determines the source image score for further descriptor extraction and matching.

An estimation output is a float score which is normalized in range [0..1]. The closer score to 1, the better matching result is received for the image.

The AGS estimation value must be between the minimal and maximum values:

LUNA ID for Android LUNA ID for iOS
public const val AGS_MIN: Float = 0F LCLunaConfiguration → bestShotConfiguration → estimationThreshold → ags = 0;
public const val AGS_MAX: Float = 1F LCLunaConfiguration → bestShotConfiguration → estimationThreshold → ags = 1;

The default value is 0.5 in Luna ID for Android and 0.2 in LUNA ID for iOS.

LUNA ID for Android LUNA ID for iOS
public const val DEFAULT_AGS: Float = 0.5F LCLunaConfiguration → bestShotConfiguration → estimationThreshold → ags = 0.2;

Implementation#

LUNA ID for Android LUNA ID for iOS
public val ags: Float = DEFAULT_AGS @property (nonatomic) CGFloat ags;

Image quality estimation#

Description#

The estimation determines an image quality by the following criteria:

  • The image is blurred.
  • The image is underexposed, that is, too dark.
  • The image is overexposed, that is, too light.
  • The face in the image is illuminated unevenly and there is a great difference between dark and light regions.
  • The image contains flares on face, that is, too specular.

To perform the estimation, LUNA ID uses the LUNA SDK SubjectiveQuality estimator. For details, see Image Quality Estimation.

The default values are:

Parameter Default value
Blurriness 0.61
Lightness 0.57
Darkness 0.50
Illumination 0.1
Specularity 0.1

For details on how to change the default values, see Changing best shot image quality estimation thresholds.

Best shot capture period#

Description#

The estimation determines that the frame was received in the time interval allotted for the best shot.

The estimation is performed only in LUNA ID for iOS.

The default value is 5.

Implementation#

@property (nonatomic, assign) NSTimeInterval interactionTimeout;

Face occlusion#

Description#

The estimation determines whether the face in the frame is occluded with something. You can define whether such frames can be considered best shots. For details, see Getting the best shot with an occluded face.

Eye occlusion#

Description#

The estimation determines whether eyes in the frame are occluded with glasses. You can define whether such frames can be best shot candidates.

In LUNA ID for Android, you can specify the following eye occlusion rules:

  • Images of people in sunglasses cannot be considered best shots.
  • Images of people in eyeglasses cannot be considered best shots.
  • Images of people in any glasses cannot be considered best shots.

In LUNA ID for iOS, frames that contain faces with sunglasses will be excluded from best shot candidates. Images that contain faces with eyeglasses can be considered to be best shots.

For details, see Getting the best shot with faces with occluded eyes.