# UniFace: All-in-One Face Analysis Library
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
![Python](https://img.shields.io/badge/Python-3.8%2B-blue)
[![PyPI Version](https://img.shields.io/pypi/v/uniface.svg)](https://pypi.org/project/uniface/)
[![Build Status](https://github.com/yakhyo/uniface/actions/workflows/build.yml/badge.svg)](https://github.com/yakhyo/uniface/actions)
[![GitHub Repository](https://img.shields.io/badge/GitHub-Repository-blue?logo=github)](https://github.com/yakhyo/uniface)
[![Downloads](https://pepy.tech/badge/uniface)](https://pepy.tech/project/uniface)
[![Code Style: PEP8](https://img.shields.io/badge/code%20style-PEP8-green.svg)](https://www.python.org/dev/peps/pep-0008/)
[![GitHub Release Downloads](https://img.shields.io/github/downloads/yakhyo/uniface/total.svg?label=Model%20Downloads)](https://github.com/yakhyo/uniface/releases)
**uniface** is a lightweight face detection library designed for high-performance face localization, landmark detection and face alignment. The library supports ONNX models and provides utilities for bounding box visualization and landmark plotting. To train RetinaFace model, see https://github.com/yakhyo/retinaface-pytorch.
---
## Features
- [ ] Age and gender detection (Planned).
- [ ] Face recognition (Planned).
- [x] Face Alignment (Added: 2024-11-21).
- [x] High-speed face detection using ONNX models (Added: 2024-11-20).
- [x] Accurate facial landmark localization (e.g., eyes, nose, and mouth) (Added: 2024-11-20).
- [x] Easy-to-use API for inference and visualization (Added: 2024-11-20).
---
## Installation
The easiest way to install **UniFace** is via [PyPI](https://pypi.org/project/uniface/). This will automatically install the library along with its prerequisites.
```bash
pip install uniface
```
To work with the latest version of **UniFace**, which may not yet be released on PyPI, you can install it directly from the repository:
```bash
git clone https://github.com/yakhyo/uniface.git
cd uniface
pip install .
```
---
## Quick Start
To get started with face detection using **UniFace**, check out the [example notebook](examples/face_detection.ipynb).
It demonstrates how to initialize the model, run inference, and visualize the results.
---
## Examples
Explore the following example notebooks to learn how to use **UniFace** effectively:
- [Face Detection](examples/face_detection.ipynb): Demonstrates how to perform face detection, draw bounding boxes, and landmarks on an image.
- [Face Alignment](examples/face_alignment.ipynb): Shows how to align faces using detected landmarks.
- [Age and Gender Detection](examples/age_gender.ipynb): Example for detecting age and gender from faces. (underdevelopment)
### Initialize the Model
```python
from uniface import RetinaFace
# Initialize the RetinaFace model
uniface_inference = RetinaFace(
model="retinaface_mnet_v2", # Model name
conf_thresh=0.5, # Confidence threshold
pre_nms_topk=5000, # Pre-NMS Top-K detections
nms_thresh=0.4, # NMS IoU threshold
post_nms_topk=750, # Post-NMS Top-K detections
dynamic_size=False, # Arbitrary image size inference
input_size=(640, 640) # Pre-defined input image size
)
```
### Run Inference
Inference on image:
```python
import cv2
from uniface.visualization import draw_detections
# Load an image
image_path = "assets/test.jpg"
original_image = cv2.imread(image_path)
# Perform inference
boxes, landmarks = uniface_inference.detect(original_image)
# Visualize results
draw_detections(original_image, (boxes, landmarks), vis_threshold=0.6)
# Save the output image
output_path = "output.jpg"
cv2.imwrite(output_path, original_image)
print(f"Saved output image to {output_path}")
```
Inference on video:
```python
import cv2
from uniface.visualization import draw_detections
# Initialize the webcam
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Error: Unable to access the webcam.")
exit()
while True:
# Capture a frame from the webcam
ret, frame = cap.read()
if not ret:
print("Error: Failed to read frame.")
break
# Perform inference
boxes, landmarks = uniface_inference.detect(frame)
# Draw detections on the frame
draw_detections(frame, (boxes, landmarks), vis_threshold=0.6)
# Display the output
cv2.imshow("Webcam Inference", frame)
# Exit if 'q' is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release the webcam and close all OpenCV windows
cap.release()
cv2.destroyAllWindows()
```
---
### Evaluation results of available models on WiderFace
| RetinaFace Models | Easy | Medium | Hard |
| ------------------ | ---------- | ---------- | ---------- |
| retinaface_mnet025 | 88.48% | 87.02% | 80.61% |
| retinaface_mnet050 | 89.42% | 87.97% | 82.40% |
| retinaface_mnet_v1 | 90.59% | 89.14% | 84.13% |
| retinaface_mnet_v2 | 91.70% | 91.03% | 86.60% |
| retinaface_r18 | 92.50% | 91.02% | 86.63% |
| retinaface_r34 | **94.16%** | **93.12%** | **88.90%** |
## API Reference
### `RetinaFace` Class
#### Initialization
```python
from typings import Tuple
RetinaFace(
model: str,
conf_thresh: float = 0.5,
pre_nms_topk: int = 5000,
nms_thresh: float = 0.4,
post_nms_topk: int = 750,
dynamic_size: bool = False,
input_size: Tuple[int, int] = (640, 640)
)
```
**Parameters**:
- `model` _(str)_: Name of the model to use. Supported models:
- `retinaface_mnet025`, `retinaface_mnet050`, `retinaface_mnet_v1`, `retinaface_mnet_v2`
- `retinaface_r18`, `retinaface_r34`
- `conf_thresh` _(float, default=0.5)_: Minimum confidence score for detections.
- `pre_nms_topk` _(int, default=5000)_: Max detections to keep before NMS.
- `nms_thresh` _(float, default=0.4)_: IoU threshold for Non-Maximum Suppression.
- `post_nms_topk` _(int, default=750)_: Max detections to keep after NMS.
- `dynamic_size` _(Optional[bool], default=False)_: Use dynamic input size.
- `input_size` _(Optional[Tuple[int, int]], default=(640, 640))_: Static input size for the model (width, height).
---
### `detect` Method
```python
detect(
image: np.ndarray,
max_num: int = 0,
metric: str = "default",
center_weight: float = 2.0
) -> Tuple[np.ndarray, np.ndarray]
```
**Description**:
Detects faces in the given image and returns bounding boxes and landmarks.
**Parameters**:
- `image` _(np.ndarray)_: Input image in BGR format.
- `max_num` _(int, default=0)_: Maximum number of faces to return. `0` means return all.
- `metric` _(str, default="default")_: Metric for prioritizing detections:
- `"default"`: Prioritize detections closer to the image center.
- `"max"`: Prioritize larger bounding box areas.
- `center_weight` _(float, default=2.0)_: Weight for prioritizing center-aligned faces.
**Returns**:
- `bounding_boxes` _(np.ndarray)_: Array of detections as `[x_min, y_min, x_max, y_max, confidence]`.
- `landmarks` _(np.ndarray)_: Array of landmarks as `[(x1, y1), ..., (x5, y5)]`.
---
### Visualization Utilities
#### `draw_detections`
```python
draw_detections(
image: np.ndarray,
detections: Tuple[np.ndarray, np.ndarray],
vis_threshold: float = 0.6
) -> None
```
**Description**:
Draws bounding boxes and landmarks on the given image.
**Parameters**:
- `image` _(np.ndarray)_: The input image in BGR format.
- `detections` _(Tuple[np.ndarray, np.ndarray])_: A tuple of bounding boxes and landmarks.
- `vis_threshold` _(float, default=0.6)_: Minimum confidence score for visualization.
---
## Contributing
We welcome contributions to enhance the library! Feel free to:
- Submit bug reports or feature requests.
- Fork the repository and create a pull request.
---
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
---
## Acknowledgments
- Based on the RetinaFace model for face detection ([https://github.com/yakhyo/retinaface-pytorch](https://github.com/yakhyo/retinaface-pytorch)).
- Inspired by InsightFace and other face detection projects.
---
Raw data
{
"_id": null,
"home_page": "https://github.com/yakhyo/uniface",
"name": "uniface",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "face detection, face recognition, facial landmark, facial attribute, onnx, opencv, retinaface",
"author": "Yakhyokhuja Valikhujaev",
"author_email": "yakhyo9696@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/3a/be/b6486f9b14a1fa88e14e895ccf01f521c98cd851d058d090de25a51a264c/uniface-0.1.5.tar.gz",
"platform": null,
"description": "# UniFace: All-in-One Face Analysis Library\n\n\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n![Python](https://img.shields.io/badge/Python-3.8%2B-blue)\n[![PyPI Version](https://img.shields.io/pypi/v/uniface.svg)](https://pypi.org/project/uniface/)\n[![Build Status](https://github.com/yakhyo/uniface/actions/workflows/build.yml/badge.svg)](https://github.com/yakhyo/uniface/actions)\n[![GitHub Repository](https://img.shields.io/badge/GitHub-Repository-blue?logo=github)](https://github.com/yakhyo/uniface)\n[![Downloads](https://pepy.tech/badge/uniface)](https://pepy.tech/project/uniface)\n[![Code Style: PEP8](https://img.shields.io/badge/code%20style-PEP8-green.svg)](https://www.python.org/dev/peps/pep-0008/)\n[![GitHub Release Downloads](https://img.shields.io/github/downloads/yakhyo/uniface/total.svg?label=Model%20Downloads)](https://github.com/yakhyo/uniface/releases)\n\n\n**uniface** is a lightweight face detection library designed for high-performance face localization, landmark detection and face alignment. The library supports ONNX models and provides utilities for bounding box visualization and landmark plotting. To train RetinaFace model, see https://github.com/yakhyo/retinaface-pytorch.\n\n---\n\n## Features\n\n- [ ] Age and gender detection (Planned).\n- [ ] Face recognition (Planned).\n- [x] Face Alignment (Added: 2024-11-21).\n- [x] High-speed face detection using ONNX models (Added: 2024-11-20).\n- [x] Accurate facial landmark localization (e.g., eyes, nose, and mouth) (Added: 2024-11-20).\n- [x] Easy-to-use API for inference and visualization (Added: 2024-11-20).\n\n---\n\n## Installation\n\nThe easiest way to install **UniFace** is via [PyPI](https://pypi.org/project/uniface/). This will automatically install the library along with its prerequisites.\n\n```bash\npip install uniface\n```\n\nTo work with the latest version of **UniFace**, which may not yet be released on PyPI, you can install it directly from the repository:\n\n```bash\ngit clone https://github.com/yakhyo/uniface.git\ncd uniface\npip install .\n```\n\n---\n\n## Quick Start\n\nTo get started with face detection using **UniFace**, check out the [example notebook](examples/face_detection.ipynb).\nIt demonstrates how to initialize the model, run inference, and visualize the results.\n\n---\n\n## Examples\n\nExplore the following example notebooks to learn how to use **UniFace** effectively:\n\n- [Face Detection](examples/face_detection.ipynb): Demonstrates how to perform face detection, draw bounding boxes, and landmarks on an image.\n- [Face Alignment](examples/face_alignment.ipynb): Shows how to align faces using detected landmarks.\n- [Age and Gender Detection](examples/age_gender.ipynb): Example for detecting age and gender from faces. (underdevelopment)\n\n### Initialize the Model\n\n```python\nfrom uniface import RetinaFace\n\n# Initialize the RetinaFace model\nuniface_inference = RetinaFace(\n model=\"retinaface_mnet_v2\", # Model name\n conf_thresh=0.5, # Confidence threshold\n pre_nms_topk=5000, # Pre-NMS Top-K detections\n nms_thresh=0.4, # NMS IoU threshold\n post_nms_topk=750, # Post-NMS Top-K detections\n dynamic_size=False, # Arbitrary image size inference\n input_size=(640, 640) # Pre-defined input image size\n)\n```\n\n### Run Inference\n\nInference on image:\n\n```python\nimport cv2\nfrom uniface.visualization import draw_detections\n\n# Load an image\nimage_path = \"assets/test.jpg\"\noriginal_image = cv2.imread(image_path)\n\n# Perform inference\nboxes, landmarks = uniface_inference.detect(original_image)\n\n# Visualize results\ndraw_detections(original_image, (boxes, landmarks), vis_threshold=0.6)\n\n# Save the output image\noutput_path = \"output.jpg\"\ncv2.imwrite(output_path, original_image)\nprint(f\"Saved output image to {output_path}\")\n```\n\nInference on video:\n\n```python\nimport cv2\nfrom uniface.visualization import draw_detections\n\n# Initialize the webcam\ncap = cv2.VideoCapture(0)\n\nif not cap.isOpened():\n print(\"Error: Unable to access the webcam.\")\n exit()\n\nwhile True:\n # Capture a frame from the webcam\n ret, frame = cap.read()\n if not ret:\n print(\"Error: Failed to read frame.\")\n break\n\n # Perform inference\n boxes, landmarks = uniface_inference.detect(frame)\n\n # Draw detections on the frame\n draw_detections(frame, (boxes, landmarks), vis_threshold=0.6)\n\n # Display the output\n cv2.imshow(\"Webcam Inference\", frame)\n\n # Exit if 'q' is pressed\n if cv2.waitKey(1) & 0xFF == ord('q'):\n break\n\n# Release the webcam and close all OpenCV windows\ncap.release()\ncv2.destroyAllWindows()\n```\n\n---\n\n### Evaluation results of available models on WiderFace\n\n| RetinaFace Models | Easy | Medium | Hard |\n| ------------------ | ---------- | ---------- | ---------- |\n| retinaface_mnet025 | 88.48% | 87.02% | 80.61% |\n| retinaface_mnet050 | 89.42% | 87.97% | 82.40% |\n| retinaface_mnet_v1 | 90.59% | 89.14% | 84.13% |\n| retinaface_mnet_v2 | 91.70% | 91.03% | 86.60% |\n| retinaface_r18 | 92.50% | 91.02% | 86.63% |\n| retinaface_r34 | **94.16%** | **93.12%** | **88.90%** |\n\n## API Reference\n\n### `RetinaFace` Class\n\n#### Initialization\n\n```python\nfrom typings import Tuple\n\nRetinaFace(\n model: str,\n conf_thresh: float = 0.5,\n pre_nms_topk: int = 5000,\n nms_thresh: float = 0.4,\n post_nms_topk: int = 750,\n dynamic_size: bool = False,\n input_size: Tuple[int, int] = (640, 640)\n)\n```\n\n**Parameters**:\n\n- `model` _(str)_: Name of the model to use. Supported models:\n - `retinaface_mnet025`, `retinaface_mnet050`, `retinaface_mnet_v1`, `retinaface_mnet_v2`\n - `retinaface_r18`, `retinaface_r34`\n- `conf_thresh` _(float, default=0.5)_: Minimum confidence score for detections.\n- `pre_nms_topk` _(int, default=5000)_: Max detections to keep before NMS.\n- `nms_thresh` _(float, default=0.4)_: IoU threshold for Non-Maximum Suppression.\n- `post_nms_topk` _(int, default=750)_: Max detections to keep after NMS.\n- `dynamic_size` _(Optional[bool], default=False)_: Use dynamic input size.\n- `input_size` _(Optional[Tuple[int, int]], default=(640, 640))_: Static input size for the model (width, height).\n\n---\n\n### `detect` Method\n\n```python\ndetect(\n image: np.ndarray,\n max_num: int = 0,\n metric: str = \"default\",\n center_weight: float = 2.0\n) -> Tuple[np.ndarray, np.ndarray]\n```\n\n**Description**:\nDetects faces in the given image and returns bounding boxes and landmarks.\n\n**Parameters**:\n\n- `image` _(np.ndarray)_: Input image in BGR format.\n- `max_num` _(int, default=0)_: Maximum number of faces to return. `0` means return all.\n- `metric` _(str, default=\"default\")_: Metric for prioritizing detections:\n - `\"default\"`: Prioritize detections closer to the image center.\n - `\"max\"`: Prioritize larger bounding box areas.\n- `center_weight` _(float, default=2.0)_: Weight for prioritizing center-aligned faces.\n\n**Returns**:\n\n- `bounding_boxes` _(np.ndarray)_: Array of detections as `[x_min, y_min, x_max, y_max, confidence]`.\n- `landmarks` _(np.ndarray)_: Array of landmarks as `[(x1, y1), ..., (x5, y5)]`.\n\n---\n\n### Visualization Utilities\n\n#### `draw_detections`\n\n```python\ndraw_detections(\n image: np.ndarray,\n detections: Tuple[np.ndarray, np.ndarray],\n vis_threshold: float = 0.6\n) -> None\n```\n\n**Description**:\nDraws bounding boxes and landmarks on the given image.\n\n**Parameters**:\n\n- `image` _(np.ndarray)_: The input image in BGR format.\n- `detections` _(Tuple[np.ndarray, np.ndarray])_: A tuple of bounding boxes and landmarks.\n- `vis_threshold` _(float, default=0.6)_: Minimum confidence score for visualization.\n\n---\n\n## Contributing\n\nWe welcome contributions to enhance the library! Feel free to:\n\n- Submit bug reports or feature requests.\n- Fork the repository and create a pull request.\n\n---\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n---\n\n## Acknowledgments\n\n- Based on the RetinaFace model for face detection ([https://github.com/yakhyo/retinaface-pytorch](https://github.com/yakhyo/retinaface-pytorch)).\n- Inspired by InsightFace and other face detection projects.\n\n---\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "UniFace: A Comprehensive Library for Face Detection, Recognition, Landmark Analysis, Age, and Gender Detection",
"version": "0.1.5",
"project_urls": {
"Homepage": "https://github.com/yakhyo/uniface"
},
"split_keywords": [
"face detection",
" face recognition",
" facial landmark",
" facial attribute",
" onnx",
" opencv",
" retinaface"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b9666f5f747783c93b357ea29b45ca869b1149bcf2098aca1d15f0a6ac9deade",
"md5": "658aea38c70551035b26e37973746ec2",
"sha256": "1b9587a5a4d227d51ea9e0f67e700d9216c376c67a96e77d11de1bbff2252798"
},
"downloads": -1,
"filename": "uniface-0.1.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "658aea38c70551035b26e37973746ec2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 16198,
"upload_time": "2024-11-23T10:30:20",
"upload_time_iso_8601": "2024-11-23T10:30:20.176100Z",
"url": "https://files.pythonhosted.org/packages/b9/66/6f5f747783c93b357ea29b45ca869b1149bcf2098aca1d15f0a6ac9deade/uniface-0.1.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3abeb6486f9b14a1fa88e14e895ccf01f521c98cd851d058d090de25a51a264c",
"md5": "d08559289415ace14b803e3c844e0c5c",
"sha256": "f1394dfbef97b942c590819e473b2e1de7ab23964c3495b8c209fdf1b81c5360"
},
"downloads": -1,
"filename": "uniface-0.1.5.tar.gz",
"has_sig": false,
"md5_digest": "d08559289415ace14b803e3c844e0c5c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 17426,
"upload_time": "2024-11-23T10:30:21",
"upload_time_iso_8601": "2024-11-23T10:30:21.784005Z",
"url": "https://files.pythonhosted.org/packages/3a/be/b6486f9b14a1fa88e14e895ccf01f521c98cd851d058d090de25a51a264c/uniface-0.1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-23 10:30:21",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yakhyo",
"github_project": "uniface",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "uniface"
}