Using Python API¶
IDLive Face needs Python 3.8–3.10. We support 64-bit only.
Set up¶
The package for the IDLive Face Python API is idliveface
:
import idliveface
You can find it 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 idliveface
Initialize¶
The entry point to the IDLive Face is called the Blueprint
. It's a factory for all main SDK objects, and it's also used to configure the IDLive Face. Initialize it with the path to the SDK's data
directory (we assume the SDK was installed to /opt/idliveface
):
from pathlib import Path
IDLIVEFACE_HOME = Path("/opt/idliveface")
blueprint = idliveface.Blueprint(IDLIVEFACE_HOME / "data")
You can use strings instead of pathlib.Path
objects if you prefer.
Next use the blueprint to create the image decoder and the face analyzer:
decoder = blueprint.create_image_decoder()
analyzer = blueprint.create_face_analyzer()
You don't need the blueprint afterwards. IDLive Face reports all error via exceptions, you need to catch them in your exception handler:
try:
...
except idliveface.IDLiveFaceException as e:
print(f"Error: {e}")
Load image¶
To load a compressed image from a file, use the image decoder:
image = decoder.decode_file(IDLIVEFACE_HOME / "examples/images/real_face.jpg")
IDLive Face supports JPEG, PNG and BMP formats. You can also load the image from the bytes
or bytearray
buffers:
image_content = (IDLIVEFACE_HOME / "examples/images/real_face.jpg").read_bytes()
image = decoder.decode(image_content)
If the image can't be decoded, the decoder will throw idliveface.ImageDecodingException
.
Alternatively you can use OpenCV images:
import cv2
image = cv2.imread(str(IDLIVEFACE_HOME / "examples/images/real_face.jpg"))
Such images are expected to be in BGR format. If you have an RGB image, you need wrap it into the Image
object with the specified PixelFormat
:
image = idliveface.Image(opencv_rgb_image, idliveface.PixelFormat.RGB)
Grayscale images are also supported.
Analyze image¶
To analyze the image, use the face analyzer:
result = analyzer.analyze(image);
Once the analysis is complete, you need to first check the status
field. If it's set to INVALID
, the image has failed to pass validations and was not analyzed. Such images do not conform to the requirements, and it's either not possible to analyze them, or produce the result with the decent accuracy. All validations the image has failed to pass are listed in the failed_validations
field.
if result.status == idliveface.FaceStatus.INVALID:
print("Image did not pass validations and is not suitable for analysis")
print(f"Failed validations: {result.failed_validations}")
For the images that pass the validations, the status
will be either GENUINE
or NOT_GENUINE
. The result's genuine_probability
field will also be set. It's a float value showing how confident we are if the face on the image belongs to a real person, with 1 being the most confident. If the value is closer to 0, the face does not look genuine and may be spoofed. The decision threshold is 0.5. When the probability is this high or higher, the status
will be set to GENUINE
. For lower probabilities it will be set to NOT_GENUINE
.
So your decision logic may look like this:
if result.status == idliveface.FaceStatus.INVALID:
# Ask to retake the image, use result.failed_validations as hints
elif result.status == idliveface.FaceStatus.NOT_GENUINE:
# Reject the image
else:
# Accept the image
Additionally the result
contains a bounding box around the processed face. It will be returned when the face was detected, no matter if the image was analyzed or not. For example, if the face on the image is too small, the status
will be INVALID
, but the box
field will still be set. You can use it to diagnose why the image was not analyzed, along with failed_validations
.
if result.box:
print(f"Detected face: {result.box}")
Example program¶
Here is a program that uses everything described in this article:
example.py
from pathlib import Path
import idliveface
IDLIVEFACE_HOME = Path(r"/opt/idliveface")
def process_result(result):
print(f"Result: {result}")
if result.status != idliveface.FaceStatus.INVALID:
print(f"Image is {result.status}, probability is {result.genuine_probability}")
else:
print("Image did not pass validations and is not suitable for analysis")
print(f"Failed validations: {result.failed_validations}")
def main():
blueprint = idliveface.Blueprint(IDLIVEFACE_HOME / "data")
print("Initializing...")
decoder = blueprint.create_image_decoder()
analyzer = blueprint.create_face_analyzer()
print("\nAnalyzing real_face.jpg")
image = decoder.decode_file(IDLIVEFACE_HOME / "examples/images/real_face.jpg")
result = analyzer.analyze(image)
process_result(result)
print("\nAnalyzing spoof_face.jpg")
image = decoder.decode_file(IDLIVEFACE_HOME / "examples/images/spoof_face.jpg")
result = analyzer.analyze(image)
process_result(result)
print("\nAnalyzing face_is_occluded.jpg")
image = decoder.decode_file(IDLIVEFACE_HOME / "examples/images/face_is_occluded.jpg")
result = analyzer.analyze(image)
process_result(result)
if __name__ == "__main__":
main()