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 the size of a bounding box with the detected face corresponds to the specified size. The estimation helps to check if the face is far from the camera.
The minimum recommended size for the face bounding box is 200 x 200 pixels.
The default value is:
- 200 pixels in LUNA ID for iOS
- 350 dp in LUNA ID for Android
If the value when converting to pixels is less than 100, the frame size will be set to 100 pixels.
LUNA ID for Android | LUNA ID for iOS |
---|---|
public const val DEFAULT_MIN_DETECT_FRAME_SIZE: Int = 350 |
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 or closed.
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.
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.2.
LUNA ID for Android | LUNA ID for iOS |
---|---|
public const val DEFAULT_AGS: Float = 0.2F |
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.
Face occlusion#
Description#
The estimation determines whether the face in the frame is occluded with a medical mask. 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.