AhmedAdamu commited on
Commit
324cf79
·
verified ·
1 Parent(s): 200e338

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -17
app.py CHANGED
@@ -1,11 +1,10 @@
1
- # SecureFace ID – FINAL VERSION THAT WORKS EVERYWHERE (Nov 2025)
2
-
3
  import os
4
  import cv2
5
  import numpy as np
6
  import gradio as gr
7
  from ultralytics import YOLO
8
- from huggingface_hub import hf_hub_download # ← fixed import
9
  import insightface
10
  from insightface.app import FaceAnalysis
11
  import faiss
@@ -16,18 +15,15 @@ KNOWN_EMBS_PATH = "known_embeddings.npy"
16
  KNOWN_NAMES_PATH = "known_names.npy"
17
 
18
  # ==================== MODELS ====================
19
- # YOLOv8 face detector – auto-downloaded first run
20
  model_path = hf_hub_download(
21
  repo_id="arnabdhar/YOLOv8-Face-Detection",
22
  filename="model.pt"
23
  )
24
  detector = YOLO(model_path)
25
 
26
- # InsightFace buffalo_l (best model 2025)
27
  recognizer = FaceAnalysis(name='buffalo_l', providers=['CPUExecutionProvider'])
28
  recognizer.prepare(ctx_id=0, det_size=(640, 640))
29
 
30
- # Tracker + FAISS index
31
  tracker = DeepSort(max_age=30, n_init=3, max_cosine_distance=0.4, embedder_gpu=False)
32
  index = faiss.IndexHNSWFlat(512, 32)
33
  index.hnsw.efSearch = 16
@@ -35,18 +31,18 @@ known_names = []
35
  unknown_counter = 0
36
  track_to_label = {}
37
 
38
- # Load existing database at startup
39
  if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
40
  embs = np.load(KNOWN_EMBS_PATH)
41
  known_names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
42
  index.add(embs.astype('float32'))
43
  print(f"Loaded {len(known_names)} people")
44
 
45
- # ==================== PROCESS FRAME ====================
46
  def process_frame(frame, blur_type="gaussian", intensity=40, expand=1.3, show_labels=True):
47
  global unknown_counter, track_to_label
48
 
49
- img = frame.copy()
50
  h, w = img.shape[:2]
51
  results = detector(img, conf=0.4)[0]
52
 
@@ -70,12 +66,16 @@ def process_frame(frame, blur_type="gaussian", intensity=40, expand=1.3, show_la
70
  tid = track.track_id
71
 
72
  if tid not in track_to_label or track.time_since_update % 15 == 0:
73
- faces = recognizer.get(crop, max_num=1)
 
 
74
  name = "Unknown"
75
  if faces and index.ntotal > 0:
76
  emb = faces[0].normed_embedding.reshape(1, -1).astype('float32')
77
  D, I = index.search(emb, 1)
78
- if D[0][0] < 0.45:
 
 
79
  name = known_names[I[0][0]]
80
 
81
  if name == "Unknown":
@@ -88,7 +88,7 @@ def process_frame(frame, blur_type="gaussian", intensity=40, expand=1.3, show_la
88
 
89
  label = track_to_label[tid]
90
 
91
- # Blur face
92
  face = img[y1:y2, x1:x2]
93
  if blur_type == "gaussian":
94
  k = max(15, int(min(x2-x1, y2-y1) * intensity / 100) | 1)
@@ -106,20 +106,22 @@ def process_frame(frame, blur_type="gaussian", intensity=40, expand=1.3, show_la
106
 
107
  return img
108
 
109
- # ==================== ENROLL ====================
110
  def enroll_person(name, face_image):
111
  global index, known_names
112
 
113
  if face_image is None or name.strip() == "":
114
  return "Add name + photo"
115
 
116
- faces = recognizer.get(face_image, max_num=1)
 
 
117
  if not faces:
118
- return "No face detected – try again"
119
 
120
  new_emb = faces[0].normed_embedding.reshape(1, 512)
121
 
122
- # Load or create database
123
  if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
124
  embs = np.load(KNOWN_EMBS_PATH)
125
  names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
@@ -130,13 +132,13 @@ def enroll_person(name, face_image):
130
  embs = np.vstack([embs, new_emb])
131
  names.append(name)
132
 
133
- # Save & update index
134
  np.save(KNOWN_EMBS_PATH, embs)
135
  np.save(KNOWN_NAMES_PATH, np.array(names))
136
  index.reset()
137
  index.add(embs.astype('float32'))
138
  known_names = names
139
 
 
140
  return f"**{name}** enrolled successfully!"
141
 
142
  # ==================== UI ====================
 
1
+ # SecureFace ID – DEBUG & FIXED VERSION (Threshold 0.6 + Logging)
 
2
  import os
3
  import cv2
4
  import numpy as np
5
  import gradio as gr
6
  from ultralytics import YOLO
7
+ from huggingface_hub import hf_hub_download
8
  import insightface
9
  from insightface.app import FaceAnalysis
10
  import faiss
 
15
  KNOWN_NAMES_PATH = "known_names.npy"
16
 
17
  # ==================== MODELS ====================
 
18
  model_path = hf_hub_download(
19
  repo_id="arnabdhar/YOLOv8-Face-Detection",
20
  filename="model.pt"
21
  )
22
  detector = YOLO(model_path)
23
 
 
24
  recognizer = FaceAnalysis(name='buffalo_l', providers=['CPUExecutionProvider'])
25
  recognizer.prepare(ctx_id=0, det_size=(640, 640))
26
 
 
27
  tracker = DeepSort(max_age=30, n_init=3, max_cosine_distance=0.4, embedder_gpu=False)
28
  index = faiss.IndexHNSWFlat(512, 32)
29
  index.hnsw.efSearch = 16
 
31
  unknown_counter = 0
32
  track_to_label = {}
33
 
34
+ # Load database at startup
35
  if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
36
  embs = np.load(KNOWN_EMBS_PATH)
37
  known_names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
38
  index.add(embs.astype('float32'))
39
  print(f"Loaded {len(known_names)} people")
40
 
41
+ # ==================== PROCESS FRAME (WITH DEBUG LOGGING) ====================
42
  def process_frame(frame, blur_type="gaussian", intensity=40, expand=1.3, show_labels=True):
43
  global unknown_counter, track_to_label
44
 
45
+ img = frame.copy() # Gradio gives RGB
46
  h, w = img.shape[:2]
47
  results = detector(img, conf=0.4)[0]
48
 
 
66
  tid = track.track_id
67
 
68
  if tid not in track_to_label or track.time_since_update % 15 == 0:
69
+ # Convert to BGR for InsightFace (if needed)
70
+ crop_bgr = cv2.cvtColor(crop, cv2.COLOR_RGB2BGR)
71
+ faces = recognizer.get(crop_bgr, max_num=1)
72
  name = "Unknown"
73
  if faces and index.ntotal > 0:
74
  emb = faces[0].normed_embedding.reshape(1, -1).astype('float32')
75
  D, I = index.search(emb, 1)
76
+ distance = D[0][0]
77
+ print(f"DEBUG: Distance = {distance:.3f} for potential match to index {I[0][0]} ({known_names[I[0][0]] if I[0][0] < len(known_names) else 'invalid'})")
78
+ if distance < 0.6: # ← FIXED: More lenient threshold
79
  name = known_names[I[0][0]]
80
 
81
  if name == "Unknown":
 
88
 
89
  label = track_to_label[tid]
90
 
91
+ # Blur
92
  face = img[y1:y2, x1:x2]
93
  if blur_type == "gaussian":
94
  k = max(15, int(min(x2-x1, y2-y1) * intensity / 100) | 1)
 
106
 
107
  return img
108
 
109
+ # ==================== ENROLL (SAME PREPROCESSING) ====================
110
  def enroll_person(name, face_image):
111
  global index, known_names
112
 
113
  if face_image is None or name.strip() == "":
114
  return "Add name + photo"
115
 
116
+ # Convert to BGR for consistency
117
+ face_bgr = cv2.cvtColor(face_image, cv2.COLOR_RGB2BGR)
118
+ faces = recognizer.get(face_bgr, max_num=1)
119
  if not faces:
120
+ return "No face detected"
121
 
122
  new_emb = faces[0].normed_embedding.reshape(1, 512)
123
 
124
+ # Load or create
125
  if os.path.exists(KNOWN_EMBS_PATH) and os.path.getsize(KNOWN_EMBS_PATH) > 0:
126
  embs = np.load(KNOWN_EMBS_PATH)
127
  names = np.load(KNOWN_NAMES_PATH, allow_pickle=True).tolist()
 
132
  embs = np.vstack([embs, new_emb])
133
  names.append(name)
134
 
 
135
  np.save(KNOWN_EMBS_PATH, embs)
136
  np.save(KNOWN_NAMES_PATH, np.array(names))
137
  index.reset()
138
  index.add(embs.astype('float32'))
139
  known_names = names
140
 
141
+ print(f"ENROLL DEBUG: Added {name} with embedding shape {new_emb.shape}")
142
  return f"**{name}** enrolled successfully!"
143
 
144
  # ==================== UI ====================