mirror of
https://github.com/yakhyo/uniface.git
synced 2025-12-30 09:02:25 +00:00
275 lines
8.4 KiB
Python
275 lines
8.4 KiB
Python
import numpy as np
|
|
import pytest
|
|
|
|
from uniface import (
|
|
create_detector,
|
|
create_landmarker,
|
|
create_recognizer,
|
|
detect_faces,
|
|
list_available_detectors,
|
|
)
|
|
from uniface.constants import RetinaFaceWeights, SCRFDWeights
|
|
|
|
|
|
# create_detector tests
|
|
def test_create_detector_retinaface():
|
|
"""
|
|
Test creating a RetinaFace detector using factory function.
|
|
"""
|
|
detector = create_detector("retinaface")
|
|
assert detector is not None, "Failed to create RetinaFace detector"
|
|
|
|
|
|
def test_create_detector_scrfd():
|
|
"""
|
|
Test creating a SCRFD detector using factory function.
|
|
"""
|
|
detector = create_detector("scrfd")
|
|
assert detector is not None, "Failed to create SCRFD detector"
|
|
|
|
|
|
def test_create_detector_with_config():
|
|
"""
|
|
Test creating detector with custom configuration.
|
|
"""
|
|
detector = create_detector(
|
|
"retinaface",
|
|
model_name=RetinaFaceWeights.MNET_V2,
|
|
conf_thresh=0.8,
|
|
nms_thresh=0.3,
|
|
)
|
|
assert detector is not None, "Failed to create detector with custom config"
|
|
|
|
|
|
def test_create_detector_invalid_method():
|
|
"""
|
|
Test that invalid detector method raises an error.
|
|
"""
|
|
with pytest.raises((ValueError, KeyError)):
|
|
create_detector("invalid_method")
|
|
|
|
|
|
def test_create_detector_scrfd_with_model():
|
|
"""
|
|
Test creating SCRFD detector with specific model.
|
|
"""
|
|
detector = create_detector("scrfd", model_name=SCRFDWeights.SCRFD_10G_KPS, conf_thresh=0.5)
|
|
assert detector is not None, "Failed to create SCRFD with specific model"
|
|
|
|
|
|
# create_recognizer tests
|
|
def test_create_recognizer_arcface():
|
|
"""
|
|
Test creating an ArcFace recognizer using factory function.
|
|
"""
|
|
recognizer = create_recognizer("arcface")
|
|
assert recognizer is not None, "Failed to create ArcFace recognizer"
|
|
|
|
|
|
def test_create_recognizer_mobileface():
|
|
"""
|
|
Test creating a MobileFace recognizer using factory function.
|
|
"""
|
|
recognizer = create_recognizer("mobileface")
|
|
assert recognizer is not None, "Failed to create MobileFace recognizer"
|
|
|
|
|
|
def test_create_recognizer_sphereface():
|
|
"""
|
|
Test creating a SphereFace recognizer using factory function.
|
|
"""
|
|
recognizer = create_recognizer("sphereface")
|
|
assert recognizer is not None, "Failed to create SphereFace recognizer"
|
|
|
|
|
|
def test_create_recognizer_invalid_method():
|
|
"""
|
|
Test that invalid recognizer method raises an error.
|
|
"""
|
|
with pytest.raises((ValueError, KeyError)):
|
|
create_recognizer("invalid_method")
|
|
|
|
|
|
# create_landmarker tests
|
|
def test_create_landmarker():
|
|
"""
|
|
Test creating a Landmark106 detector using factory function.
|
|
"""
|
|
landmarker = create_landmarker("2d106det")
|
|
assert landmarker is not None, "Failed to create Landmark106 detector"
|
|
|
|
|
|
def test_create_landmarker_default():
|
|
"""
|
|
Test creating landmarker with default parameters.
|
|
"""
|
|
landmarker = create_landmarker()
|
|
assert landmarker is not None, "Failed to create default landmarker"
|
|
|
|
|
|
def test_create_landmarker_invalid_method():
|
|
"""
|
|
Test that invalid landmarker method raises an error.
|
|
"""
|
|
with pytest.raises((ValueError, KeyError)):
|
|
create_landmarker("invalid_method")
|
|
|
|
|
|
# detect_faces tests
|
|
def test_detect_faces_retinaface():
|
|
"""
|
|
Test high-level detect_faces function with RetinaFace.
|
|
"""
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
faces = detect_faces(mock_image, method="retinaface")
|
|
|
|
assert isinstance(faces, list), "detect_faces should return a list"
|
|
|
|
|
|
def test_detect_faces_scrfd():
|
|
"""
|
|
Test high-level detect_faces function with SCRFD.
|
|
"""
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
faces = detect_faces(mock_image, method="scrfd")
|
|
|
|
assert isinstance(faces, list), "detect_faces should return a list"
|
|
|
|
|
|
def test_detect_faces_with_threshold():
|
|
"""
|
|
Test detect_faces with custom confidence threshold.
|
|
"""
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
faces = detect_faces(mock_image, method="retinaface", conf_thresh=0.8)
|
|
|
|
assert isinstance(faces, list), "detect_faces should return a list"
|
|
|
|
# All detections should respect threshold
|
|
for face in faces:
|
|
assert face["confidence"] >= 0.8, "All detections should meet confidence threshold"
|
|
|
|
|
|
def test_detect_faces_default_method():
|
|
"""
|
|
Test detect_faces with default method (should use retinaface).
|
|
"""
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
faces = detect_faces(mock_image) # No method specified
|
|
|
|
assert isinstance(faces, list), "detect_faces should return a list with default method"
|
|
|
|
|
|
def test_detect_faces_empty_image():
|
|
"""
|
|
Test detect_faces on a blank image.
|
|
"""
|
|
empty_image = np.zeros((640, 640, 3), dtype=np.uint8)
|
|
faces = detect_faces(empty_image, method="retinaface")
|
|
|
|
assert isinstance(faces, list), "Should return a list even for empty image"
|
|
assert len(faces) == 0, "Should detect no faces in blank image"
|
|
|
|
|
|
# list_available_detectors tests
|
|
def test_list_available_detectors():
|
|
"""
|
|
Test that list_available_detectors returns a dictionary.
|
|
"""
|
|
detectors = list_available_detectors()
|
|
|
|
assert isinstance(detectors, dict), "Should return a dictionary of detectors"
|
|
assert len(detectors) > 0, "Should have at least one detector available"
|
|
|
|
|
|
def test_list_available_detectors_contents():
|
|
"""
|
|
Test that list includes known detectors.
|
|
"""
|
|
detectors = list_available_detectors()
|
|
|
|
# Should include at least these detectors
|
|
assert "retinaface" in detectors, "Should include 'retinaface'"
|
|
assert "scrfd" in detectors, "Should include 'scrfd'"
|
|
|
|
|
|
# Integration tests
|
|
def test_detector_inference_from_factory():
|
|
"""
|
|
Test that detector created from factory can perform inference.
|
|
"""
|
|
detector = create_detector("retinaface")
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
|
|
faces = detector.detect(mock_image)
|
|
assert isinstance(faces, list), "Detector should return list of faces"
|
|
|
|
|
|
def test_recognizer_inference_from_factory():
|
|
"""
|
|
Test that recognizer created from factory can perform inference.
|
|
"""
|
|
recognizer = create_recognizer("arcface")
|
|
mock_image = np.random.randint(0, 255, (112, 112, 3), dtype=np.uint8)
|
|
|
|
embedding = recognizer.get_embedding(mock_image)
|
|
assert embedding is not None, "Recognizer should return embedding"
|
|
assert embedding.shape[1] == 512, "Should return 512-dimensional embedding"
|
|
|
|
|
|
def test_landmarker_inference_from_factory():
|
|
"""
|
|
Test that landmarker created from factory can perform inference.
|
|
"""
|
|
landmarker = create_landmarker("2d106det")
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
mock_bbox = [100, 100, 300, 300]
|
|
|
|
landmarks = landmarker.get_landmarks(mock_image, mock_bbox)
|
|
assert landmarks is not None, "Landmarker should return landmarks"
|
|
assert landmarks.shape == (106, 2), "Should return 106 landmarks"
|
|
|
|
|
|
def test_multiple_detector_creation():
|
|
"""
|
|
Test that multiple detectors can be created independently.
|
|
"""
|
|
detector1 = create_detector("retinaface")
|
|
detector2 = create_detector("scrfd")
|
|
|
|
assert detector1 is not None
|
|
assert detector2 is not None
|
|
assert detector1 is not detector2, "Should create separate instances"
|
|
|
|
|
|
def test_detector_with_different_configs():
|
|
"""
|
|
Test creating multiple detectors with different configurations.
|
|
"""
|
|
detector_high_thresh = create_detector("retinaface", conf_thresh=0.9)
|
|
detector_low_thresh = create_detector("retinaface", conf_thresh=0.3)
|
|
|
|
mock_image = np.random.randint(0, 255, (640, 640, 3), dtype=np.uint8)
|
|
|
|
faces_high = detector_high_thresh.detect(mock_image)
|
|
faces_low = detector_low_thresh.detect(mock_image)
|
|
|
|
# Both should work
|
|
assert isinstance(faces_high, list)
|
|
assert isinstance(faces_low, list)
|
|
|
|
|
|
def test_factory_returns_correct_types():
|
|
"""
|
|
Test that factory functions return instances of the correct types.
|
|
"""
|
|
from uniface import RetinaFace, ArcFace, Landmark106
|
|
|
|
detector = create_detector("retinaface")
|
|
recognizer = create_recognizer("arcface")
|
|
landmarker = create_landmarker("2d106det")
|
|
|
|
assert isinstance(detector, RetinaFace), "Should return RetinaFace instance"
|
|
assert isinstance(recognizer, ArcFace), "Should return ArcFace instance"
|
|
assert isinstance(landmarker, Landmark106), "Should return Landmark106 instance"
|