File size: 2,194 Bytes
69def8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import numpy as np
from deepface import DeepFace
import os

class FaceEmbedder:
    def __init__(self, model_name="Facenet"):
        self.model_name = model_name
        # Trigger a dummy call to download/load the model if needed
        print(f"Initializing FaceEmbedder with model: {self.model_name}")
        # Note: DeepFace downloads models on first use.

    def compute_embedding(self, image_path: str) -> np.ndarray:
        if not os.path.exists(image_path):
            raise FileNotFoundError(f"Image not found: {image_path}")
            
        objs = DeepFace.represent(
            img_path=image_path, 
            model_name=self.model_name,
            enforce_detection=False,
            detector_backend="opencv",
            align=True
        )
        if not objs:
            return np.zeros(128)
            
        emb = np.array(objs[0]["embedding"], dtype=np.float32)
        return emb

    def extract_face_details(self, image_input) -> dict:
        """Extract embedding, facial bounding box, and cropped face image.
        image_input can be a file path str or numpy ndarray (BGR/RGB image).
        """
        objs = DeepFace.represent(
            img_path=image_input,
            model_name=self.model_name,
            enforce_detection=False,
            detector_backend="opencv",
            align=True
        )
        if not objs:
            return {
                "embedding": np.zeros(128, dtype=np.float32),
                "facial_area": {"x": 0, "y": 0, "w": 0, "h": 0},
                "confidence": 0.0
            }
        
        target = objs[0]
        emb = np.array(target["embedding"], dtype=np.float32)
        facial_area = target.get("facial_area", {"x": 0, "y": 0, "w": 0, "h": 0})
        
        return {
            "embedding": emb,
            "facial_area": facial_area,
            "confidence": target.get("face_confidence", 1.0)
        }

    def batch_compute_embeddings(self, image_paths: list, batch_size: int = 16) -> np.ndarray:
        embeddings = []
        for path in image_paths:
            emb = self.compute_embedding(path)
            embeddings.append(emb)
        return np.vstack(embeddings)