vrfefavr commited on
Commit
cdc4788
·
verified ·
1 Parent(s): e0d48a6

Update services/vision.py

Browse files
Files changed (1) hide show
  1. services/vision.py +27 -33
services/vision.py CHANGED
@@ -2,21 +2,17 @@ import cv2
2
  import os
3
  import time
4
  from deepface import DeepFace
5
- from core.config import DETECTOR, MODELS, THRESHOLDS, MIN_FACE_AREA
6
 
7
  def process_frame_synchronous(frame):
8
  """
9
- The Hard-Logic Pipeline:
10
- 1. Detects all faces.
11
- 2. Filters by quality.
12
- 3. Identifies every face with a confidence score.
13
- 4. Returns a complete report BEFORE the next frame is allowed.
14
  """
15
  report = []
16
  pipeline_status = {"detected": 0, "identified": 0}
17
 
18
  try:
19
- # Phase 1: Harvester (Detection)
20
  raw_faces = DeepFace.extract_faces(img_path=frame, detector_backend=DETECTOR, enforce_detection=True, align=True)
21
  pipeline_status["detected"] = len(raw_faces)
22
 
@@ -24,17 +20,13 @@ def process_frame_synchronous(frame):
24
  region = face_obj.get('facial_area', {})
25
  w, h = region.get('w', 0), region.get('h', 0)
26
 
27
- # Quality Gate
28
  if (w * h) < MIN_FACE_AREA:
29
  continue
30
 
31
  x, y = region.get('x', 0), region.get('y', 0)
32
  cropped_face = frame[y:y+h, x:x+w]
33
-
34
- if cropped_face.size == 0:
35
- continue
36
 
37
- # Phase 2: Interrogator (Consensus Engine)
38
  predictions = {}
39
  confidences = {}
40
 
@@ -48,35 +40,37 @@ def process_frame_synchronous(frame):
48
  best_match = df.iloc[0]
49
  dist = best_match["distance"]
50
 
51
- if dist < THRESHOLDS[model]:
52
- name = os.path.basename(best_match['identity']).split('.')[0]
53
- predictions[model] = name
54
- # Calculate mathematical confidence percentage
55
- # Distance 0 = 100%, Distance 1.0 = 0%
56
- conf = round((1.0 - dist) * 100, 1)
57
- confidences[model] = conf
58
- else:
59
- predictions[model] = None
60
  else:
61
- predictions[model] = None
 
62
 
63
- # Consensus Check
64
- names_found = list(predictions.values())
65
- if None not in names_found and len(set(names_found)) == 1:
66
- # Both models agree!
67
- confirmed_name = names_found[0]
68
- # Use the primary model (ArcFace) confidence for the report
69
- score = confidences.get("ArcFace", 0)
70
- report.append({"name": confirmed_name, "confidence": score})
 
 
71
  pipeline_status["identified"] += 1
72
  else:
73
- # Disagreement or unknown
74
- report.append({"name": "Unknown", "confidence": 0})
 
 
75
 
76
  return report, pipeline_status
77
 
78
  except ValueError:
79
- return [], pipeline_status # No faces found
80
  except Exception as e:
81
  print(f"🔴 Critical Pipeline Error: {e}")
82
  return [], pipeline_status
 
2
  import os
3
  import time
4
  from deepface import DeepFace
5
+ from core.config import DETECTOR, MODELS, THRESHOLDS, MIN_FACE_AREA, REQUIRED_AVERAGE_CONFIDENCE
6
 
7
  def process_frame_synchronous(frame):
8
  """
9
+ The Smart-Hard Pipeline:
10
+ Calculates weighted average across models and returns failure details.
 
 
 
11
  """
12
  report = []
13
  pipeline_status = {"detected": 0, "identified": 0}
14
 
15
  try:
 
16
  raw_faces = DeepFace.extract_faces(img_path=frame, detector_backend=DETECTOR, enforce_detection=True, align=True)
17
  pipeline_status["detected"] = len(raw_faces)
18
 
 
20
  region = face_obj.get('facial_area', {})
21
  w, h = region.get('w', 0), region.get('h', 0)
22
 
 
23
  if (w * h) < MIN_FACE_AREA:
24
  continue
25
 
26
  x, y = region.get('x', 0), region.get('y', 0)
27
  cropped_face = frame[y:y+h, x:x+w]
28
+ if cropped_face.size == 0: continue
 
 
29
 
 
30
  predictions = {}
31
  confidences = {}
32
 
 
40
  best_match = df.iloc[0]
41
  dist = best_match["distance"]
42
 
43
+ # Convert distance to confidence (0.0 distance = 100%)
44
+ conf = round((1.0 - dist) * 100, 1)
45
+ name = os.path.basename(best_match['identity']).split('.')[0]
46
+
47
+ predictions[model] = name
48
+ confidences[model] = conf
 
 
 
49
  else:
50
+ predictions[model] = "Unknown"
51
+ confidences[model] = 0.0
52
 
53
+ # --- SMART CONSENSUS LOGIC ---
54
+ # 1. Check if they agree on the NAME
55
+ all_names = [n for n in predictions.values() if n != "Unknown"]
56
+ unique_names = set(all_names)
57
+
58
+ avg_conf = sum(confidences.values()) / len(MODELS)
59
+
60
+ if len(unique_names) == 1 and avg_conf >= REQUIRED_AVERAGE_CONFIDENCE:
61
+ confirmed_name = all_names[0]
62
+ report.append({"status": "match", "name": confirmed_name, "score": avg_conf})
63
  pipeline_status["identified"] += 1
64
  else:
65
+ # Failure Report: Tell the user WHO we thought it was and WHAT the score was
66
+ best_guess = "Unknown"
67
+ if unique_names: best_guess = list(unique_names)[0]
68
+ report.append({"status": "fail", "name": best_guess, "score": avg_conf})
69
 
70
  return report, pipeline_status
71
 
72
  except ValueError:
73
+ return [], pipeline_status
74
  except Exception as e:
75
  print(f"🔴 Critical Pipeline Error: {e}")
76
  return [], pipeline_status