-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathembedding.py
More file actions
88 lines (66 loc) · 2.51 KB
/
Copy pathembedding.py
File metadata and controls
88 lines (66 loc) · 2.51 KB
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
87
88
# =============================================================
# embedding.py — Face detection + embedding generation
#
# Uses:
# MTCNN → detect and align faces
# InceptionResnetV1 → generate 512-dim embedding vector
#
# Both models are loaded once at import time and reused
# everywhere else in the project.
# =============================================================
import torch
import numpy as np
from PIL import Image
from facenet_pytorch import MTCNN, InceptionResnetV1
import config
# Load models once — shared across the whole project
mtcnn = MTCNN(
image_size = config.IMAGE_SIZE,
device = config.DEVICE,
keep_all = True, # detect all faces in frame, not just largest
post_process= True # normalise output for InceptionResnetV1
)
facenet = InceptionResnetV1(pretrained="vggface2").eval().to(config.DEVICE)
# -------------------------------------------------------------
def _to_pil(image):
"""Convert numpy BGR (OpenCV) or PIL image to RGB PIL image."""
if isinstance(image, np.ndarray):
return Image.fromarray(image[:, :, ::-1]) # BGR → RGB
return image # already PIL
def get_single_embedding(image):
"""
Detect the first (largest) face in the image and return its embedding.
Args:
image : PIL Image or numpy BGR array
Returns:
embedding (np.ndarray, shape 512) — or None if no face found
"""
pil = _to_pil(image)
faces = mtcnn(pil) # tensor of aligned face crops, or None
if faces is None:
return None
face_tensor = faces[0].unsqueeze(0).to(config.DEVICE)
with torch.no_grad():
emb = facenet(face_tensor)
return emb.squeeze().cpu().numpy()
def get_all_embeddings(image):
"""
Detect ALL faces in an image and return an embedding for each.
Used during real-time webcam verification and group photo verification.
Args:
image : PIL Image or numpy BGR array
Returns:
embeddings (list of np.ndarray) — one per detected face
boxes (list of [x1,y1,x2,y2])— bounding boxes, same order
"""
pil = _to_pil(image)
boxes, _ = mtcnn.detect(pil)
faces = mtcnn(pil)
if faces is None or boxes is None:
return [], []
embeddings = []
with torch.no_grad():
for face in faces:
emb = facenet(face.unsqueeze(0).to(config.DEVICE))
embeddings.append(emb.squeeze().cpu().numpy())
return embeddings, boxes.tolist()