AhmedAdamu commited on
Commit
40856e4
Β·
verified Β·
1 Parent(s): 09f4075

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -38
app.py CHANGED
@@ -14,8 +14,11 @@ import faiss
14
  from deep_sort_realtime.deepsort_tracker import DeepSort
15
  from pathlib import Path
16
 
17
- # ==================== 1. MODELS & DATABASE ====================
18
- # Download and load face model (auto-downloads if missing)
 
 
 
19
  model_path = hf_hub_download(
20
  repo_id="arnabdhar/YOLOv8-Face-Detection",
21
  filename="model.pt",
@@ -23,31 +26,20 @@ model_path = hf_hub_download(
23
  )
24
  detector = YOLO(model_path)
25
 
26
- recognizer = FaceAnalysis(name='buffalo_l', providers=['CUDAExecutionProvider'])
27
  recognizer.prepare(ctx_id=0, det_size=(640,640))
28
 
 
 
 
 
29
 
30
- # FAISS index for known faces
31
- KNOWN_EMBS_PATH = "known_embeddings.npy"
32
- KNOWN_NAMES_PATH = "known_names.npy"
33
-
34
- index = None
35
- known_names = []
36
-
37
  if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
38
  embeddings = np.load(KNOWN_EMBS_PATH)
39
  known_names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
40
- index = faiss.IndexHNSWFlat(512, 32)
41
- index.hnsw.efSearch = 16
42
  index.add(embeddings.astype('float32'))
43
- else:
44
- index = faiss.IndexHNSWFlat(512, 32) # empty but valid index
45
- known_names = []
46
-
47
- # Tracker for persistent IDs
48
- tracker = DeepSort(max_age=30, n_init=3, max_cosine_distance=0.4, nn_budget=None, embedder_gpu=True)
49
- unknown_counter = 0
50
- track_to_label = {} # track_id β†’ "Alice" or "Unknown_003"
51
 
52
  # ==================== 2. CORE PROCESSING FUNCTION ====================
53
  def process_frame(frame: np.ndarray, blur_type: str = "gaussian", intensity: float = 30, expand: float = 1.2, show_labels: bool = True):
@@ -125,43 +117,41 @@ def process_frame(frame: np.ndarray, blur_type: str = "gaussian", intensity: flo
125
 
126
  return img
127
 
128
- # ==================== 3. ENROLLMENT FUNCTION ====================
129
  def enroll_person(name: str, face_image: np.ndarray):
130
- global index, known_names
131
-
132
  if face_image is None:
133
- return "Please upload a photo"
134
 
135
- # Get face embedding
136
  faces = recognizer.get(face_image, max_num=1)
137
  if not faces:
138
- return "No face detected – try a clearer frontal photo with good lighting"
139
 
140
- new_emb = faces[0].normed_embedding.reshape(1, 512) # shape (1,512)
141
 
142
- # === Load existing data (safely) ===
143
- if os.path.exists(KNOWN_EMBS_PATH):
144
- all_embs = np.load(KNOWN_EMBS_PATH) # shape (N,512)
145
  all_names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
146
  else:
147
  all_embs = np.empty((0, 512))
148
  all_names = []
149
 
150
- # === Append new person ===
151
  all_embs = np.vstack([all_embs, new_emb])
152
  all_names.append(name)
153
 
154
- # === Save to disk ===
155
  np.save(KNOWN_EMBS_PATH, all_embs)
156
  np.save(KNOWN_NAMES_PATH, np.array(all_names))
157
 
158
- # === Rebuild FAISS index safely ===
159
- index = faiss = faiss.IndexHNSWFlat(512, 32)
160
- index.hnsw.efSearch = 16
161
- index.add(all_embs.astype('float32')) # ← this line used to crash if all_embs was empty
162
- known_names = all_names # refresh the global list too
163
 
164
- return f"Successfully enrolled **{name}** – now instantly recognized!"
165
 
166
  # ==================== 4. GRADIO UI ====================
167
  with gr.Blocks(title="SecureFace ID – Privacy-First Recognition") as demo:
 
14
  from deep_sort_realtime.deepsort_tracker import DeepSort
15
  from pathlib import Path
16
 
17
+ # ==================== 1. MODELS & DATABASE (FIXED) ====================
18
+ from huggingface_hub import hf_hub_download
19
+ import faiss
20
+
21
+ # Download YOLO face model
22
  model_path = hf_hub_download(
23
  repo_id="arnabdhar/YOLOv8-Face-Detection",
24
  filename="model.pt",
 
26
  )
27
  detector = YOLO(model_path)
28
 
29
+ recognizer = FaceAnalysis(name='buffalo_l', providers=['CPUExecutionProvider'])
30
  recognizer.prepare(ctx_id=0, det_size=(640,640))
31
 
32
+ # ←←← THESE THREE LINES ARE CRUCIAL ←←←
33
+ index = faiss.IndexHNSWFlat(512, 32) # will stay alive forever
34
+ index.hnsw.efSearch = 16
35
+ known_names = [] # global list
36
 
37
+ # Load existing database at startup (safe)
 
 
 
 
 
 
38
  if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
39
  embeddings = np.load(KNOWN_EMBS_PATH)
40
  known_names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
 
 
41
  index.add(embeddings.astype('float32'))
42
+ print(f"Loaded {len(known_names)} known people at startup")
 
 
 
 
 
 
 
43
 
44
  # ==================== 2. CORE PROCESSING FUNCTION ====================
45
  def process_frame(frame: np.ndarray, blur_type: str = "gaussian", intensity: float = 30, expand: float = 1.2, show_labels: bool = True):
 
117
 
118
  return img
119
 
120
+ # ==================== ENROLL FUNCTION (FINAL WORKING VERSION) ====================
121
  def enroll_person(name: str, face_image: np.ndarray):
122
+ global index, known_names # ← THIS LINE WAS MISSING BEFORE!
123
+
124
  if face_image is None:
125
+ return "Upload a photo"
126
 
 
127
  faces = recognizer.get(face_image, max_num=1)
128
  if not faces:
129
+ return "No face detected – use a clear frontal photo"
130
 
131
+ new_emb = faces[0].normed_embedding.reshape(1, 512)
132
 
133
+ # Load current data
134
+ if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
135
+ all_embs = np.load(KNOWN_EMBS_PATH)
136
  all_names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
137
  else:
138
  all_embs = np.empty((0, 512))
139
  all_names = []
140
 
141
+ # Add new person
142
  all_embs = np.vstack([all_embs, new_emb])
143
  all_names.append(name)
144
 
145
+ # Save to disk
146
  np.save(KNOWN_EMBS_PATH, all_embs)
147
  np.save(KNOWN_NAMES_PATH, np.array(all_names))
148
 
149
+ # ←←← REBUILD GLOBAL INDEX (this is what makes it work instantly) ←←←
150
+ index.reset() # clear old index
151
+ index.add(all_embs.astype('float32')) # add all embeddings
152
+ known_names = all_names # update global name list
 
153
 
154
+ return f"**{name}** enrolled and now instantly recognized!"
155
 
156
  # ==================== 4. GRADIO UI ====================
157
  with gr.Blocks(title="SecureFace ID – Privacy-First Recognition") as demo: