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
Prebuilt wheels are available for:
- Linux x86_64 (manylinux_2_28)
- macOS arm64 (Apple Silicon, macOS 14+)
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
OFIQinstance per thread, or - Serialize access with a lock, or
- Use
multiprocessinginstead ofthreading
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
Linux (via Docker, produces manylinux wheel):
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')"
macOS (Apple Silicon):
brew install cmake git
git clone https://github.com/unicef/python-ofiq.git
cd python-ofiq
bash scripts/build_ofiq.sh
export OFIQ_ROOT="$HOME/OFIQ-Project/install_arm64_mac/Release"
pip install -e .
Or build a wheel directly with cibuildwheel:
pip install cibuildwheel
cibuildwheel --platform macos --output-dir wheelhouse
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
Metadata
Release files for python-ofiq 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 134.1 MB
Release files / python_ofiq-0.3.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | python_ofiq-0.3.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.9 MB |
| Tags | CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
d602ccf8986fdc012bfadff26be370c0cfbe223f5dc940424300f353e01a8b9b
|
|
BLAKE2b-256 checksum How to use checksums |
24ed1b367c6155cf7686e0811a86e7aa9f114a7dfa45076ccd55987897fd7f6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp314-cp314-macosx_14_0_arm64.whl
| Download URL | python_ofiq-0.3.1-cp314-cp314-macosx_14_0_arm64.whl |
|---|---|
| Size | 19.6 MB |
| Tags | CPython 3.14 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
ebe8c4af05aaee06851b47a53b3fe252aad5477506104933d5a787cbb4f21305
|
|
BLAKE2b-256 checksum How to use checksums |
8df496a6af860c3de2f6a56357269af59a9f9d9a72b747f1538cfae181651025
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | python_ofiq-0.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.9 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
a7890eda62991701ad8d28f2661cf73fa245478aed2eec5dc45c43522e31c0d6
|
|
BLAKE2b-256 checksum How to use checksums |
05fe3637671fada218c92a3b072176f2eaf77eeb0b2ee80243e35ac30bc43596
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp313-cp313-macosx_14_0_arm64.whl
| Download URL | python_ofiq-0.3.1-cp313-cp313-macosx_14_0_arm64.whl |
|---|---|
| Size | 19.6 MB |
| Tags | CPython 3.13 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b814fe722d67244aa4327134ba23447dec38f72fb8553389236ee5598b05bbbd
|
|
BLAKE2b-256 checksum How to use checksums |
3c9902172c10075af4a5cb2377e5e92a93c7aae6aaa68f3c57d4272fd50e8e09
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | python_ofiq-0.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.9 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
73b4c2f95c4d90b34e9362d1b195ce8b4262b25ff5e70afe90eab82de78d356a
|
|
BLAKE2b-256 checksum How to use checksums |
7960d5fe4bd336c273a34b173a4da767c41aa4cd3be262c1566afff0c63ca984
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp312-cp312-macosx_14_0_arm64.whl
| Download URL | python_ofiq-0.3.1-cp312-cp312-macosx_14_0_arm64.whl |
|---|---|
| Size | 19.6 MB |
| Tags | CPython 3.12 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
54bf79f558b5fedb1e9daaea68593eb8e3ee32cf9bbd0862dce4b7040e6b5183
|
|
BLAKE2b-256 checksum How to use checksums |
072ea5fe991ab455a0271bd5b0e3fc75d07b86162029e6735231bf7567bcfa1a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | python_ofiq-0.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.9 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
5580f7f6084839a50d93aa929246da742f296b841464feed0480b35b5822d0f9
|
|
BLAKE2b-256 checksum How to use checksums |
2c427ec67070b2dfb42d8dd558a43a242c44293993db0a3edd81286b429cfecc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / python_ofiq-0.3.1-cp311-cp311-macosx_14_0_arm64.whl
| Download URL | python_ofiq-0.3.1-cp311-cp311-macosx_14_0_arm64.whl |
|---|---|
| Size | 19.6 MB |
| Tags | CPython 3.11 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e8b30cc0955d664203885356b014df4c1ca1a28df765e65cec0abeb674314831
|
|
BLAKE2b-256 checksum How to use checksums |
d67a0617ef8a5fd8d1c8d5c0a4887b9eabbc0263f56d15984f7c8e561f2de54d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency log