Enrollment 28.2.0
Loading...
Searching...
No Matches

The library can be used to detect faces from face captures. More...

Collaboration diagram for Face:

Topics

 Solvers
 The Enrollment SDK package includes large binary files called solvers.

Classes

class  FaceExtractorConfig
 It contains extraction configuration. More...
class  FaceTemplate
 FaceTemplate is Innovatrics proprietary face template. More...
class  ExtractedFace
 ExtractedFace is ICF Template created by FaceExtractor with Face that was extracted. More...
class  CroppedFace
 Represents a face cropped from the original face capture. More...
class  Face
 It holds all functions and data related to Face manipulation. More...
class  Face::Keypoint
 It holds all attributes related to a facial key point. More...
class  Face::Keypoints
 It holds all facial keypoints detected on a FaceCapture image. More...
class  FaceAttributes
 Face attributes Holds the face attributes. More...
class  FaceCaptureDeviceTypeID
 Capture device type identifier The capture device type identifier shall identify the biometric organization that owns the product that created the BDIR. More...
class  FaceCaptureDeviceVendorID
 Capture device vendor identifier The capture device vendor identifier shall identify the biometric organization that owns the product that created the BDIR. More...
class  FaceCapture
 Face capture can contains one or group of people, faces or full body. More...
class  FaceCropConfiguration
 Face crop configuration. More...
class  FaceDetector
 FaceDetector implements detection by means of Innovatrics IFace. More...
class  GlobalFaceExecutor
 Holds instance of FaceExecutor. More...
struct  FailedFaceAttribute
 It contains attribute data that express which and why attribute fails in reliability check. More...
class  FaceAttributeReliability
 Interface for checking reliability of attribute. More...
class  ICAOReliability
 Check if Face will fullfil ICAO requirements. More...
class  TemplateReliability
 Check if template extraction will be reliable. More...
class  AgeReliability
 Check if calculation of Age attribute will be reliable. More...
class  GlassStatusReliability
 Check if calculation of Glass Status attribute will be reliable. More...
class  TintedGlassesReliability
 Check if calculation of Tinted Glasses attribute will be reliable. More...
class  SegmentationMaskReliability
 Check if calculation of Segmentation Mask in functions Face::FaceAreaSegment, Face::FaceAreaSegment(RGB), Face::FaceAreaMask will be reliable. More...
class  FaceSizeReliability
 Check if calculation of Face Size attribute will be reliable. More...
class  MouthOpennessReliability
 Check if calculation of Mouth Openness attribute will be reliable. More...
class  UniversalPassiveLivenessReliability
 Check if calculation of Universal passive liveness will be reliable. More...
class  ISOFullFrontalImageValidator
 Check if usage of Full Frontal Images on travel documents will follow best practices, as described in Section B.3.2 Best practices for use of Full Frontal Images on travel documents [6]. More...
class  OFIQFace
 It provides quality measures as defined in ISO/IEC 29794-5:2025. More...

Typedefs

using FaceSimilarityScore = unsigned int
 It is similarity score between face Templates.

Enumerations

enum class  FaceCaptureDeviceTechnology : uint8_t {
  UNKNOWN = 0 , STATIC_PHOTOGRAPH_FROM_UNKNOWN_SOURCE = 1 , STATIC_PHOTOGRAPH_FROM_DIGITAL_CAMERA = 2 , STATIC_PHOTOGRAPH_FROM_SCANNER = 3 ,
  VIDEO_FRAME_FROM_UNKNOWN_SOURCE = 4 , VIDEO_FRAME_FROM_ANALOGUE_CAMERA = 5 , VIDEO_FRAME_FROM_DIGITAL_CAMERA = 6
}
 It indicates the class of device technology used to acquire the captured biometric sample [6]. More...
enum class  FaceImageType : uint8_t { BASIC = 0 , FULL_FRONTAL = 1 , TOKEN_FRONTAL = 2 , POST_PROCESSED_FRONTAL = 3 }
 Several face image types are introduced to define categories that satisfy requirements of some applications [6]. More...
enum class  FaceCrop : uint8_t { TOKEN_NOT_FRONTAL = 0 , FULL = 1 , TOKEN = 2 , FULL_NOT_ALIGNED = 3 }
 Defines different Crop methods. More...

Functions

static constexpr int FaceToIsoCaptureDeviceTechnology (FaceCaptureDeviceTechnology printCaptureDeviceTechnology)
 Function converts FaceCaptureDeviceTechnology to ISO capture technology.
static constexpr FaceCaptureDeviceTechnology IsoToFaceCaptureDeviceTechnology (int isoCaptureDeviceTechnology)
 Function converts ISO capture technology to FaceCaptureDeviceTechnology.
static constexpr int FaceToIsoImageType (FaceImageType faceImageType)
 Function converts FaceImageType to ISO face image type as defined in iso_19794-5_2011.
static constexpr FaceImageType IsoToFaceImageType (int faceImageType)
 Function converts ISO face image type to FaceImageType.
static constexpr bool IsFaceCropMethodValid (FaceCrop faceCrop)
 Function validates the value of FaceCrop enum.

Detailed Description

The library can be used to detect faces from face captures.

Overview

The library can be used to detect faces from face captures. Face capture can contains one or group of people, faces or full body.

Face Detection

SDK can detect faces of various sizes, orientations, facial hair types or ethnicities. Face can be partly occluded by glasses, sunglasses or hat. SDK can operate with many different lighting conditions and image qualities. Face size is defined as a maximum of values of inter eyes centers distance and distance between center of mouth and center point between eyes: face_size = max(distance(left_eye_center, right_eye_center), distance(mouth_center,eyes_center))

Face Size

Image above shows face size visualizations of various distances of inter eyes centers distances (X=distance(left_eye_center,right_eye_center)) and distances between center of mouth and center point between eyes (Y=distance(mouth_center, eyes_center)). The face size is the maximum of these two distances. It can be seen from images (a), (b) and (c) that the face size (red arrow) defined in this way is invariant to pose of the head (yaw, pitch, roll). The face size can be specified in absolute (pixel distance) or relative value (pixel distance) relative to image size (max(image_height, image_width)) and is important parameter for face detection. SDK can detect faces of various size but there is a lower limit of face size. Upper limit on the face size is not defined. The recommended face size is more than 50 pixels. SDK face processing or recognition functions have the most accurate results when this recommendation is fulfilled. Face area is closely related to the face size. It is an area around a face defined by a bounding rectangle with width = 4 x face_size, height = width / 0.75 (according to ISO/IEC 19794-5 standard, section 9.2). The Point which is the geometric center between eyes is positioned in the face area in position X_Pos, Y_Pos, where Y_Pos = 0.6f x width, and X_Pos relies on the head yaw rotation. The main reason for this is to have the whole head in the face area no matter what the head rotation is.

Face Area

Image above shows face area visualizations of face areas (green boxes) for face in various positions. The face size is defined by distance shown as the red arrow. There are shown different positions of face area according to the face yaw rotation in (a),(b) and (c). Positions of the eyes centers in the face areas are the same in the Y direction (Y_Pos) but changes in the X direction (X_Pos1, X_Pos2, X_Pos3). Width and Height is the same in all three cases. The face area size relative to image area size can specify sizes of faces that should be detected.

