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
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
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
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
- Download URL: python_ofiq-0.2.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.9 MB
- Tags: CPython 3.14, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
193f0cff86cbdfaccab518be85cfb325c2467446d36b0d63d55de000cd3dce65
|
|
| MD5 |
41c625509705d0ae5d4b7abc895538ee
|
|
| BLAKE2b-256 |
2418d2da5f9cb0ec9c2500775ac9f753fc0860850c411618cd35ab202c7ffd17
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_ofiq-0.2.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
193f0cff86cbdfaccab518be85cfb325c2467446d36b0d63d55de000cd3dce65 - Sigstore transparency entry: 1359941339
- Sigstore integration time:
-
Permalink:
unicef/python-ofiq@58896f27ad33aadd387959fda565f4eaf1c35060 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/unicef
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58896f27ad33aadd387959fda565f4eaf1c35060 -
Trigger Event:
push
-
Statement type:
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
- Download URL: python_ofiq-0.2.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.9 MB
- Tags: CPython 3.13, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0d3e835d48166ef5b998f59202a6c7e7c58db48e9e1ce4238d467d892017a28
|
|
| MD5 |
5be787c4b73f816172586b9f9cc64e96
|
|
| BLAKE2b-256 |
90ef6931877cd938d04174012e8990a432a7bdf79cc4a5e953dedd4fe08623a2
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_ofiq-0.2.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
e0d3e835d48166ef5b998f59202a6c7e7c58db48e9e1ce4238d467d892017a28 - Sigstore transparency entry: 1359941319
- Sigstore integration time:
-
Permalink:
unicef/python-ofiq@58896f27ad33aadd387959fda565f4eaf1c35060 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/unicef
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58896f27ad33aadd387959fda565f4eaf1c35060 -
Trigger Event:
push
-
Statement type:
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
- Download URL: python_ofiq-0.2.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.9 MB
- Tags: CPython 3.12, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6f095aefccde2c85b847ba9dbb60f667e6d39a7c3fb5c04eb3929318f4967ad
|
|
| MD5 |
b655cb492fc483ab7ae3a50e0d83d119
|
|
| BLAKE2b-256 |
f291e3cfa1db7b7af39e8310d77ce7cc30522ce76a4ee111367e195252b221d3
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_ofiq-0.2.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
c6f095aefccde2c85b847ba9dbb60f667e6d39a7c3fb5c04eb3929318f4967ad - Sigstore transparency entry: 1359941362
- Sigstore integration time:
-
Permalink:
unicef/python-ofiq@58896f27ad33aadd387959fda565f4eaf1c35060 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/unicef
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58896f27ad33aadd387959fda565f4eaf1c35060 -
Trigger Event:
push
-
Statement type:
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
- Download URL: python_ofiq-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.9 MB
- Tags: CPython 3.11, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0091b20e2727523b9f42ad1e982b6821224b0d8620e66782104c8e2bc15456d
|
|
| MD5 |
09fb53b47e79b2d639c40f1eac073f18
|
|
| BLAKE2b-256 |
b7ea16b8fa146bbe0fabf1751596e5e4bc1624b1385b83568b7cd14d48fe7a38
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_ofiq-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
b0091b20e2727523b9f42ad1e982b6821224b0d8620e66782104c8e2bc15456d - Sigstore transparency entry: 1359941399
- Sigstore integration time:
-
Permalink:
unicef/python-ofiq@58896f27ad33aadd387959fda565f4eaf1c35060 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/unicef
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58896f27ad33aadd387959fda565f4eaf1c35060 -
Trigger Event:
push
-
Statement type:
File details
Details for the file python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl.
File metadata
- Download URL: python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl
- Upload date:
- Size: 19.6 MB
- Tags: CPython 3.11, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
466784eaaeafcf30b999f5598ecfbe04a0da63377d41cf9a2ff1d28e30ed501e
|
|
| MD5 |
fd56ed27128f2847520aae0813ca43dd
|
|
| BLAKE2b-256 |
7838dd80c60b4f815bcf3601092b4ad9df241081e3dc23d619e9ca04f0c138c6
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_ofiq-0.2.2-cp311-cp311-macosx_14_0_arm64.whl -
Subject digest:
466784eaaeafcf30b999f5598ecfbe04a0da63377d41cf9a2ff1d28e30ed501e - Sigstore transparency entry: 1524534772
- Sigstore integration time:
-
Permalink:
unicef/python-ofiq@79db750a21157e1bcb50f29032272d26d7c30a3a -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/unicef
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79db750a21157e1bcb50f29032272d26d7c30a3a -
Trigger Event:
push
-
Statement type: