2024-11-20 08:43:25 +00:00
# UniFace: All-in-One Face Analysis Library
2025-12-24 00:34:24 +09:00
<div align="center">
2024-11-20 08:43:25 +00:00
[](https://opensource.org/licenses/MIT)
2025-12-28 21:07:36 +09:00
[](https://www.python.org/)
2025-11-30 20:32:07 +09:00
[](https://pypi.org/project/uniface/)
2025-11-08 01:46:28 +09:00
[](https://github.com/yakhyo/uniface/actions)
2025-12-24 00:34:24 +09:00
[](https://pepy.tech/project/uniface)
[](https://deepwiki.com/yakhyo/uniface)
</div>
2025-12-01 13:19:25 +09:00
2025-04-03 13:44:32 +09:00
<div align="center">
<img src=".github/logos/logo_web.webp" width=75%>
</div>
2025-12-14 21:13:53 +09:00
**UniFace** is a lightweight, production-ready face analysis library built on ONNX Runtime. It provides high-performance face detection, recognition, landmark detection, face parsing, gaze estimation, 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-12-07 19:51:08 +09:00
- **High-Speed Face Detection**: ONNX-optimized RetinaFace, SCRFD, and YOLOv5-Face models
2025-11-08 01:02:14 +09:00
- **Facial Landmark Detection**: Accurate 106-point landmark localization
- **Face Recognition**: ArcFace, MobileFace, and SphereFace embeddings
2025-12-14 21:13:53 +09:00
- **Face Parsing**: BiSeNet-based semantic segmentation with 19 facial component classes
2025-12-14 14:07:46 +09:00
- **Gaze Estimation**: Real-time gaze direction prediction with MobileGaze
2025-12-28 21:07:36 +09:00
- **Attribute Analysis**: Age, gender, race (FairFace), and emotion detection
2025-12-20 22:34:47 +09:00
- **Anti-Spoofing**: Face liveness detection with MiniFASNet models
2025-12-20 21:27:26 +09:00
- **Face Anonymization**: Privacy-preserving face blurring with 5 methods (pixelate, gaussian, blackout, elliptical, median)
2025-11-08 01:02:14 +09:00
- **Face Alignment**: Precise alignment for downstream tasks
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
- **Hardware Acceleration**: ARM64 optimizations (Apple Silicon), CUDA (NVIDIA), CPU fallback
2025-11-08 01:02:14 +09:00
- **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)
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
For Apple Silicon Macs, the standard installation automatically includes optimized ARM64 support:
2025-11-08 01:02:14 +09:00
```bash
pip install uniface
```
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
The base `onnxruntime` package (included with uniface) has native Apple Silicon support with ARM64 optimizations built-in since version 1.13+.
2025-11-08 01:02:14 +09:00
#### Linux/Windows with NVIDIA GPU
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
For CUDA acceleration on NVIDIA GPUs:
2025-11-08 01:02:14 +09:00
```bash
pip install uniface[gpu]
```
**Requirements:**
2025-11-30 20:32:07 +09:00
2025-11-08 01:02:14 +09:00
- 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:
2025-12-22 19:25:38 +09:00
bbox = face.bbox # np.ndarray [x1, y1, x2, y2]
confidence = face.confidence
landmarks = face.landmarks # np.ndarray (5, 2) landmarks
2025-11-08 01:02:14 +09:00
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)
2025-12-22 19:25:38 +09:00
embedding1 = recognizer.get_normalized_embedding(image1, faces1[0].landmarks)
embedding2 = recognizer.get_normalized_embedding(image2, faces2[0].landmarks)
2025-11-08 01:02:14 +09:00
# 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)
2025-12-22 19:25:38 +09:00
landmarks = landmarker.get_landmarks(image, faces[0].bbox)
2025-11-08 01:02:14 +09:00
# 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)
2025-12-28 21:07:36 +09:00
result = age_gender.predict(image, faces[0].bbox)
print(f"{result.sex}, {result.age} years old")
# result.gender: 0=Female, 1=Male
# result.sex: "Female" or "Male"
# result.age: age in years
```
### FairFace Attributes (Race, Gender, Age Group)
```python
from uniface import RetinaFace, FairFace
detector = RetinaFace()
fairface = FairFace()
faces = detector.detect(image)
result = fairface.predict(image, faces[0].bbox)
print(f"{result.sex}, {result.age_group}, {result.race}")
# result.gender: 0=Female, 1=Male
# result.sex: "Female" or "Male"
# result.age_group: "20-29", "30-39", etc.
# result.race: "East Asian", "White", etc.
2025-03-26 11:55:56 +09:00
```
2025-12-14 14:07:46 +09:00
### Gaze Estimation
```python
from uniface import RetinaFace, MobileGaze
from uniface.visualization import draw_gaze
import numpy as np
detector = RetinaFace()
gaze_estimator = MobileGaze()
faces = detector.detect(image)
for face in faces:
2025-12-22 19:25:38 +09:00
x1, y1, x2, y2 = map(int, face.bbox[:4])
2025-12-14 14:07:46 +09:00
face_crop = image[y1:y2, x1:x2]
2025-12-30 17:05:24 +09:00
result = gaze_estimator.estimate(face_crop)
print(f"Gaze: pitch={np.degrees(result.pitch):.1f}°, yaw={np.degrees(result.yaw):.1f}°")
2025-12-14 14:07:46 +09:00
# Visualize
2025-12-30 17:05:24 +09:00
draw_gaze(image, face.bbox, result.pitch, result.yaw)
2025-12-14 14:07:46 +09:00
```
2025-12-14 21:13:53 +09:00
### Face Parsing
```python
from uniface.parsing import BiSeNet
from uniface.visualization import vis_parsing_maps
# Initialize parser
parser = BiSeNet() # Uses ResNet18 by default
# Parse face image (already cropped)
mask = parser.parse(face_image)
# Visualize with overlay
import cv2
face_rgb = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
vis_result = vis_parsing_maps(face_rgb, mask, save_image=False)
# mask contains 19 classes: skin, eyes, nose, mouth, hair, etc.
print(f"Unique classes: {len(np.unique(mask))}")
```
2025-12-20 22:34:47 +09:00
### Face Anti-Spoofing
Detect if a face is real or fake (photo, video replay, mask):
```python
from uniface import RetinaFace
from uniface.spoofing import MiniFASNet
detector = RetinaFace()
spoofer = MiniFASNet() # Uses V2 by default
faces = detector.detect(image)
for face in faces:
2025-12-30 17:05:24 +09:00
result = spoofer.predict(image, face.bbox)
# result.is_real: True for real, False for fake
# result.confidence: confidence score
label = 'Real' if result.is_real else 'Fake'
print(f"{label}: {result.confidence:.1%}")
2025-12-20 22:34:47 +09:00
```
2025-12-20 20:57:42 +09:00
### Face Anonymization
2025-12-20 21:27:26 +09:00
Protect privacy by blurring or pixelating faces with 5 different methods:
2025-12-20 20:57:42 +09:00
```python
from uniface import RetinaFace
from uniface.privacy import BlurFace, anonymize_faces
2025-12-20 21:27:26 +09:00
import cv2
2025-12-20 20:57:42 +09:00
# Method 1: One-liner with automatic detection
2025-12-20 21:27:26 +09:00
image = cv2.imread("photo.jpg")
2025-12-20 20:57:42 +09:00
anonymized = anonymize_faces(image, method='pixelate')
2025-12-20 21:27:26 +09:00
cv2.imwrite("anonymized.jpg", anonymized)
2025-12-20 20:57:42 +09:00
# Method 2: Manual control with custom parameters
detector = RetinaFace()
2025-12-20 21:27:26 +09:00
blurrer = BlurFace(method='gaussian', blur_strength=5.0)
2025-12-20 20:57:42 +09:00
faces = detector.detect(image)
anonymized = blurrer.anonymize(image, faces)
2025-12-20 21:27:26 +09:00
# Available blur methods:
2025-12-20 20:57:42 +09:00
methods = {
2025-12-20 21:27:26 +09:00
'pixelate': BlurFace(method='pixelate', pixel_blocks=10), # Blocky effect (news media standard)
2025-12-20 20:57:42 +09:00
'gaussian': BlurFace(method='gaussian', blur_strength=3.0), # Smooth, natural blur
2025-12-20 21:27:26 +09:00
'blackout': BlurFace(method='blackout', color=(0, 0, 0)), # Solid color boxes (maximum privacy)
'elliptical': BlurFace(method='elliptical', margin=20), # Soft oval blur (natural face shape)
'median': BlurFace(method='median', blur_strength=3.0) # Edge-preserving blur
2025-12-20 20:57:42 +09:00
}
2025-12-20 21:27:26 +09:00
# Real-time webcam anonymization
cap = cv2.VideoCapture(0)
detector = RetinaFace()
blurrer = BlurFace(method='pixelate')
while True:
ret, frame = cap.read()
if not ret:
break
faces = detector.detect(frame)
frame = blurrer.anonymize(frame, faces, inplace=True)
cv2.imshow('Anonymized', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
2025-12-20 20:57:42 +09:00
```
2025-12-20 21:27:26 +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
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
from uniface.detection import RetinaFace, SCRFD
from uniface.recognition import ArcFace
from uniface.landmark import Landmark106
2025-12-20 20:57:42 +09:00
from uniface.privacy import BlurFace, anonymize_faces
2025-11-08 01:02:14 +09:00
2025-12-08 10:07:30 +09:00
from uniface.constants import SCRFDWeights
2025-11-08 01:02:14 +09:00
# Create detector with default settings
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
detector = RetinaFace()
2025-11-08 01:02:14 +09:00
# Create with custom config
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
detector = SCRFD(
2025-12-08 10:07:30 +09:00
model_name=SCRFDWeights.SCRFD_10G_KPS, # SCRFDWeights.SCRFD_500M_KPS
2025-12-30 00:20:34 +09:00
confidence_threshold=0.4,
2025-11-08 01:02:14 +09:00
input_size=(640, 640)
)
2025-12-08 10:07:30 +09:00
# Or with defaults settings: detector = SCRFD()
2025-11-08 01:02:14 +09:00
# Recognition and landmarks
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
recognizer = ArcFace()
landmarker = Landmark106()
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
2025-12-03 23:35:56 +09:00
from uniface import RetinaFace, SCRFD, YOLOv5Face, ArcFace, MobileFace, SphereFace
from uniface.constants import RetinaFaceWeights, YOLOv5FaceWeights
2025-11-08 01:02:14 +09:00
# Detection
detector = RetinaFace(
model_name=RetinaFaceWeights.MNET_V2,
2025-12-30 00:20:34 +09:00
confidence_threshold=0.5,
nms_threshold=0.4
2025-11-08 01:02:14 +09:00
)
2025-12-08 10:07:30 +09:00
# Or detector = RetinaFace()
2025-11-08 01:02:14 +09:00
2025-12-03 23:35:56 +09:00
# YOLOv5-Face detection
detector = YOLOv5Face(
model_name=YOLOv5FaceWeights.YOLOV5S,
2025-12-30 00:20:34 +09:00
confidence_threshold=0.6,
nms_threshold=0.5
2025-12-03 23:35:56 +09:00
)
2025-12-08 10:07:30 +09:00
# Or detector = YOLOv5Face
2025-12-03 23:35:56 +09:00
2025-11-08 01:02:14 +09:00
# Recognition
recognizer = ArcFace() # Uses default weights
recognizer = MobileFace() # Lightweight alternative
ref: Add comprehensive test suite and enhance model functionality
- Add new test files for age_gender, factory, landmark, recognition, scrfd, and utils
- Add new scripts for age_gender, landmarks, and video detection
- Update documentation in README.md, MODELS.md, QUICKSTART.md
- Improve model constants and face utilities
- Update detection models (retinaface, scrfd) with enhanced functionality
- Update project configuration in pyproject.toml
2025-11-15 21:09:37 +09:00
recognizer = SphereFace() # Angular softmax alternative
2025-11-08 01:02:14 +09:00
```
### 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
2025-12-30 00:20:34 +09:00
faces = detect_faces(image, method='retinaface', confidence_threshold=0.8) # methods: retinaface, scrfd, yolov5face
2025-11-08 01:02:14 +09:00
```
2025-12-07 19:51:08 +09:00
### Key Parameters (quick reference)
**Detection**
| Class | Key params (defaults) | Notes |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------- |
2025-12-30 00:20:34 +09:00
| `RetinaFace` | `model_name=RetinaFaceWeights.MNET_V2` , `confidence_threshold=0.5` , `nms_threshold=0.4` , `input_size=(640, 640)` , `dynamic_size=False` | Supports 5-point landmarks |
| `SCRFD` | `model_name=SCRFDWeights.SCRFD_10G_KPS` , `confidence_threshold=0.5` , `nms_threshold=0.4` , `input_size=(640, 640)` | Supports 5-point landmarks |
| `YOLOv5Face` | `model_name=YOLOv5FaceWeights.YOLOV5S` , `confidence_threshold=0.6` , `nms_threshold=0.5` , `input_size=640` (fixed) | Supports 5-point landmarks; models: YOLOV5N/S/M; `input_size` must be 640 |
2025-12-07 19:51:08 +09:00
**Recognition**
| Class | Key params (defaults) | Notes |
| -------------- | ----------------------------------------- | ------------------------------------- |
| `ArcFace` | `model_name=ArcFaceWeights.MNET` | Returns 512-dim normalized embeddings |
| `MobileFace` | `model_name=MobileFaceWeights.MNET_V2` | Lightweight embeddings |
| `SphereFace` | `model_name=SphereFaceWeights.SPHERE20` | Angular softmax variant |
**Landmark & Attributes**
| Class | Key params (defaults) | Notes |
| --------------- | --------------------------------------------------------------------- | --------------------------------------- |
| `Landmark106` | No required params | 106-point landmarks |
2025-12-28 21:07:36 +09:00
| `AgeGender` | `model_name=AgeGenderWeights.DEFAULT` ; `input_size` auto-detected | Returns `AttributeResult` with gender, age |
| `FairFace` | `model_name=FairFaceWeights.DEFAULT` , `input_size=(224, 224)` | Returns `AttributeResult` with gender, age_group, race |
2025-12-07 19:51:08 +09:00
| `Emotion` | `model_weights=DDAMFNWeights.AFFECNET7` , `input_size=(112, 112)` | Requires 5-point landmarks; TorchScript |
2025-12-14 14:07:46 +09:00
**Gaze Estimation**
| Class | Key params (defaults) | Notes |
| ------------- | ------------------------------------------ | ------------------------------------ |
2025-12-30 17:05:24 +09:00
| `MobileGaze` | `model_name=GazeWeights.RESNET34` | Returns `GazeResult(pitch, yaw)` in radians; trained on Gaze360 |
2025-12-14 14:07:46 +09:00
2025-12-14 21:13:53 +09:00
**Face Parsing**
| Class | Key params (defaults) | Notes |
| ---------- | ---------------------------------------- | ------------------------------------ |
| `BiSeNet` | `model_name=ParsingWeights.RESNET18` , `input_size=(512, 512)` | 19 facial component classes; BiSeNet architecture with ResNet backbone |
2025-12-20 22:34:47 +09:00
**Anti-Spoofing**
| Class | Key params (defaults) | Notes |
| ------------- | ----------------------------------------- | ------------------------------------ |
2025-12-30 17:05:24 +09:00
| `MiniFASNet` | `model_name=MiniFASNetWeights.V2` | Returns `SpoofingResult(is_real, confidence)` |
2025-12-20 22:34:47 +09:00
2025-11-08 01:02:14 +09:00
---
## 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-30 20:32:07 +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 |
2025-12-11 01:02:18 +09:00
| yolov5n_face | 93.61% | 91.52% | 80.53% | Lightweight/Mobile |
2025-12-03 23:35:56 +09:00
| yolov5s_face | 94.33% | 92.61% | 83.15% | Real-time + accuracy |
| yolov5m_face | 95.30% | 93.76% | 85.28% | High accuracy |
2024-11-20 08:43:25 +00:00
2025-12-03 23:35:56 +09:00
_Accuracy values from original papers: [RetinaFace ](https://arxiv.org/abs/1905.00641 ), [SCRFD ](https://arxiv.org/abs/2105.04714 ), [YOLOv5-Face ](https://arxiv.org/abs/2105.12931 )_
2024-11-20 08:43:25 +00:00
2025-11-08 01:02:14 +09:00
**Benchmark on your hardware:**
2025-11-30 20:32:07 +09:00
2025-11-08 01:02:14 +09:00
```bash
2025-12-30 17:05:24 +09:00
python tools/detection.py --source 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
2025-12-07 19:51:08 +09:00
### Jupyter Notebooks
Interactive examples covering common face analysis tasks:
| Example | Description | Notebook |
|---------|-------------|----------|
2025-12-30 00:20:34 +09:00
| **Face Detection ** | Detect faces and facial landmarks | [01_face_detection.ipynb ](examples/01_face_detection.ipynb ) |
| **Face Alignment ** | Align and crop faces for recognition | [02_face_alignment.ipynb ](examples/02_face_alignment.ipynb ) |
| **Face Verification ** | Compare two faces to verify identity | [03_face_verification.ipynb ](examples/03_face_verification.ipynb ) |
| **Face Search ** | Find a person in a group photo | [04_face_search.ipynb ](examples/04_face_search.ipynb ) |
| **Face Analyzer ** | All-in-one detection, recognition & attributes | [05_face_analyzer.ipynb ](examples/05_face_analyzer.ipynb ) |
| **Face Parsing ** | Segment face into semantic components | [06_face_parsing.ipynb ](examples/06_face_parsing.ipynb ) |
| **Face Anonymization ** | Blur or pixelate faces for privacy protection | [07_face_anonymization.ipynb ](examples/07_face_anonymization.ipynb ) |
| **Gaze Estimation ** | Estimate gaze direction from face images | [08_gaze_estimation.ipynb ](examples/08_gaze_estimation.ipynb ) |
2025-12-07 19:51:08 +09:00
2025-11-08 01:02:14 +09:00
### 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
2025-12-22 19:25:38 +09:00
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-12-07 19:51:08 +09:00
draw_detections(
image=frame,
bboxes=bboxes,
scores=scores,
landmarks=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(
2025-12-22 19:25:38 +09:00
image, faces[0].landmarks
2025-11-08 01:02:14 +09:00
)
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(
2025-12-22 19:25:38 +09:00
query_image, query_faces[0].landmarks
2025-11-08 01:02:14 +09:00
)
# 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
2025-11-26 00:05:40 +09:00
```
### Code Formatting
2024-11-21 02:34:01 +00:00
2025-11-26 00:05:40 +09:00
This project uses [Ruff ](https://docs.astral.sh/ruff/ ) for linting and formatting.
```bash
2025-11-08 01:02:14 +09:00
# Format code
2025-11-26 00:05:40 +09:00
ruff format .
# Check for linting errors
ruff check .
# Auto-fix linting errors
ruff check . --fix
2025-11-08 01:02:14 +09:00
```
2024-11-20 08:43:25 +00:00
2025-11-26 00:05:40 +09:00
Ruff configuration is in `pyproject.toml` . Key settings:
2025-11-30 20:32:07 +09:00
2025-11-26 00:05:40 +09:00
- Line length: 120
- Python target: 3.10+
- Import sorting: `uniface` as first-party
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
2025-12-14 21:13:53 +09:00
│ ├── parsing/ # Face parsing
2025-12-14 14:07:46 +09:00
│ ├── gaze/ # Gaze estimation
2025-11-08 01:02:14 +09:00
│ ├── attribute/ # Age, gender, emotion
2025-12-20 22:34:47 +09:00
│ ├── spoofing/ # Face anti-spoofing
2025-12-20 21:27:26 +09:00
│ ├── privacy/ # Face anonymization & blurring
2025-11-08 01:02:14 +09:00
│ ├── onnx_utils.py # ONNX Runtime utilities
│ ├── model_store.py # Model download & caching
│ └── visualization.py # Drawing utilities
├── tests/ # Unit tests
├── examples/ # Example notebooks
2025-12-30 17:05:24 +09:00
└── tools/ # CLI utilities
2025-11-08 01:02:14 +09:00
```
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
- **RetinaFace Training**: [yakhyo/retinaface-pytorch ](https://github.com/yakhyo/retinaface-pytorch ) - PyTorch implementation and training code
2025-12-03 23:35:56 +09:00
- **YOLOv5-Face ONNX**: [yakhyo/yolov5-face-onnx-inference ](https://github.com/yakhyo/yolov5-face-onnx-inference ) - ONNX inference implementation
2025-11-08 01:02:14 +09:00
- **Face Recognition Training**: [yakhyo/face-recognition ](https://github.com/yakhyo/face-recognition ) - ArcFace, MobileFace, SphereFace training code
2025-12-14 21:13:53 +09:00
- **Face Parsing Training**: [yakhyo/face-parsing ](https://github.com/yakhyo/face-parsing ) - BiSeNet face parsing training code and pretrained weights
2025-12-14 14:07:46 +09:00
- **Gaze Estimation Training**: [yakhyo/gaze-estimation ](https://github.com/yakhyo/gaze-estimation ) - MobileGaze training code and pretrained weights
2025-12-20 22:34:47 +09:00
- **Face Anti-Spoofing**: [yakhyo/face-anti-spoofing ](https://github.com/yakhyo/face-anti-spoofing ) - MiniFASNet ONNX inference (weights from [minivision-ai/Silent-Face-Anti-Spoofing ](https://github.com/minivision-ai/Silent-Face-Anti-Spoofing ))
2025-12-28 21:07:36 +09:00
- **FairFace**: [yakhyo/fairface-onnx ](https://github.com/yakhyo/fairface-onnx ) - FairFace ONNX inference for race, gender, age prediction
2025-11-08 01:02:14 +09:00
- **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
## 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 ).