uniface

UniFace: All-in-One Face Analysis Library

License Python PyPI Version Build Status GitHub Repository Downloads Code Style: PEP8 GitHub Release Downloads

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

Date Feature Description
Planned 🎭 Age and Gender Detection: Planned feature for predicting age and gender from facial images.
Planned 🧩 Face Recognition: Upcoming capability to identify and verify faces.
2024-11-21 πŸ”„ Face Alignment: Added precise face alignment for better downstream tasks.
2024-11-20 ⚑ High-Speed Face Detection: ONNX model integration for faster and efficient face detection.
2024-11-20 🎯 Facial Landmark Localization: Accurate detection of key facial features like eyes, nose, and mouth.
2024-11-20 πŸ›  API for Inference and Visualization: Simplified API for seamless inference and visual results generation.

Installation

The easiest way to install UniFace is via PyPI. This will automatically install the library along with its prerequisites.

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:

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. 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:

Initialize the Model

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:

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:

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

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:


detect Method

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:

Returns:


Visualization Utilities

draw_detections

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:


Contributing

We welcome contributions to enhance the library! Feel free to:


License

This project is licensed under the MIT License. See the LICENSE file for details.


Acknowledgments