saketh-005 commited on
Commit
20df945
·
verified ·
1 Parent(s): 8c10e13

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -15
app.py CHANGED
@@ -4,10 +4,31 @@ import cv2
4
  from ultralytics import YOLO
5
  import insightface
6
 
7
- # Load models
8
- yolo = YOLO("yolov8n.pt")
 
 
 
 
9
  face_model = insightface.app.FaceAnalysis(name="buffalo_l")
10
- face_model.prepare(ctx_id=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  def process_image(image):
13
  image_np = np.array(image)
@@ -17,41 +38,61 @@ def process_image(image):
17
  faces_output = []
18
 
19
  for r in results:
20
- for box, cls, conf in zip(r.boxes.xyxy, r.boxes.cls, r.boxes.conf):
21
 
22
- # Only detect persons
 
 
23
  if int(cls) != 0:
24
  continue
25
- if conf < 0.4:
 
26
  continue
27
 
28
  xmin, ymin, xmax, ymax = box.cpu().numpy()
29
  xmin, ymin, xmax, ymax = map(int, [xmin, ymin, xmax, ymax])
30
 
 
 
 
 
 
 
 
31
  person_crop = image_np[ymin:ymax, xmin:xmax]
32
 
 
 
 
 
33
  detected_faces = face_model.get(person_crop)
34
 
35
  for face in detected_faces:
36
- embedding = face.embedding.tolist()
37
 
38
- cx = (xmin + xmax) / 2
39
- cy = (ymin + ymax) / 2
40
 
41
  faces_output.append({
42
- "cx": float(cx),
43
- "cy": float(cy),
 
44
  "box": {
45
- "xmin": xmin,
46
- "ymin": ymin,
47
- "xmax": xmax,
48
- "ymax": ymax
49
  },
50
  "embedding": embedding
51
  })
52
 
53
  return faces_output
54
 
 
 
 
 
 
55
  iface = gr.Interface(
56
  fn=process_image,
57
  inputs=gr.Image(type="pil"),
 
4
  from ultralytics import YOLO
5
  import insightface
6
 
7
+ # ----------------------------
8
+ # Load Models (CPU mode)
9
+ # ----------------------------
10
+
11
+ yolo = YOLO("yolov8n.pt") # lightweight model
12
+
13
  face_model = insightface.app.FaceAnalysis(name="buffalo_l")
14
+ face_model.prepare(ctx_id=-1) # -1 forces CPU (important for HF free tier)
15
+
16
+
17
+ # ----------------------------
18
+ # Utility: Normalize embedding
19
+ # ----------------------------
20
+
21
+ def normalize(vec):
22
+ vec = np.array(vec, dtype=np.float32)
23
+ norm = np.linalg.norm(vec)
24
+ if norm == 0:
25
+ return vec.tolist()
26
+ return (vec / norm).tolist()
27
+
28
+
29
+ # ----------------------------
30
+ # Main Processing Function
31
+ # ----------------------------
32
 
33
  def process_image(image):
34
  image_np = np.array(image)
 
38
  faces_output = []
39
 
40
  for r in results:
41
+ boxes = r.boxes
42
 
43
+ for box, cls, conf in zip(boxes.xyxy, boxes.cls, boxes.conf):
44
+
45
+ # YOLO class 0 = person
46
  if int(cls) != 0:
47
  continue
48
+
49
+ if float(conf) < 0.4:
50
  continue
51
 
52
  xmin, ymin, xmax, ymax = box.cpu().numpy()
53
  xmin, ymin, xmax, ymax = map(int, [xmin, ymin, xmax, ymax])
54
 
55
+ # Safety check for valid crop
56
+ h, w, _ = image_np.shape
57
+ xmin = max(0, xmin)
58
+ ymin = max(0, ymin)
59
+ xmax = min(w, xmax)
60
+ ymax = min(h, ymax)
61
+
62
  person_crop = image_np[ymin:ymax, xmin:xmax]
63
 
64
+ if person_crop.size == 0:
65
+ continue
66
+
67
+ # Detect face inside person crop
68
  detected_faces = face_model.get(person_crop)
69
 
70
  for face in detected_faces:
71
+ embedding = normalize(face.embedding)
72
 
73
+ # Adjust face bbox to original image coordinates
74
+ fxmin, fymin, fxmax, fymax = face.bbox.astype(int)
75
 
76
  faces_output.append({
77
+ "cx": float((fxmin + fxmax) / 2 + xmin),
78
+ "cy": float((fymin + fymax) / 2 + ymin),
79
+ "confidence": float(conf),
80
  "box": {
81
+ "xmin": int(fxmin + xmin),
82
+ "ymin": int(fymin + ymin),
83
+ "xmax": int(fxmax + xmin),
84
+ "ymax": int(fymax + ymin)
85
  },
86
  "embedding": embedding
87
  })
88
 
89
  return faces_output
90
 
91
+
92
+ # ----------------------------
93
+ # Gradio Interface
94
+ # ----------------------------
95
+
96
  iface = gr.Interface(
97
  fn=process_image,
98
  inputs=gr.Image(type="pil"),