Skip to content

Using Python API

IDLive Face Python API is available in the package PythonFaceSDK:

import PythonFaceSDK as sdk

We support Python 3.8–3.10, 64-bit only.

Python support in previous releases

Previous versions of IDLive Face supported different Python versions:

  • Python 3.6–3.7: Available until version 1.34.
  • Python 3.9: Added in version 1.32.
  • Python 3.10: Added in version 1.35.

Package location

The PythonFaceSDK package is located in the SDK's libs/python directory. You need to put this directory into the PYTHONPATH environment variable before starting the Python interpreter:

export PYTHONPATH="$PYTHONPATH:/opt/idliveface/libs/python"
$env:PYTHONPATH = "$env:PYTHONPATH;C:\idliveface\libs\python"
IF DEFINED PYTHONPATH (
    SET PYTHONPATH=%PYTHONPATH%;C:\idliveface\libs\python
) ELSE (
    SET PYTHONPATH=C:\idliveface\libs\python
)

Alternatively you can specify the package's location in the Python script itself:

import sys
sys.path.append("/opt/idliveface/libs/python")

import PythonFaceSDK as sdk

Using on Windows

If you are on Windows you need to additionally provide a path to the SDK's libs directory. The approach is different depending on the Python's version used:

  • For Python 3.6 and 3.7 you need to add this directory to the Path environment variable. Please refer to the DLL discovery article.

  • For Python 3.8 and newer you need to execute os.add_dll_directory in your script before importing PythonFaceSDK package:

    import os
    os.add_dll_directory(r"C:\idliveface\libs")
    
    import PythonFaceSDK as sdk
    

Basics

Initialize pipeline

The main entity of the IDLive Face API is a pipeline (represented by the class Pipeline). The SDK contains several pipelines, each one is described by the configuration file stored in the data/pipelines directory. To initialize a pipeline first you need to load its configuration. For example to load the configuration for the Astraea pipeline do:

IDLIVEFACE_HOME = "/opt/idliveface"
config = sdk.InitConfig.createConfig(os.path.join(IDLIVEFACE_HOME, "data/pipelines/astraea.json"))

List of all available pipelines can be found in the Pipelines article.

Next use the loaded configuration to create a pipeline:

pipeline = sdk.FaceSDK.getPipeline("ConfigurablePipeline", config)

Load image

To load an image into the memory you need to create an Image object that will contain the image's content. The image can be loaded from a file:

image = sdk.Image.createImage(os.path.join(IDLIVEFACE_HOME, "examples/images/real_face.jpg"))

Or from a memory buffer:

image_bytes: bytes = ...
image = sdk.Image.createImage(list(image_bytes))

You can also load an OpenCV image:

pixels = cv2.imread(os.path.join(IDLIVEFACE_HOME, "examples/images/real_face.jpg"))
image = sdk.Image.createImage(pixels, pixels.shape[0], pixels.shape[1], sdk.COLOR_ENCODING.BGR888)

IDLive Face supports JPEG, PNG and other image formats.

Perform liveness check

To perform a liveness check call the pipeline's checkLiveness method:

result = pipeline.checkLiveness(image)

The result contains measurements of the image's liveness and quality. The main factor to decide if the image is live or spoofed is the result.liveness_result.probability. The image can be considered live if the probability is higher than 0.5:

if (result.liveness_result.probability >= 0.5):
    # Image is live
else:
    # Image is spoofed

Additional factor to take into consideration is result.quality_result.score. It measures how "appropriate" the image is for the liveness check. Images with the quality values lower than 0.5 should generally be rejected:

if (result.quality_result.score < 0.5):
    # Image has a bad quality, reject it

Both measurements are float values in a range of [0,1]. The detailed explanation of the results of the liveness check can be found in the Liveness check result article.

Error handling

When an error occurs the IDLive Face API generates an exception, which is returned inside of the RuntimeError. Generally you should wrap all invocations of the API into a try-except block:

try:
    ...
except RuntimeError as e:
    face_exception = e.args[0]
    print(f"Error code: {face_exception.status()}, message: {face_exception.what()}")

The status of the exception is an enumeration you can use to react to specific errors. For example when the Pipeline.checkLiveness rejects an image it returns statuses that classify the rejection reason:

status = face_exception.status()

if status == sdk.STATUS.FACE_TOO_SMALL:
    # Inform a user to get closer to a camera.
elif status == ...

The list of all statuses is available in the Error statuses article.

Example program

Here is a program that uses everything described in the previous section:

example.py
import os

import PythonFaceSDK as sdk

IDLIVEFACE_HOME = r"/opt/idliveface"


def process_liveness_result(result):
    print(f"Result: {result}")

    if result.quality_result.score < 0.5:
        print("Image has a bad quality")
    elif result.liveness_result.probability >= 0.5:
        print("Image is genuine")
    else:
        print("Image is spoofed")


def main():
    try:
        print("Initializing...")
        config = sdk.InitConfig.createConfig(os.path.join(IDLIVEFACE_HOME, "data/pipelines/astraea.json"))
        pipeline = sdk.FaceSDK.getPipeline("ConfigurablePipeline", config)

        print("\nChecking liveness for real_face.jpg")
        image = sdk.Image.createImage(os.path.join(IDLIVEFACE_HOME, "examples/images/real_face.jpg"))
        liveness_result = pipeline.checkLiveness(image)
        process_liveness_result(liveness_result)

        print("\nChecking liveness for spoof_face.jpg")
        image = sdk.Image.createImage(os.path.join(IDLIVEFACE_HOME, "examples/images/spoof_face.jpg"))
        liveness_result = pipeline.checkLiveness(image)
        process_liveness_result(liveness_result)

        print("\nChecking liveness for face_not_found.jpg")
        image = sdk.Image.createImage(os.path.join(IDLIVEFACE_HOME, "examples/images/face_not_found.jpg"))
        pipeline.checkLiveness(image)

    except RuntimeError as e:
        face_exception = e.args[0]
        print(f"Error: {face_exception.status()}, message: {face_exception.what()}")


if __name__ == "__main__":
    main()

Download

It performs the liveness check for several example images and prints the following output:

Checking liveness for real_face.jpg
Result: { "liveness_result": { "score": 2.3685, "probability": 0.914393 }, "quality_result": { "score": 0.843499, "class_": true } }
Image is genuine

Checking liveness for spoof_face.jpg
Result: { "liveness_result": { "score": -6.79468, "probability": 0.00111846 }, "quality_result": { "score": 0.811047, "class_": true } }
Image is spoofed

Checking liveness for face_not_found.jpg
Error: STATUS.FACE_NOT_FOUND, message: Failed to detect face