Skip to main content

Python bindings for OFIQ (Open Source Face Image Quality)

Project description

python-ofiq

Python bindings for OFIQ (Open Source Face Image Quality) — the reference implementation for ISO/IEC 29794-5.

Features

  • One-time initialization, process many images efficiently
  • Unified quality score [0-100] and 25+ individual quality metrics
  • Custom exception hierarchy for precise error handling
  • Full type hint support

Installation

pip install python-ofiq

Download OFIQ models and config (~400 MB):

python-ofiq setup

This stores data in ~/.ofiq/data. Set OFIQ_DATA_DIR to use a custom directory.

Quick Start

import cv2
from ofiq import OFIQ, FaceDetectionError

ofiq = OFIQ()

bgr = cv2.imread("face.png")
rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)

try:
    score = ofiq.scalar_quality(rgb)
    print(f"Quality score: {score}")
except FaceDetectionError:
    print("No face detected")

measures = ofiq.vector_quality(rgb)
print(measures)
# {'UnifiedQualityScore': 85.2, 'Sharpness': 92.1, ...}

measures_with_raw = ofiq.vector_quality(rgb, include_raw=True)
print(measures_with_raw["Sharpness"])
# {'scalar': 92.1, 'raw': 0.847}

Exception Handling

from ofiq import (
    OFIQ,
    OFIQError,
    ConfigError,
    QualityError,
    FaceDetectionError,
    LandmarkError,
    SegmentationError,
)

try:
    score = ofiq.scalar_quality(image)
except FaceDetectionError:
    print("No face in image")
except LandmarkError:
    print("Could not extract facial landmarks")
except QualityError as e:
    print(f"Quality assessment failed: {e}")
except OFIQError as e:
    print(f"OFIQ error: {e}")

Thread Safety

OFIQ instances are not thread-safe. The underlying C++ library uses shared mutable state without synchronization:

  • Use one OFIQ instance per thread, or
  • Serialize access with a lock, or
  • Use multiprocessing instead of threading

Scalar vs Raw Scores

Scalar scores are normalized to [0, 100] where higher is always better. Raw scores are the native OFIQ values before normalization — their range and direction vary per measure. Use include_raw=True when you need the original measurement values.

Available Quality Measures

All measures return scalar values in [0, 100] where higher is better, or None if the measure failed:

Measure Description
UnifiedQualityScore Overall quality score
Sharpness Image sharpness/focus
BackgroundUniformity Background consistency
IlluminationUniformity Lighting evenness
LuminanceMean Average brightness
LuminanceVariance Brightness variation
DynamicRange Contrast range
CompressionArtifacts JPEG artifact detection
NaturalColour Color naturalness
HeadPoseYaw Face yaw angle
HeadPosePitch Face pitch angle
HeadPoseRoll Face roll angle
EyesOpen Eye openness
MouthClosed Mouth closure
EyesVisible Eye visibility
ExpressionNeutrality Neutral expression
SingleFacePresent Single face detection
InterEyeDistance Distance between eyes
HeadSize Face size in frame
... and more

API Reference

OFIQ(config_dir="", config_file="ofiq_config.jaxn")

Initialize OFIQ. If config_dir is omitted, uses OFIQ_DATA_DIR env var or ~/.ofiq/data.

scalar_quality(image_rgb) -> float

Compute unified quality score. image_rgb: NumPy uint8 array of shape (H, W, 3) in RGB.

vector_quality(image_rgb, include_raw=False) -> dict

Compute all quality measures. Returns None for failed individual measures.

ofiq.setup(force_download=False) -> str

Download models and config. Returns the data directory path.

ofiq.resolve_data_dir() -> str

Return the resolved data directory.

CLI

python-ofiq setup                    # download models and config
python-ofiq setup --force-download   # re-download even if present
OFIQ_DATA_DIR=/custom/path python-ofiq setup

Version Compatibility

python-ofiq OFIQ C++
0.1.x 1.1.2

Development

Build from source

git clone https://github.com/unicef/python-ofiq.git
cd python-ofiq

docker build -f docker/Dockerfile -t python-ofiq-test .
docker run -it python-ofiq-test python -c "from ofiq import OFIQ; print('OK')"

Run tests

pip install pytest numpy

pytest tests/ -v -m "not integration"

# Integration tests require models
pytest tests/ -v

License

MIT — see LICENSE.

This project wraps the OFIQ C++ library which is also MIT licensed.

Acknowledgments

  • BSI for developing OFIQ
  • pybind11 for the bindings framework

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

python_ofiq-0.2.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (13.9 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

python_ofiq-0.2.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (13.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

python_ofiq-0.2.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (13.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

python_ofiq-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (13.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl (19.6 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

File details

Details for the file python_ofiq-0.2.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for python_ofiq-0.2.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 193f0cff86cbdfaccab518be85cfb325c2467446d36b0d63d55de000cd3dce65
MD5 41c625509705d0ae5d4b7abc895538ee
BLAKE2b-256 2418d2da5f9cb0ec9c2500775ac9f753fc0860850c411618cd35ab202c7ffd17

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_ofiq-0.2.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on unicef/python-ofiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file python_ofiq-0.2.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for python_ofiq-0.2.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e0d3e835d48166ef5b998f59202a6c7e7c58db48e9e1ce4238d467d892017a28
MD5 5be787c4b73f816172586b9f9cc64e96
BLAKE2b-256 90ef6931877cd938d04174012e8990a432a7bdf79cc4a5e953dedd4fe08623a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_ofiq-0.2.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on unicef/python-ofiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file python_ofiq-0.2.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for python_ofiq-0.2.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c6f095aefccde2c85b847ba9dbb60f667e6d39a7c3fb5c04eb3929318f4967ad
MD5 b655cb492fc483ab7ae3a50e0d83d119
BLAKE2b-256 f291e3cfa1db7b7af39e8310d77ce7cc30522ce76a4ee111367e195252b221d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_ofiq-0.2.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on unicef/python-ofiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file python_ofiq-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for python_ofiq-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b0091b20e2727523b9f42ad1e982b6821224b0d8620e66782104c8e2bc15456d
MD5 09fb53b47e79b2d639c40f1eac073f18
BLAKE2b-256 b7ea16b8fa146bbe0fabf1751596e5e4bc1624b1385b83568b7cd14d48fe7a38

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_ofiq-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on unicef/python-ofiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 466784eaaeafcf30b999f5598ecfbe04a0da63377d41cf9a2ff1d28e30ed501e
MD5 fd56ed27128f2847520aae0813ca43dd
BLAKE2b-256 7838dd80c60b4f815bcf3601092b4ad9df241081e3dc23d619e9ca04f0c138c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl:

Publisher: release.yml on unicef/python-ofiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page