| """ |
| Face verification utilities. |
| |
| This module provides functions to compare face embeddings and decide |
| whether two faces belong to the same person. It relies on |
| ``extract_embeddings.extract_embedding`` to obtain the embeddings. |
| """ |
|
|
| from typing import Tuple, Optional |
|
|
| import numpy as np |
| from PIL import Image |
|
|
| from .extract_embeddings import extract_embedding |
|
|
|
|
| def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float: |
| """Compute the cosine similarity between two vectors. |
| |
| Parameters |
| ---------- |
| a, b: np.ndarray |
| 1D vectors of the same length. |
| |
| Returns |
| ------- |
| float |
| The cosine similarity ranging from -1 (opposite) to 1 (identical). |
| """ |
| return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))) |
|
|
|
|
| def verify_images(img1: Image.Image, img2: Image.Image, threshold: float = 0.8, device: str = "cpu") -> Tuple[Optional[float], bool, str]: |
| """Verify whether two images depict the same person. |
| |
| This function detects faces in each image, extracts embeddings and |
| computes the cosine similarity. A threshold decides whether the |
| similarity represents the same identity. |
| |
| Parameters |
| ---------- |
| img1, img2: PIL.Image.Image |
| The two images to compare. |
| threshold: float, optional |
| Similarity threshold above which the faces are considered the |
| same person. Defaults to 0.8. |
| device: str, optional |
| Device to run the embedding extraction on. Defaults to ``"cpu"``. |
| |
| Returns |
| ------- |
| Tuple[Optional[float], bool, str] |
| A tuple of (similarity score, decision, message). If no face is |
| detected in either image, the similarity is ``None`` and the |
| decision is ``False``. |
| """ |
| emb1 = extract_embedding(img1, device=device) |
| emb2 = extract_embedding(img2, device=device) |
| if emb1 is None or emb2 is None: |
| return None, False, "Face not detected in one or both images." |
| sim = cosine_similarity(emb1, emb2) |
| is_same = sim >= threshold |
| return sim, is_same, "Same person" if is_same else "Different people" |
|
|
|
|
| __all__ = ["verify_images", "cosine_similarity"] |