2024-11-20 08:43:25 +00:00
# UniFace: All-in-One Face Analysis Library
[](https://opensource.org/licenses/MIT)
2025-11-08 01:02:14 +09:00

2024-11-20 08:43:25 +00:00
[](https://pypi.org/project/uniface/)
2025-11-08 01:46:28 +09:00
[](https://github.com/yakhyo/uniface/actions)
2024-11-20 08:43:25 +00:00
[](https://pepy.tech/project/uniface)
2025-04-03 13:44:32 +09:00
<div align="center">
<img src=".github/logos/logo_web.webp" width=75%>
</div>
2025-11-08 01:02:14 +09:00
**UniFace** is a lightweight, production-ready face analysis library built on ONNX Runtime. It provides high-performance face detection, recognition, landmark detection, and attribute analysis with hardware acceleration support across platforms.
2024-11-20 08:43:25 +00:00
---
## Features
2024-11-21 02:34:01 +00:00
2025-11-08 01:02:14 +09:00
- **High-Speed Face Detection**: ONNX-optimized RetinaFace and SCRFD models
- **Facial Landmark Detection**: Accurate 106-point landmark localization
- **Face Recognition**: ArcFace, MobileFace, and SphereFace embeddings
- **Attribute Analysis**: Age, gender, and emotion detection
- **Face Alignment**: Precise alignment for downstream tasks
- **Hardware Acceleration**: CoreML (Apple Silicon), CUDA (NVIDIA), CPU fallback
- **Simple API**: Intuitive factory functions and clean interfaces
- **Production-Ready**: Type hints, comprehensive logging, PEP8 compliant
2024-11-20 08:43:25 +00:00
---
## Installation
2025-11-08 01:02:14 +09:00
### Quick Install (All Platforms)
2024-11-20 08:43:25 +00:00
```bash
pip install uniface
```
2025-11-08 01:02:14 +09:00
### Platform-Specific Installation
#### macOS (Apple Silicon - M1/M2/M3/M4)
For optimal performance with **CoreML acceleration ** (3-5x faster):
```bash
# Standard installation (CPU only)
pip install uniface
# With CoreML acceleration (recommended for M-series chips)
pip install uniface[silicon]
```
**Verify CoreML is available:**
```python
import onnxruntime as ort
print(ort.get_available_providers())
# Should show: ['CoreMLExecutionProvider', 'CPUExecutionProvider']
```
#### Linux/Windows with NVIDIA GPU
```bash
# With CUDA acceleration
pip install uniface[gpu]
```
**Requirements:**
- CUDA 11.x or 12.x
- cuDNN 8.x
- See [ONNX Runtime GPU requirements ](https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html )
#### CPU-Only (All Platforms)
```bash
pip install uniface
```
### Install from Source
2024-11-20 08:43:25 +00:00
```bash
git clone https://github.com/yakhyo/uniface.git
cd uniface
2025-07-02 16:32:50 +09:00
pip install -e .
2024-11-20 08:43:25 +00:00
```
---
## Quick Start
2025-11-08 01:02:14 +09:00
### Face Detection
2024-11-21 05:55:55 +00:00
2025-11-08 01:02:14 +09:00
```python
import cv2
from uniface import RetinaFace
2024-11-21 05:55:55 +00:00
2025-11-08 01:02:14 +09:00
# Initialize detector
detector = RetinaFace()
2024-11-21 05:55:55 +00:00
2025-11-08 01:02:14 +09:00
# Load image
image = cv2.imread("image.jpg")
2025-01-09 05:16:32 +00:00
2025-11-08 01:02:14 +09:00
# Detect faces
faces = detector.detect(image)
2024-11-21 05:55:55 +00:00
2025-11-08 01:02:14 +09:00
# Process results
for face in faces:
bbox = face['bbox'] # [x1, y1, x2, y2]
confidence = face['confidence']
landmarks = face['landmarks'] # 5-point landmarks
print(f"Face detected with confidence: {confidence:.2f}")
```
2024-11-21 05:55:55 +00:00
2025-11-08 01:02:14 +09:00
### Face Recognition
2025-03-26 11:55:56 +09:00
2025-11-08 01:02:14 +09:00
```python
from uniface import ArcFace, RetinaFace
from uniface import compute_similarity
# Initialize models
detector = RetinaFace()
recognizer = ArcFace()
2025-03-26 11:55:56 +09:00
2025-11-08 01:02:14 +09:00
# Detect and extract embeddings
faces1 = detector.detect(image1)
faces2 = detector.detect(image2)
embedding1 = recognizer.get_normalized_embedding(image1, faces1[0]['landmarks'])
embedding2 = recognizer.get_normalized_embedding(image2, faces2[0]['landmarks'])
# Compare faces
similarity = compute_similarity(embedding1, embedding2)
print(f"Similarity: {similarity:.4f}")
```
### Facial Landmarks
2024-11-20 08:43:25 +00:00
```python
2025-11-08 01:02:14 +09:00
from uniface import RetinaFace, Landmark106
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
detector = RetinaFace()
landmarker = Landmark106()
faces = detector.detect(image)
landmarks = landmarker.get_landmarks(image, faces[0]['bbox'])
# Returns 106 (x, y) landmark points
2024-11-20 08:43:25 +00:00
```
2025-11-08 01:02:14 +09:00
### Age & Gender Detection
2025-03-26 11:55:56 +09:00
```python
2025-11-08 01:02:14 +09:00
from uniface import RetinaFace, AgeGender
2025-03-26 11:55:56 +09:00
2025-11-08 01:02:14 +09:00
detector = RetinaFace()
age_gender = AgeGender()
faces = detector.detect(image)
gender, age = age_gender.predict(image, faces[0]['bbox'])
print(f"{gender}, {age} years old")
2025-03-26 11:55:56 +09:00
```
2025-11-08 01:02:14 +09:00
---
## Documentation
- [**QUICKSTART.md** ](QUICKSTART.md ) - 5-minute getting started guide
- [**MODELS.md** ](MODELS.md ) - Model zoo, benchmarks, and selection guide
- [**Examples** ](examples/ ) - Jupyter notebooks with detailed examples
---
## API Overview
### Factory Functions (Recommended)
2025-03-26 11:55:56 +09:00
```python
2025-11-08 01:02:14 +09:00
from uniface import create_detector, create_recognizer, create_landmarker
# Create detector with default settings
detector = create_detector('retinaface')
# Create with custom config
detector = create_detector(
'scrfd',
model_name='scrfd_10g_kps',
conf_thresh=0.8,
input_size=(640, 640)
)
# Recognition and landmarks
recognizer = create_recognizer('arcface')
landmarker = create_landmarker('2d106det')
2025-03-26 11:55:56 +09:00
```
2025-11-08 01:02:14 +09:00
### Direct Model Instantiation
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
```python
from uniface import RetinaFace, SCRFD, ArcFace, MobileFace
from uniface.constants import RetinaFaceWeights
# Detection
detector = RetinaFace(
model_name=RetinaFaceWeights.MNET_V2,
conf_thresh=0.5,
nms_thresh=0.4
)
# Recognition
recognizer = ArcFace() # Uses default weights
recognizer = MobileFace() # Lightweight alternative
```
### High-Level Detection API
2024-11-20 08:43:25 +00:00
```python
2025-11-08 01:02:14 +09:00
from uniface import detect_faces
# One-line face detection
faces = detect_faces(image, method='retinaface', conf_thresh=0.8)
```
---
## Model Performance
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Face Detection (WIDER FACE Dataset)
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
| Model | Easy | Medium | Hard | Use Case |
|--------------------|--------|--------|--------|-------------------------|
| retinaface_mnet025 | 88.48% | 87.02% | 80.61% | Mobile/Edge devices |
| retinaface_mnet_v2 | 91.70% | 91.03% | 86.60% | Balanced (recommended) |
| retinaface_r34 | 94.16% | 93.12% | 88.90% | High accuracy |
| scrfd_500m | 90.57% | 88.12% | 68.51% | Real-time applications |
| scrfd_10g | 95.16% | 93.87% | 83.05% | Best accuracy/speed |
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
*Accuracy values from original papers: [RetinaFace ](https://arxiv.org/abs/1905.00641 ), [SCRFD ](https://arxiv.org/abs/2105.04714 )*
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
**Benchmark on your hardware:**
```bash
python scripts/run_detection.py --image assets/test.jpg --iterations 100
2024-11-20 08:43:25 +00:00
```
2025-11-08 01:02:14 +09:00
See [MODELS.md ](MODELS.md ) for detailed model information and selection guide.
<div align="center">
<img src="assets/test_result.png">
</div>
---
## Examples
### Webcam Face Detection
2024-11-20 08:43:25 +00:00
```python
import cv2
2025-11-08 01:02:14 +09:00
from uniface import RetinaFace
2024-11-20 08:43:25 +00:00
from uniface.visualization import draw_detections
2025-11-08 01:02:14 +09:00
detector = RetinaFace()
2024-11-20 08:43:25 +00:00
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
2025-11-08 01:02:14 +09:00
faces = detector.detect(frame)
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
# Extract data for visualization
bboxes = [f['bbox'] for f in faces]
scores = [f['confidence'] for f in faces]
landmarks = [f['landmarks'] for f in faces]
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
draw_detections(frame, bboxes, scores, landmarks, vis_threshold=0.6)
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
cv2.imshow("Face Detection", frame)
2024-11-20 08:43:25 +00:00
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
```
2025-11-08 01:02:14 +09:00
### Face Search System
```python
import numpy as np
from uniface import RetinaFace, ArcFace
detector = RetinaFace()
recognizer = ArcFace()
# Build face database
database = {}
for person_id, image_path in person_images.items():
image = cv2.imread(image_path)
faces = detector.detect(image)
if faces:
embedding = recognizer.get_normalized_embedding(
image, faces[0]['landmarks']
)
database[person_id] = embedding
# Search for a face
query_image = cv2.imread("query.jpg")
query_faces = detector.detect(query_image)
if query_faces:
query_embedding = recognizer.get_normalized_embedding(
query_image, query_faces[0]['landmarks']
)
# Find best match
best_match = None
best_similarity = -1
for person_id, db_embedding in database.items():
similarity = np.dot(query_embedding, db_embedding.T)[0][0]
if similarity > best_similarity:
best_similarity = similarity
best_match = person_id
print(f"Best match: {best_match} (similarity: {best_similarity:.4f})")
```
More examples in the [examples/ ](examples/ ) directory.
2024-11-20 08:43:25 +00:00
---
2025-11-08 01:02:14 +09:00
## Advanced Configuration
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Custom ONNX Runtime Providers
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
```python
from uniface.onnx_utils import get_available_providers, create_onnx_session
2025-01-09 05:16:32 +00:00
2025-11-08 01:02:14 +09:00
# Check available providers
providers = get_available_providers()
print(f"Available: {providers}")
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
# Force CPU-only execution
from uniface import RetinaFace
detector = RetinaFace()
# Internally uses create_onnx_session() which auto-selects best provider
```
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Model Download and Caching
Models are automatically downloaded on first use and cached in `~/.uniface/models/` .
2024-11-21 02:34:01 +00:00
2024-11-20 08:43:25 +00:00
```python
2025-11-08 01:02:14 +09:00
from uniface.model_store import verify_model_weights
2025-03-26 11:55:56 +09:00
from uniface.constants import RetinaFaceWeights
2024-11-23 10:25:09 +00:00
2025-11-08 01:02:14 +09:00
# Manually download and verify a model
model_path = verify_model_weights(
RetinaFaceWeights.MNET_V2,
root='./custom_models' # Custom cache directory
2024-11-20 08:43:25 +00:00
)
```
2025-11-08 01:02:14 +09:00
### Logging Configuration
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
```python
from uniface import Logger
import logging
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
# Set logging level
Logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR
2024-11-21 02:34:01 +00:00
2025-11-08 01:02:14 +09:00
# Disable logging
Logger.setLevel(logging.CRITICAL)
2024-11-20 08:43:25 +00:00
```
2025-11-08 01:02:14 +09:00
---
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
## Testing
2024-11-21 02:34:01 +00:00
2025-11-08 01:02:14 +09:00
```bash
# Run all tests
pytest
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
# Run with coverage
pytest --cov=uniface --cov-report=html
2024-11-21 02:34:01 +00:00
2025-11-08 01:02:14 +09:00
# Run specific test file
pytest tests/test_retinaface.py -v
```
2024-11-20 08:43:25 +00:00
---
2025-11-08 01:02:14 +09:00
## Development
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Setup Development Environment
2024-11-21 02:34:01 +00:00
2025-11-08 01:02:14 +09:00
```bash
git clone https://github.com/yakhyo/uniface.git
cd uniface
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
# Run tests
pytest
2024-11-21 02:34:01 +00:00
2025-11-08 01:02:14 +09:00
# Format code
black uniface/
isort uniface/
```
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Project Structure
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
```
uniface/
├── uniface/
│ ├── detection/ # Face detection models
│ ├── recognition/ # Face recognition models
│ ├── landmark/ # Landmark detection
│ ├── attribute/ # Age, gender, emotion
│ ├── onnx_utils.py # ONNX Runtime utilities
│ ├── model_store.py # Model download & caching
│ └── visualization.py # Drawing utilities
├── tests/ # Unit tests
├── examples/ # Example notebooks
└── scripts/ # Utility scripts
```
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
---
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
## References
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Model Training & Architectures
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
- **RetinaFace Training**: [yakhyo/retinaface-pytorch ](https://github.com/yakhyo/retinaface-pytorch ) - PyTorch implementation and training code
- **Face Recognition Training**: [yakhyo/face-recognition ](https://github.com/yakhyo/face-recognition ) - ArcFace, MobileFace, SphereFace training code
- **InsightFace**: [deepinsight/insightface ](https://github.com/deepinsight/insightface ) - Model architectures and pretrained weights
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
### Papers
- **RetinaFace**: [Single-Shot Multi-Level Face Localisation in the Wild ](https://arxiv.org/abs/1905.00641 )
- **SCRFD**: [Sample and Computation Redistribution for Efficient Face Detection ](https://arxiv.org/abs/2105.04714 )
- **ArcFace**: [Additive Angular Margin Loss for Deep Face Recognition ](https://arxiv.org/abs/1801.07698 )
2024-11-20 08:43:25 +00:00
---
2025-11-08 01:02:14 +09:00
## Contributing
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
Contributions are welcome! Please open an issue or submit a pull request on [GitHub ](https://github.com/yakhyo/uniface ).
2024-11-20 08:43:25 +00:00