Face

If image above has resolution of 730x470 pixels (image_area_size = 730 x 470 = 343100) and face_size is 70 pixels (face_area_width = 70 x 4 = 280, face_area_height = face_area_width / 0.75 = 373, face_area_size = 104440), then relative image size is relative_image_size = 104440 / 343100 = 0.304 (30.4%). Face area is marked with green box and face size with red arrow. Sometimes, when faces are close to image boundaries, their face areas can get out of the image boundaries. Some application may want to find these faces (and filter them out). Due to this reason each face has attribute related to face area visible in image (FaceRelativeAreaInImage).

Face area visible in image.

In the image above relative values are (a) 0.30, (b) 0.5, (c) 1

SDK can detect faces of various rotations. However various face detection modes imply different ranges of detectable faces

fast accurate / balanced / accurate server
Roll <-15, 15 > <-45, 45>
Yaw <-30, 30 > <-90, 90>
Pitch <-30, 30 > <-45, 45>
Possible face rotations (defined as in DIN9300)

Prior to further processing each face in FaceCapture MUST be detected via FaceDetector. SDK provides following detection modes:

  • fast

    The fastest face detector in combination with the fastest face validators and facial features detectors are used when fast mode is used.

    Some faces that are partially occluded faces or faces with sunglasses may be missed. However the speed performance of the face detection is much better as when other modes are used.

    Required Solvers

    Total size of solvers is 559 kB.

    References face-detector-fast.solver, face-detector-eye-validation.solver, face-detector-landmarks-fast.solver

  • accurate_server

    Note
    Not supported in this variant of Enrollment SDK.

Using of different modes can adjust trade-off between speed and accuracy of face detection. Face detection accuracy has two meaning:

  1. ratio between false accepted faces and false rejected faces.
  2. precision of facial keypoints detection.

Face Detection

Face
  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/face.png"));
    auto fc = FaceCapture::Create(std::move(img));
    auto cfg = FaceDetector::Config{};
    FaceDetector fd(cfg);
    auto face = fc->DetectWith(fd)[0];
    auto cropCfg = FaceCropConfiguration();
    auto croppedFace = face->Crop(cropCfg);
    if (not croppedFace->IsCropRegionInsideImage())
    {
    // shrink bounding box into image
    cropCfg.SetCropScale(0.90F);
    auto resizedCrop = face->Crop(cropCfg);
    auto resizedCropRegion =
    fc->Draw(resizedCrop->GetCropRectangle(), Shapes::InnoBlue);
    resizedCropRegion->SaveAs("output/face_crop_box_resized.png");
    }
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector.Config cfg = FaceDetector.Config.Default();
    FaceDetector detector = new FaceDetector(cfg);
    Face face = capture.DetectWith(detector).get(0);
    FaceCropConfiguration cropCfg = new FaceCropConfiguration();
    cropCfg.SetCropMethod(FaceCrop.TOKEN);
    CroppedFace croppedFace = face.Crop(cropCfg);
    if (croppedFace.IsCropRegionInsideImage() == false) {
    // shrink bounding box into image
    cropCfg.SetCropScale(0.90f);
    CroppedFace resizedCrop = face.Crop(cropCfg);
    Image resizedCropRegion = capture.Draw(
    resizedCrop.GetCropRectangle(), Shapes.InnoBlue);
    resizedCropRegion.SaveAs("output/face_crop_box_resized.png");
    }
  • csharp
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector detector = new FaceDetector();
    Face face = capture.DetectWith(detector)[0];
    FaceCropConfiguration cropCfg = new FaceCropConfiguration();
    cropCfg.SetCropMethod(FaceCrop.TOKEN);
    CroppedFace croppedFace = face.Crop(cropCfg);
    if (croppedFace.IsCropRegionInsideImage() == false)
    {
    // shrink bounding box into image
    cropCfg.SetCropScale(0.90f);
    CroppedFace resizedCrop = face.Crop(cropCfg);
    Image resizedCropRegion =
    capture.Draw(resizedCrop.GetCropRectangle(), Shapes.InnoBlue);
    resizedCropRegion.SaveAs("output/face_crop_box_resized.png");
    }

The output of example

Face with crop region outside of image
Face with shrunken crop

Face Detection with various crops

Once a face is detected, a Face object is provided. It is possible to set various crop methods via Face::Crop() method.

  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/face.png"));
    auto fc = FaceCapture::Create(std::move(img));
    auto cfg = FaceDetector::Config{};
    FaceDetector fd(cfg);
    auto face = fc->DetectWith(fd)[0];
    FaceCropConfiguration cropCfg;
    cropCfg.SetCropBackground(Colors::InnoBlue);
    auto full = face->Crop(cropCfg)->GetFaceCapture();
    auto fullNotAligned = face->Crop(cropCfg)->GetFaceCapture();
    auto token = face->Crop(cropCfg)->GetFaceCapture();
    auto tokenNotFrontal = face->Crop(cropCfg)->GetFaceCapture();
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector detector = new FaceDetector();
    Face face = capture.DetectWith(detector).get(0);
    FaceCropConfiguration cropCfg = new FaceCropConfiguration();
    cropCfg.SetCropBackground(Colors.InnoBlue);
    cropCfg.SetCropMethod(FaceCrop.FULL);
    FaceCapture full = face.Crop(cropCfg).GetFaceCapture();
    cropCfg.SetCropMethod(FaceCrop.FULL_NOT_ALIGNED);
    FaceCapture fullNotAligned = face.Crop(cropCfg).GetFaceCapture();
    cropCfg.SetCropMethod(FaceCrop.TOKEN);
    FaceCapture token = face.Crop(cropCfg).GetFaceCapture();
    cropCfg.SetCropMethod(FaceCrop.TOKEN_NOT_FRONTAL);
    FaceCapture tokenNotFrontal = face.Crop(cropCfg).GetFaceCapture();
  • csharp
    var img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    var capture = new FaceCapture(img);
    var detector = new FaceDetector();
    var face = capture.DetectWith(detector)[0];
    var cropCfg = new FaceCropConfiguration();
    cropCfg.SetCropBackground(Colors.InnoBlue);
    cropCfg.SetCropMethod(FaceCrop.FULL);
    var full = face.Crop(cropCfg).GetFaceCapture();
    cropCfg.SetCropMethod(FaceCrop.FULL_NOT_ALIGNED);
    var fullNotAligned = face.Crop(cropCfg).GetFaceCapture();
    cropCfg.SetCropMethod(FaceCrop.TOKEN);
    var token = face.Crop(cropCfg).GetFaceCapture();
    cropCfg.SetCropMethod(FaceCrop.TOKEN_NOT_FRONTAL);
    var tokenNotFrontal = face.Crop(cropCfg).GetFaceCapture();

The output of example

Face with FULL crop configuration
Face with FULL_NOT_ALIGNED crop
Face with TOKEN crop
Face with TOKEN_NOT_FRONTAL crop

Faces Detection

It is possible to detect multiple faces (up to 16) in FaceCapture.

Faces

The faces are detected with function FaceCapture::DetectWith.

  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/faces.png"));
    auto fc = FaceCapture::Create(std::move(img));
    FaceDetector fd;
    auto faces = fc->DetectWith(fd);
    unsigned int index = 0;
    for (const auto& face : faces)
    {
    const std::string name = "output/face_" + std::to_string(index++) + ".png";
    face->Crop({})->GetFaceCapture()->image->SaveAs(name);
    }
    auto boundingBoxes = fc->Draw(faces, Shapes::InnoBlue);
    boundingBoxes->SaveAs("output/faces_bounding_boxes.png");
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/faces.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector detector = new FaceDetector();
    Faces faces = capture.DetectWith(detector);
    int index = 0;
    for (Face face : faces) {
    face.Crop(new FaceCropConfiguration())
    .GetFaceCapture()
    .getImage()
    .SaveAs("output/face_" + index + ".png");
    index++;
    }
    Image boundingBoxes = capture.Draw(faces, Shapes.InnoBlue);
    boundingBoxes.SaveAs("output/faces_bounding_boxes.png");
  • csharp
    Image img = Image.Decode(BinaryFile.ReadAll("assets/faces.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector detector = new FaceDetector();
    Faces faces = capture.DetectWith(detector);
    int index = 0;
    foreach (Face face in faces)
    {
    face.Crop(new FaceCropConfiguration())
    .GetFaceCapture()
    .image.SaveAs("output/face_" + index + ".png");
    index++;
    }
    Image boundingBoxes = capture.Draw(faces, Shapes.InnoBlue);
    boundingBoxes.SaveAs("output/faces_bounding_boxes.png");

The output of example are detected faces

Detect Faces

and unique faces

Detected face 1
Detected face 2
Detected face 3
Detected face 4

Extraction

We provide Internal Innovatrics template for Face. The main goal is to create template for further processing e.g. 1:1 Verification.

  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/face.png"));
    auto fc = FaceCapture::Create(std::move(img));
    FaceDetector fd;
    // Detect face
    auto face = fc->DetectWith(fd)[0];
    auto faceTemplate = face->Extract(cfg);
    BinaryFile::WriteAll("output/face.ics", faceTemplate->data);
    std::cout << " Template Version: " << faceTemplate->GetVersion() << std::endl;
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture fc = new FaceCapture(img);
    FaceDetector fd = new FaceDetector();
    Face face = fc.DetectWith(fd).get(0);
    FaceExtractorConfig cfg = FaceExtractorConfig.Default();
    ExtractedFace faceTemplate = face.Extract(cfg);
    BinaryFile.WriteAll("output/face.ics", faceTemplate.getData());
    System.out.println(" Template Version: " + faceTemplate.GetVersion());
  • csharp
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture fc = new FaceCapture(img);
    FaceDetector fd = new FaceDetector();
    Face face = fc.DetectWith(fd)[0];
    FaceExtractorConfig cfg = FaceExtractorConfig.Default();
    ExtractedFace faceTemplate = face.Extract(cfg);
    BinaryFile.WriteAll("output/face.ics", faceTemplate.data);
    System.Console.WriteLine(" Template Version: " + faceTemplate.GetVersion());

1 to 1 Verification

We provide verification of face templates. The main goal is to calculate Similarity Score for given probe and gallery templates. The examples uses same image for probe and gallery

Face
  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/face.png"));
    auto fc = FaceCapture::Create(std::move(img));
    FaceDetector fd;
    auto face = fc->DetectWith(fd)[0];
    auto probe = face->Extract();
    auto gallery = face->Extract();
    auto score = probe->SimilarWith(*gallery);
    std::cout << " Match Score: " << score << std::endl;
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture fc = new FaceCapture(img);
    FaceDetector fd = new FaceDetector();
    Face face = fc.DetectWith(fd).get(0);
    ExtractedFace probe = face.Extract();
    ExtractedFace gallery = face.Extract();
    long score = probe.SimilarWith(gallery);
    System.out.println(" Match Score: " + score);
  • csharp
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture fc = new FaceCapture(img);
    FaceDetector fd = new FaceDetector();
    Face face = fc.DetectWith(fd)[0];
    ExtractedFace probe = face.Extract();
    ExtractedFace gallery = face.Extract();
    uint score = probe.SimilarWith(gallery);
    System.Console.WriteLine(" Match Score: " + score);

Face Segmentation

It is possible to distinguish face and background once face is detected.

  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/face.png"));
    auto fc = FaceCapture::Create(std::move(img));
    const FaceDetector::Config cfg;
    FaceDetector fd(cfg);
    auto face = fc->DetectWith(fd)[0];
    auto cropCfg = FaceCropConfiguration();
    auto croppedFace = face->Crop(cropCfg);
    auto maskImage = croppedFace->FaceAreaMask();
    auto faceSegmentColor = croppedFace->FaceAreaSegment(Colors::InnoBlue.color);
    auto faceSegmentTransparent = croppedFace->FaceAreaSegment();
    maskImage->SaveAs("output/face_seg_mask.png");
    faceSegmentColor->SaveAs("output/face_seg_color.png");
    faceSegmentTransparent->SaveAs("output/face_seg_transparent.png");
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector detector = new FaceDetector();
    Face face = capture.DetectWith(detector).get(0);
    FaceCropConfiguration cropCfg = new FaceCropConfiguration();
    cropCfg.SetCropMethod(FaceCrop.FULL);
    CroppedFace croppedFace = face.Crop(cropCfg);
    Image maskImage = croppedFace.FaceAreaMask();
    Image faceSegmentColor = croppedFace.FaceAreaSegment(Colors.InnoBlue.getColor());
    Image faceSegmentTransparent = croppedFace.FaceAreaSegment();
    maskImage.SaveAs("output/face_seg_mask.png");
    faceSegmentColor.SaveAs("output/face_seg_color.png");
    faceSegmentTransparent.SaveAs("output/face_seg_transparent.png");
  • csharp
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector detector = new FaceDetector();
    Face face = capture.DetectWith(detector)[0];
    FaceCropConfiguration cropCfg = new FaceCropConfiguration();
    cropCfg.SetCropMethod(FaceCrop.FULL);
    CroppedFace croppedFace = face.Crop(cropCfg);
    Image maskImage = croppedFace.FaceAreaMask();
    Image faceSegmentColor = croppedFace.FaceAreaSegment(Colors.InnoBlue.color);
    Image faceSegmentTransparent = croppedFace.FaceAreaSegment();
    maskImage.SaveAs("output/face_seg_mask.png");
    faceSegmentColor.SaveAs("output/face_seg_color.png");
    faceSegmentTransparent.SaveAs("output/face_seg_transparent.png");

The output of example

Face with colored background
Masked Face
Face with transparent background

Face Attributes

ICAO and face image quality

The International Civil Aviation Organization (ICAO) defines global requirements for facial images used in machine-readable travel documents (MRTDs) in ICAO Doc 9303. These requirements describe how a compliant face image must be captured and presented: frontal pose, neutral expression, proper illumination, uniform background, correct head size and positioning. Compliant images ensure easy use for ID document personalization and good performance in both human verification and computer automated facial recognition.

These ICAO requirements are technically implemented and formalized in:

  • ISO/IEC 39794-5 — Face image data format and capture requirements
  • ISO/IEC 19794-5 — Legacy face image specifications
  • ISO/IEC 29794-5 — Face image quality assessment

ISO/IEC 19794-5 defines four face image types: Basic (record format only), Frontal (with Full Frontal and Token Frontal subtypes), and specifies scene requirements (pose, expression, lighting, background, etc.), photographic requirements (exposure, focus, face position, head size), digital requirements (color profile, resolution, geometry), and format requirements (encoding, compression).

ISO/IEC 29794-5 defines a canonical face image as a face image conformant to an external standard or specification of a reference face image in most civil identity and travel document applications this corresponds to the ISO/IEC 39794-5 portrait specification, which reflects ICAO Doc 9303. [8]

Implementations and rationale

Enrollment provides two implementations for assessing face image quality against ICAO/ISO requirements:

  • Innovatrics — proprietary implementation that checks mandatory and best-practice requirements of ICAO Doc 9303 and ISO/IEC 19794-5 for the full frontal face image type, with a rich set of individual attributes.
  • OFIQ (Open Face Image Quality) — Implementation recognized by ISO/IEC 29794-5 as the reference for computing face image quality it outputs a unified quality score and standardized quality components.

When compliance with the standard or interchange with other systems is required, prefer OFIQ, as it is officially recognized by ISO/IEC 29794-5. The Innovatrics implementation is well-suited when fine-grained control over individual attributes or integration with other SDK features is needed.

Innovatrics implementation

The SDK (Innovatrics propietary implementation) is able to check all mandatory requirements and best practice recommendations of the ICAO Document 9303 specification and the ISO/IEC 19794-5 standard for the interoperable full frontal face image type, and of other relevant international standards (e.g. ANSI/INCITS 385-2004).

Once face is detected and Face object is provided, it is possible to get Face attributes.

  • Sharpness - Sharpness attribute used to measure the sharpness level of an area of the detected face in the original face capture. See Face::Sharpness for more details.
  • Brightness - Brightness attribute used to measure the brightness level of an area of the detected face in the original face capture. See Face::Brightness for more details.
  • Contrast - Contrast attribute used to measure the contrast level of an area of the detected face in the original face capture. See Face::Contrast for more details.
  • Unique Intensity Levels - Unique Intensity Levels attribute used to measure whether an area of the detected face in the original face capture has an appropriate number of unique intensity levels. See Face::UniqueIntensityLevels for more details.
  • Shadow - Shadow attribute used to evaluate whether an area of the detected face in the original face capture is affected by shadows. See Face::Shadow for more details.
  • Nose Shadow - Nose Shadow attribute for evaluating whether eyes or a nose don't cast sharp shadows. See Face::NoseShadow for more details.
  • Specularity - Specularity attribute used to evaluate the presence of spotlights in an area of the detected face in the original face capture. See Face::Specularity for more details.
  • Right Red Eye - Attribute for evaluating whether red-eye effect is not present on right eye. See Face::RightRedEye for more details.
  • Left Red Eye - Attribute for evaluating whether red-eye effect is not present on left eye. See Face::LeftRedEye for more details.
  • Eye Distance - Attribute used to measure the distance between the eyes in pixels for the detected face in the original face capture. See Face::EyeDistance for more details.
  • Roll Angle - Attribute representing the head rotation angle around the Z-axis of the detected face in the original face capture, relative to the camera reference frame, as per DIN 9300. See Face::RollAngle for more details.
  • Pitch Angle - Attribute representing the head rotation angle around the X-axis of the detected face in the original face capture, relative to the camera reference frame, as per DIN 9300. See Face::PitchAngle for more details.
  • Yaw Angle - Attribute representing the head rotation angle around the Y-axis of the detected face in the original face capture, relative to the camera reference frame, as per DIN 9300. See Face::YawAngle for more details.
  • Face Size - Attribute representing face size - the maximum of eye distance and eye-mouth distance. See Face::FaceSize for more details.
  • Face Relative Area - Attribute representing the area of the detected face in the original face capture relative to the size of the original face capture. See Face::FaceRelativeArea for more details.
  • Face Relative Area In Image - Attribute representing the visible area of the detected face in the original face capture relative to the total face area. See Face::FaceRelativeAreaInImage for more details.
  • Width To Height Ratio Of Image - Attribute representing width to height aspect ratio of the original face capture. See Face::WidthHeightRatio for more details.
  • Tinted Glasses - Attribute for evaluating tinted glasses presence. See Face::TintedGlasses for more details.
  • Gender - Attribute for evaluating gender of subject. See Face::Gender for more details.
  • Eye Gaze - Eye Gaze attribute used to evaluate whether the gaze direction of the detected face in the original face capture is frontal. See Face::EyeGaze for more details.
  • Right Eye Status - Attribute for evaluating right eye status. See Face::RightEyeStatus for more details.
  • Left Eye Status - Attribute for evaluating left eye status. See Face::LeftEyeStatus for more details.
  • Glass Status - Attribute for evaluating glasses presence. See Face::GlassStatus for more details.
  • Heavy Frame - Attribute for evaluating whether glasses with heavy frames are not present. See Face::HeavyFrame for more details.
  • Mouth Status - Attribute for evaluating mouth status. See Face::MouthStatus for more details.
  • Background Uniformity - Attribute used to measure background uniformity in the close area around the detected face in the original face capture. See Face::BackgroundUniformity for more details.
  • Age - Attribute for evaluating age of subject using the face. See Face::Age for more details.
  • c++
    std::cout << " Sharpness: " << face->Sharpness() << std::endl;
    std::cout << " Brightness: " << face->Brightness() << std::endl;
    std::cout << " Contrast: " << face->Contrast() << std::endl;
    std::cout << " Unique Intensity Levels: " << face->UniqueIntensityLevels()
    << std::endl;
    std::cout << " Shadow: " << face->Shadow() << std::endl;
    std::cout << " Nose Shadow: " << face->NoseShadow() << std::endl;
    std::cout << " Specularity: " << face->Specularity() << std::endl;
    std::cout << " Right Red Eye: " << face->RightRedEye() << std::endl;
    std::cout << " Left Red Eye: " << face->LeftRedEye() << std::endl;
    std::cout << " Eye Distance: " << face->EyeDistance() << std::endl;
    std::cout << " Roll Angle: " << face->RollAngle() << std::endl;
    std::cout << " Pitch Angle: " << face->PitchAngle() << std::endl;
    std::cout << " Yaw Angle: " << face->YawAngle() << std::endl;
    std::cout << " Face Size: " << face->FaceSize() << std::endl;
    std::cout << " Face Relative Area: " << face->FaceRelativeArea() << std::endl;
    std::cout << " Face Relative Area In Image: " << face->FaceRelativeAreaInImage()
    << std::endl;
    std::cout << " Eye Gaze: " << face->EyeGaze() << std::endl;
    std::cout << " Right Eye Status: " << face->RightEyeStatus() << std::endl;
    std::cout << " Left Eye Status: " << face->LeftEyeStatus() << std::endl;
    std::cout << " Glass Status: " << face->GlassStatus() << std::endl;
    std::cout << " Heavy Frame: " << face->HeavyFrame() << std::endl;
    std::cout << " Mouth Status: " << face->MouthStatus() << std::endl;
    std::cout << " Background Uniformity: " << face->BackgroundUniformity(5)
    << std::endl;
    std::cout << " Age: " << face->Age() << std::endl;
    std::cout << " Gender: " << face->Gender() << std::endl;
    std::cout << " Tinted Glasses: " << face->TintedGlasses() << std::endl;
  • java
    Face face = faces.get(0);
    System.out.println(" Sharpness: " + face.Sharpness());
    System.out.println(" Brightness: " + face.Brightness());
    System.out.println(" Contrast: " + face.Contrast());
    System.out.println(" Unique Intensity Levels: " + face.UniqueIntensityLevels());
    System.out.println(" Shadow: " + face.Shadow());
    System.out.println(" Nose Shadow: " + face.NoseShadow());
    System.out.println(" Specularity: " + face.Specularity());
    System.out.println(" Right Red Eye: " + face.RightRedEye());
    System.out.println(" Left Red Eye: " + face.LeftRedEye());
    System.out.println(" Eye Distance: " + face.EyeDistance());
    System.out.println(" Roll Angle: " + face.RollAngle());
    System.out.println(" Pitch Angle: " + face.PitchAngle());
    System.out.println(" Yaw Angle: " + face.YawAngle());
    System.out.println(" Face Size: " + face.FaceSize());
    System.out.println(" Face Relative Area: " + face.FaceRelativeArea());
    System.out.println(
    " Face Relative Area In Image: " + face.FaceRelativeAreaInImage());
    System.out.println(" Eye Gaze: " + face.EyeGaze());
    System.out.println(" Right Eye Status: " + face.RightEyeStatus());
    System.out.println(" Left Eye Status: " + face.LeftEyeStatus());
    System.out.println(" Glass Status: " + face.GlassStatus());
    System.out.println(" Heavy Frame: " + face.HeavyFrame());
    System.out.println(" Mouth Status: " + face.MouthStatus());
    System.out.println(
    " Background Uniformity: " + face.BackgroundUniformity((byte) 5));
    System.out.println(" Age: " + face.Age());
    System.out.println(" Gender: " + face.Gender());
    System.out.println(" Tinted Glasses: " + face.TintedGlasses());
  • csharp
    Face face = faces[0];
    System.Console.WriteLine(" Sharpness: " + face.Sharpness());
    System.Console.WriteLine(" Brightness: " + face.Brightness());
    System.Console.WriteLine(" Contrast: " + face.Contrast());
    System.Console.WriteLine(" Unique Intensity Levels: " +
    System.Console.WriteLine(" Shadow: " + face.Shadow());
    System.Console.WriteLine(" Nose Shadow: " + face.NoseShadow());
    System.Console.WriteLine(" Specularity: " + face.Specularity());
    System.Console.WriteLine(" Right Red Eye: " + face.RightRedEye());
    System.Console.WriteLine(" Left Red Eye: " + face.LeftRedEye());
    System.Console.WriteLine(" Eye Distance: " + face.EyeDistance());
    System.Console.WriteLine(" Roll Angle: " + face.RollAngle());
    System.Console.WriteLine(" Pitch Angle: " + face.PitchAngle());
    System.Console.WriteLine(" Yaw Angle: " + face.YawAngle());
    System.Console.WriteLine(" Face Size: " + face.FaceSize());
    System.Console.WriteLine(" Face Relative Area: " + face.FaceRelativeArea());
    System.Console.WriteLine(" Face Relative Area In Image: " +
    System.Console.WriteLine(" Eye Gaze: " + face.EyeGaze());
    System.Console.WriteLine(" Right Eye Status: " + face.RightEyeStatus());
    System.Console.WriteLine(" Left Eye Status: " + face.LeftEyeStatus());
    System.Console.WriteLine(" Glass Status: " + face.GlassStatus());
    System.Console.WriteLine(" Heavy Frame: " + face.HeavyFrame());
    System.Console.WriteLine(" Mouth Status: " + face.MouthStatus());
    System.Console.WriteLine(" Background Uniformity: " +
    System.Console.WriteLine(" Age: " + face.Age());
    System.Console.WriteLine(" Gender: " + face.Gender());
    System.Console.WriteLine(" Tinted Glasses: " + face.TintedGlasses());

OFIQ implementation

ISO/IEC 29794-5 recognizes OFIQ (Open Face Image Quality) as the reference implementation for computing face image quality. [8]

OFIQ computes [8] :

  • A Unified Quality Score (QS) in the range 0–100
  • Individual quality components, including:
    • Head pose (yaw, pitch, roll)
    • Head size and image margins
    • Inter-eye distance
    • Eye visibility and occlusion
    • Mouth closed / expression neutrality
    • Sharpness and focus
    • Illumination uniformity
    • Background uniformity
    • Exposure control
    • Natural colour
    • Compression artefacts

The unified quality score predicts the expected recognition performance of a face image under the assumption that it will be compared against a canonical ISO/ICAO-compliant portrait image. When face images are being collected from many biometric capture subjects, the unified quality score and quality components can be aggregated to summarize the effectiveness of the collection (e.g. mean or proportion with low or high value), to reveal site-specific problems or population effects, or as a response variable in A-B tests or trend analysis. [8] Higher scores indicate stronger conformance to ISO/ICAO portrait requirements and higher expected face recognition performance.

  • c++
    auto image = Image::Decode(BinaryFile::ReadAll("assets/face.png"));
    auto faceCapture = FaceCapture::Create(std::move(image), {});
    auto ofiq = OFIQFace::Create(faceCapture);
    auto bbImage = faceCapture->Draw(ofiq->GetBoundingBox(), Shapes::InnoBlue);
    bbImage->SaveAs("output/ofiq_bounding_box.png");
    std::cout << " Sharpness: " << static_cast<int>(ofiq->GetSharpness())
    << std::endl;
    std::cout << " UnifiedQualityScore: "
    << static_cast<int>(ofiq->GetUnifiedQualityScore()) << std::endl;
    std::cout << " BackgroundUniformity: "
    << static_cast<int>(ofiq->GetBackgroundUniformity()) << std::endl;
    // Similarly for other OFIQFace attributes
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture faceCapture = new FaceCapture(img, new FaceAttributes());
    OFIQFace ofiq = OFIQFace.Create(faceCapture);
    Image bbImage = faceCapture.Draw(ofiq.GetBoundingBox(), Shapes.InnoBlue);
    bbImage.SaveAs("output/ofiq_bounding_box.png");
    System.out.println(" Sharpness: " + ofiq.GetSharpness());
    System.out.println(" UnifiedQualityScore: " + ofiq.GetUnifiedQualityScore());
    System.out.println(" BackgroundUniformity: " + ofiq.GetBackgroundUniformity());
    // Similarly for other OFIQFace attributes
  • csharp
    Image image = Image.Decode(BinaryFile.ReadAll("assets/face.png"));
    FaceCapture faceCapture = new FaceCapture(image, new FaceAttributes());
    OFIQFace ofiq = OFIQFace.Create(faceCapture);
    Image bbImage = faceCapture.Draw(ofiq.GetBoundingBox(), Shapes.InnoBlue);
    bbImage.SaveAs("output/ofiq_bounding_box.png");
    System.Console.WriteLine(" Sharpness: {0}", ofiq.GetSharpness());
    System.Console.WriteLine(" UnifiedQualityScore: {0}",
    System.Console.WriteLine(" BackgroundUniformity: {0}",
    // Similarly for other OFIQFace attributes

The detected face by OFIQFace from example

OFIQ face

Keypoints

The Face allows also retrieval of facial keypoints.

  • c++
    auto keypoints = face->GetKeypoints();
    DotsShape dots;
    dots.Add(keypoints->RightEyeOuterCorner());
    dots.Add(keypoints->RightEyeCentre());
    dots.Add(keypoints->RightEyeInnerCorner());
    dots.Add(keypoints->LeftEyeInnerCorner());
    dots.Add(keypoints->LeftEyeCentre());
    dots.Add(keypoints->LeftEyeOuterCorner());
    dots.Add(keypoints->NoseRoot());
    dots.Add(keypoints->NoseRightBottom());
    dots.Add(keypoints->NoseTip());
    dots.Add(keypoints->NoseLeftBottom());
    dots.Add(keypoints->NoseBottom());
    dots.Add(keypoints->MouthRightCorner());
    dots.Add(keypoints->MouthCenter());
    dots.Add(keypoints->MouthLeftCorner());
    dots.Add(keypoints->MouthUpperEdge());
    dots.Add(keypoints->MouthLowerEdge());
    dots.Add(keypoints->RightEyebrowOuterEnd());
    dots.Add(keypoints->RightEyebrowInnerEnd());
    dots.Add(keypoints->LeftEyebrowInnerEnd());
    dots.Add(keypoints->LeftEyebrowOuterEnd());
    dots.Add(keypoints->RightEdge());
    dots.Add(keypoints->ChinTip());
    dots.Add(keypoints->LeftEdge());
    auto keypointImg = keypoints->GetImage()->DrawShape(dots);
    keypointImg->SaveAs("output/keypoints.png");
  • java
    Face face = faces.get(0);
    Face.Keypoints keypoints = face.GetKeypoints();
    DotsShape dots = new DotsShape();
    dots.Add(keypoints.RightEyeOuterCorner());
    dots.Add(keypoints.RightEyeCentre());
    dots.Add(keypoints.RightEyeInnerCorner());
    dots.Add(keypoints.LeftEyeInnerCorner());
    dots.Add(keypoints.LeftEyeCentre());
    dots.Add(keypoints.LeftEyeOuterCorner());
    dots.Add(keypoints.NoseRoot());
    dots.Add(keypoints.NoseRightBottom());
    dots.Add(keypoints.NoseTip());
    dots.Add(keypoints.NoseLeftBottom());
    dots.Add(keypoints.NoseBottom());
    dots.Add(keypoints.MouthRightCorner());
    dots.Add(keypoints.MouthCenter());
    dots.Add(keypoints.MouthLeftCorner());
    dots.Add(keypoints.MouthUpperEdge());
    dots.Add(keypoints.MouthLowerEdge());
    dots.Add(keypoints.RightEyebrowOuterEnd());
    dots.Add(keypoints.RightEyebrowInnerEnd());
    dots.Add(keypoints.LeftEyebrowInnerEnd());
    dots.Add(keypoints.LeftEyebrowOuterEnd());
    dots.Add(keypoints.RightEdge());
    dots.Add(keypoints.ChinTip());
    dots.Add(keypoints.LeftEdge());
    Image keypointImg = keypoints.GetImage().DrawShape(dots);
    keypointImg.SaveAs("output/keypoints.png");
  • csharp
    var face = faces[0];
    var keypoints = face.GetKeypoints();
    var dots = new DotsShape();
    dots.Add(keypoints.RightEyeOuterCorner());
    dots.Add(keypoints.RightEyeCentre());
    dots.Add(keypoints.RightEyeInnerCorner());
    dots.Add(keypoints.LeftEyeInnerCorner());
    dots.Add(keypoints.LeftEyeCentre());
    dots.Add(keypoints.LeftEyeOuterCorner());
    dots.Add(keypoints.NoseRoot());
    dots.Add(keypoints.NoseRightBottom());
    dots.Add(keypoints.NoseTip());
    dots.Add(keypoints.NoseLeftBottom());
    dots.Add(keypoints.NoseBottom());
    dots.Add(keypoints.MouthRightCorner());
    dots.Add(keypoints.MouthCenter());
    dots.Add(keypoints.MouthLeftCorner());
    dots.Add(keypoints.MouthUpperEdge());
    dots.Add(keypoints.MouthLowerEdge());
    dots.Add(keypoints.RightEyebrowOuterEnd());
    dots.Add(keypoints.RightEyebrowInnerEnd());
    dots.Add(keypoints.LeftEyebrowInnerEnd());
    dots.Add(keypoints.LeftEyebrowOuterEnd());
    dots.Add(keypoints.RightEdge());
    dots.Add(keypoints.ChinTip());
    dots.Add(keypoints.LeftEdge());
    var keypointImg = keypoints.GetImage().DrawShape(dots);
    keypointImg.SaveAs("output/keypoints.png");
Face keypoints

Face Passive Liveness

Note
Access to the passive liveness feature requires explicit permission in the license to enable face passive liveness.

We are providing following passive liveness calculations:

  • fast - Passive liveness mode with best performance available but worse accuracy as ACCURATE mode.

The Face::PassiveLivenessMode::FAST operates with higher speed but lower accuracy, whereas the Face::PassiveLivenessMode::ACCURATE is slower but provides increased accuracy, irrespective of the chosen FaceDetector::Config.

  • c++
    auto img = Image::Decode(BinaryFile::ReadAll("assets/liveness_face.png"));
    auto capture = FaceCapture::Create(std::move(img));
    FaceDetector fd;
    auto face = capture->DetectWith(fd)[0];
    auto plf = face->PassiveLiveness(Face::PassiveLivenessMode::FAST);
    std::cout << " Fast PL: " << plf << std::endl;
    auto pla = face->PassiveLiveness(Face::PassiveLivenessMode::ACCURATE);
    std::cout << " Accurate PL: " << pla << std::endl;
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/liveness_face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector fd = new FaceDetector();
    Face face = capture.DetectWith(fd).get(0);
    System.out.println(" Fast PL: "
    + face.PassiveLiveness(Face.PassiveLivenessMode.FAST));
    System.out.println(" Accurate PL: "
    + face.PassiveLiveness(Face.PassiveLivenessMode.ACCURATE));
  • csharp
    Image img = Image.Decode(BinaryFile.ReadAll("assets/liveness_face.png"));
    FaceCapture capture = new FaceCapture(img);
    FaceDetector fd = new FaceDetector();
    Face face = capture.DetectWith(fd)[0];
    System.Console.WriteLine(" Fast PL: " +
    face.PassiveLiveness(Face.PassiveLivenessMode.FAST));
    System.Console.WriteLine(" Accurate PL: " +
    face.PassiveLiveness(Face.PassiveLivenessMode.ACCURATE));
Passive Liveness Scores, Error Rates and Accuracy
  • APCER: Attack presentation images that are classified as bona-fide presentations are false accepts. The percentual rate of such error on a given dataset and given threshold represents the Attack Presentation Classification Error Rate (APCER, formerly FAR).
  • BPCER: Bona-fide presentation images that are classified as attacks are false rejects. The percentual rate of such error on a given dataset and given threshold represents the Bona-fide Presentation Classification Error Rate (BPCER, formerly FRR).

Example:

Imagine a dataset of 10,000 bona-fide presentation photos (real faces) and 1,000 attack presentation photos, where measurements were made. Threshold of 89.5, which is at working point of 1% APCER results in 3.7% BPCER. That means there are 10 attack presentation photos marked as bona-fide (false accepts) and 370 bona-fide photos are marked as attacks (false rejects).

Fast Passive Liveness Thresholds

Use case type Threshold Performance
Convenience (minimum rejected attempts) 80.0 2.75% APCER @ 1 % BPCER
Balanced (equal error rate) 83.2 1.76% both APCER & BPCER
Security (minimum accepted frauds) 86.2 3.62% BPCER @ 1% APCER

Face Attributes Reliability

In some cases the meaningfulness of attribute value relies on values of other attributes. We provide following reliability checks

  • c++
    ICAOReliability icao;
    auto failedAttributes = icao.Validate(face);
    for (const auto& a : failedAttributes)
    {
    std::cout << " Value " << a.value << " of " << a.id << " is not in range ["
    << a.min << ", " << a.max << "]" << std::endl;
    }
  • java
    ICAOReliability icao = new ICAOReliability();
    for (FailedFaceAttribute a : icao.Validate(face)) {
    System.out.println(" Value " + a.getValue() + " of " + a.getId()
    + " is not in range [" + a.getMin() + ", " + a.getMax()
    + "]");
    }
  • csharp
    ICAOReliability icao = new ICAOReliability();
    foreach (FailedFaceAttribute a in icao.Validate(face))
    {
    System.Console.WriteLine(" Value " + a.value + " of " + a.id +
    " is not in range [" + a.min + ", " + a.max + "]");
    }

Best practices for use of Face Images

We provide following best practice checks

  • ISOFullFrontalImageValidator - Check if usage of Full Frontal Images on travel documents will follow best practices, as described in Section B.3.2 Best practices for use of Full Frontal Images on travel documents [6].
  • c++
    ISOFullFrontalImageValidator icaoFullFrontal;
    auto failedAttributes = icaoFullFrontal.Validate(face);
    for (const auto& a : failedAttributes)
    {
    std::cout << " Value " << a.value << " of " << a.id << " is not in range ["
    << a.min << ", " << a.max << "]" << std::endl;
    }
  • java
    ISOFullFrontalImageValidator icaoFullFrontal = new ISOFullFrontalImageValidator();
    for (FailedFaceAttribute a : icaoFullFrontal.Validate(face)) {
    System.out.println(" Value " + a.getValue() + " of " + a.getId()
    + " is not in range [" + a.getMin() + ", " + a.getMax()
    + "]");
    }
  • csharp
    ISOFullFrontalImageValidator icaoFullFrontal = new ISOFullFrontalImageValidator();
    foreach (FailedFaceAttribute a in icaoFullFrontal.Validate(face))
    {
    System.Console.WriteLine(" Value " + a.value + " of " + a.id +
    " is not in range [" + a.min + ", " + a.max + "]");
    }

ISO Conversion

ISO Image

It is possible to convert Face to ISO image compliant with ISO 19794-5:2011 and back from image to FaceCapture.

  • c++
    auto image = Image::Decode(BinaryFile::ReadAll("assets/faces.png"));
    FaceAttributes fa;
    fa.SetCaptureDeviceVendorID(FaceCaptureDeviceVendorID(11));
    fa.SetCaptureDeviceTypeID(FaceCaptureDeviceTypeID(7));
    auto faceCapture = FaceCapture::Create(std::move(image), fa);
    FaceDetector faceDetector;
    auto face = faceCapture->DetectWith(faceDetector)[0];
    std::cout << " Conversion Face to ISO image" << std::endl;
    auto encoder = PngImageEncoder();
    auto isoImage = face->ToIsoImage(encoder);
    std::cout << " Conversion ISO to Face image" << std::endl;
    auto faceImage = faceCapture->FromIsoImage(isoImage);
  • java
    Image img = Image.Decode(BinaryFile.ReadAll("assets/faces.png"));
    FaceAttributes fa = new FaceAttributes();
    fa.SetCaptureDeviceTechnology(
    FaceCaptureDeviceTechnology.STATIC_PHOTOGRAPH_FROM_SCANNER);
    fa.SetCaptureDeviceVendorID(new FaceCaptureDeviceVendorID(11));
    fa.SetCaptureDeviceTypeID(new FaceCaptureDeviceTypeID(7));
    FaceCapture faceCapture = new FaceCapture(img, fa);
    FaceDetector faceDetector = new FaceDetector();
    Face face = faceCapture.DetectWith(faceDetector).get(0);
    System.out.println(" Conversion Face to ISO image");
    PngImageEncoder encoder = new PngImageEncoder();
    Bytes isoImage = face.ToIsoImage(encoder);
    System.out.println(" Conversion ISO to Face image");
    FaceCapture faceImage = FaceCapture.FromIsoImage(isoImage);
  • csharp
    Image image = Image.Decode(BinaryFile.ReadAll("assets/faces.png"));
    FaceAttributes fa = new FaceAttributes();
    FaceCaptureDeviceTechnology.STATIC_PHOTOGRAPH_FROM_SCANNER);
    fa.SetCaptureDeviceVendorID(new FaceCaptureDeviceVendorID(11));
    fa.SetCaptureDeviceTypeID(new FaceCaptureDeviceTypeID(7));
    FaceCapture faceCapture = new FaceCapture(image, fa);
    FaceDetector faceDetector = new FaceDetector();
    var face = faceCapture.DetectWith(faceDetector)[0];
    System.Console.WriteLine(" Conversion Face to ISO image");
    var encoder = new PngImageEncoder();
    var isoImage = face.ToIsoImage(encoder);
    System.Console.WriteLine(" Conversion ISO to Face image");
    var faceImage = FaceCapture.FromIsoImage(isoImage);

Typedef Documentation

◆ FaceSimilarityScore

using FaceSimilarityScore = unsigned int

It is similarity score between face Templates.

Score is 0-100 where 100 represents most similar templates.

When the matching score is higher then certain score threshold then the face images belongs to the same person with high probability. The matching score range is <0, 100>. Its values can be interpreted as follows:

  • Low values of the score, i.e. range <0, 60>, are normalized using FAR values and this formula score_L=-10*log(FAR). It means that score 30 is related to FAR=1:1000=10^-3, score 50 is related to FAR=1:100000=10^-5 (evaluated on our large testing non-matching pairs dataset).
  • High values of the score, i.e. range <80, 100>, are normalized using FRR values and this formula score_H=100/3*(FRR + 2). It means that score 80 is related to FRR=0.4, score 90 is related to FRR=0.7 (evaluated on our large testing matching pairs dataset).

Scores values in range (60, 80) are weighted average of score_L and score_H. This normalization help the users to select the score threshold according their needs. If it is too low e.g. score threshold is 30, then the chance of false accepted non-matching faces is quite high (FAR=10^-3). When it is too high e.g. score threshold is 90, then the chance of false rejected matching faces is quite high (FRR=0.7). For face recognition following recommendations are given:

  • minimum face size - inter eye-pupils distance at least 40 pix
  • optimal face size - inter eye-pupils distance at least 100 pix
  • optimal image - sharp, contrast, frontal facial image with standard lighting conditions
  • the more similar are conditions when the matched faces are captured the higher is the matching accuracy
  • complex robust feature extraction invariant to partial faces occlusions / poor lighting / blurriness / etc is done. So, no further preprocessing is necessary.

See Similarity Score.

Enumeration Type Documentation

◆ FaceCaptureDeviceTechnology

enum class FaceCaptureDeviceTechnology : uint8_t
strong

It indicates the class of device technology used to acquire the captured biometric sample [6].

Enumerator
UNKNOWN 

Unknown or Unspecified.

STATIC_PHOTOGRAPH_FROM_UNKNOWN_SOURCE 

Static photograph from an unknown source.

STATIC_PHOTOGRAPH_FROM_DIGITAL_CAMERA 

Static photograph from a digital still-image camera.

STATIC_PHOTOGRAPH_FROM_SCANNER 

Static photograph from a scanner.

VIDEO_FRAME_FROM_UNKNOWN_SOURCE 

Video frame(s) from an unknown source.

VIDEO_FRAME_FROM_ANALOGUE_CAMERA 

Video frame(s) from an analogue video camera.

VIDEO_FRAME_FROM_DIGITAL_CAMERA 

Video frame(s) from a digital video camera.

◆ FaceCrop

enum class FaceCrop : uint8_t
strong

Defines different Crop methods.

Enumerator
TOKEN_NOT_FRONTAL 

Image cropping method similar to TOKEN but works quite well even on non-frontal images It will produce FaceImageType::BASIC.

FULL 

Full Frontal Image cropping method defined in ISO/IEC 19794-5 standard.

Cropping requirements specified to allow for full capture of face and shoulders. Consistent with most current mug-shot and passport standards. Recommended for use with ePassports, both on the printed passport and stored in the chip. [10] It will produce FaceImageType::FULL_FRONTAL image.

TOKEN 

Token Frontal Image cropping method defined in ISO/IEC 19794-5 standard.

Eye positions in fixed positions on image. The image aspect ratio is fixed. Storage size is reduced. A 90 or 120 pixels from eye to eye Token can be used in the MRTD chip. [10] It will produce FaceImageType::TOKEN_FRONTAL image.

FULL_NOT_ALIGNED 

Crops bounding box provided by FaceCrop::FULL method as is from original FaceCapture.

It will produce FaceImageType::BASIC. It is used to get face from original FaceCapture as is.

◆ FaceImageType

enum class FaceImageType : uint8_t
strong

Several face image types are introduced to define categories that satisfy requirements of some applications [6].

Enumerator
BASIC 

This is the fundamental Face Image Type that specifies a record format including header and representation data.

All Face Image Types adhere to the properties of this type. No mandatory scene, photographic and digital requirements are specified for this image type. [6]

FULL_FRONTAL 

A Face Image Type that specifies frontal images with sufficient resolution for human examination as well as reliable computer face recognition.

This type of Face Image Type includes the full head with all hair in most cases, as well as neck and shoulders. This image type is suitable for permanent storage of the face information, and it is applicable to portraits for passport, driver license, and "mugshot" images. [6]

TOKEN_FRONTAL 

A Face Image Type that specifies frontal images with a specific geometric size and eye positioning based on the width and height of the image.

This image type is suitable for minimizing the storage requirements for computer face recognition tasks such as verification while still offering vendor independence and human verification (versus human examination which requires more detail) capabilities. [6]

POST_PROCESSED_FRONTAL 

Applying digital post-processing to a captured image can modify this image in a way that it is more suitable for automatic face recognition.

The Post-processed Frontal Face Image Type is thought of as the interchange format for these kinds of facial images. [6]

Function Documentation

◆ FaceToIsoCaptureDeviceTechnology()

constexpr int FaceToIsoCaptureDeviceTechnology ( FaceCaptureDeviceTechnology printCaptureDeviceTechnology)
staticconstexpr

Function converts FaceCaptureDeviceTechnology to ISO capture technology.

Parameters
printCaptureDeviceTechnologyFaceCaptureDeviceTechnology
Exceptions
EnrollmentInvalidArgumentExceptionfor invalid conversion
Returns
ISO capture technology

References STATIC_PHOTOGRAPH_FROM_DIGITAL_CAMERA, STATIC_PHOTOGRAPH_FROM_SCANNER, STATIC_PHOTOGRAPH_FROM_UNKNOWN_SOURCE, UNKNOWN, VIDEO_FRAME_FROM_ANALOGUE_CAMERA, VIDEO_FRAME_FROM_DIGITAL_CAMERA, and VIDEO_FRAME_FROM_UNKNOWN_SOURCE.

◆ FaceToIsoImageType()

constexpr int FaceToIsoImageType ( FaceImageType faceImageType)
staticconstexpr

Function converts FaceImageType to ISO face image type as defined in iso_19794-5_2011.

Parameters
faceImageTypeFaceImageType
Exceptions
EnrollmentInvalidArgumentExceptionfor invalid conversion
Returns
ISO face image type

References BASIC, FULL_FRONTAL, POST_PROCESSED_FRONTAL, and TOKEN_FRONTAL.

◆ IsFaceCropMethodValid()

constexpr bool IsFaceCropMethodValid ( FaceCrop faceCrop)
staticconstexpr

Function validates the value of FaceCrop enum.

Parameters
faceCropface crop method
Returns
Whether the face crop method is valid

References FULL, FULL_NOT_ALIGNED, TOKEN, and TOKEN_NOT_FRONTAL.

Referenced by FaceCropConfiguration::SetCropMethod().

Here is the caller graph for this function:

◆ IsoToFaceCaptureDeviceTechnology()

constexpr FaceCaptureDeviceTechnology IsoToFaceCaptureDeviceTechnology ( int isoCaptureDeviceTechnology)
staticconstexpr

Function converts ISO capture technology to FaceCaptureDeviceTechnology.

Parameters
isoCaptureDeviceTechnologyiso capture technology
Exceptions
EnrollmentInvalidArgumentExceptionfor invalid conversion
Returns
FaceCaptureDeviceTechnology

References STATIC_PHOTOGRAPH_FROM_DIGITAL_CAMERA, STATIC_PHOTOGRAPH_FROM_SCANNER, STATIC_PHOTOGRAPH_FROM_UNKNOWN_SOURCE, UNKNOWN, VIDEO_FRAME_FROM_ANALOGUE_CAMERA, VIDEO_FRAME_FROM_DIGITAL_CAMERA, and VIDEO_FRAME_FROM_UNKNOWN_SOURCE.

Referenced by FaceCapture::FromIsoImage().

Here is the caller graph for this function:

◆ IsoToFaceImageType()

constexpr FaceImageType IsoToFaceImageType ( int faceImageType)
staticconstexpr

Function converts ISO face image type to FaceImageType.

Parameters
faceImageTypeiso face image type
Exceptions
EnrollmentInvalidArgumentExceptionfor invalid conversion
Returns
FaceImageType

References BASIC, FULL_FRONTAL, POST_PROCESSED_FRONTAL, and TOKEN_FRONTAL.