File size: 2,946 Bytes
892fa81 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | """Unit tests for cores.face — box conversions, embedding distance, matching."""
from __future__ import annotations
import numpy as np
from cores.face import (
xywh_to_xyxy, xyxy_to_xywh, xywh_to_face_recognition_tuple,
cosine_similarity, euclidean_distance, best_match,
)
class TestBoxConversions:
def test_xywh_to_xyxy(self):
assert xywh_to_xyxy(10, 20, 100, 50) == (10, 20, 110, 70)
def test_xyxy_to_xywh(self):
assert xyxy_to_xywh(10, 20, 110, 70) == (10, 20, 100, 50)
def test_face_recognition_tuple(self):
# face_recognition uses (top, right, bottom, left)
assert xywh_to_face_recognition_tuple(10, 20, 100, 50) == (20, 110, 70, 10)
class TestEmbeddingDistance:
def test_cosine_similarity_identical(self):
v = np.array([1.0, 2.0, 3.0])
assert cosine_similarity(v, v) == pytest.approx(1.0) if (pytest := __import__("pytest")) else True
def test_cosine_similarity_orthogonal(self):
a = np.array([1.0, 0.0])
b = np.array([0.0, 1.0])
assert cosine_similarity(a, b) == 0.0
def test_cosine_similarity_zero_vector(self):
a = np.zeros(3)
b = np.array([1.0, 2.0, 3.0])
assert cosine_similarity(a, b) == 0.0
def test_euclidean_distance_identical(self):
v = np.array([1.0, 2.0, 3.0])
assert euclidean_distance(v, v) == 0.0
def test_euclidean_distance_known(self):
a = np.array([0.0, 0.0])
b = np.array([3.0, 4.0])
assert euclidean_distance(a, b) == 5.0
class TestBestMatch:
def test_empty_gallery_returns_none(self):
name, score, all_scores = best_match(np.zeros(128), {})
assert name is None
assert all_scores == {}
def test_finds_best_match_cosine(self):
query = np.array([1.0, 0.0, 0.0])
gallery = {
"alice": [np.array([0.95, 0.05, 0.0])], # close to query
"bob": [np.array([0.0, 1.0, 0.0])], # orthogonal
}
name, score, all_scores = best_match(query, gallery, metric="cosine")
assert name == "alice"
assert score > 0.9
assert "alice" in all_scores
assert "bob" in all_scores
assert all_scores["alice"] > all_scores["bob"]
def test_finds_best_match_euclidean(self):
query = np.array([0.0, 0.0, 0.0])
gallery = {
"near": [np.array([1.0, 0.0, 0.0])], # distance 1
"far": [np.array([5.0, 5.0, 5.0])], # distance ~8.66
}
name, score, all_scores = best_match(query, gallery, metric="euclidean")
assert name == "near"
assert score == 1.0
assert all_scores["near"] < all_scores["far"]
def test_handles_empty_person_embeddings(self):
query = np.array([1.0, 0.0])
gallery = {"empty_person": []}
name, score, all_scores = best_match(query, gallery)
assert name is None
assert all_scores == {}
|