anupamdutta279 commited on
Commit
77f55d7
·
verified ·
1 Parent(s): 1c9c796

testing of fix

Browse files
Files changed (1) hide show
  1. app.py +93 -84
app.py CHANGED
@@ -5,6 +5,8 @@ from fastapi.responses import JSONResponse
5
  import base64
6
  import json
7
  import logging
 
 
8
  import cv2
9
  import numpy as np
10
  import requests
@@ -24,35 +26,48 @@ def log_event(event_type: str, **fields):
24
  payload = {"event": event_type, **fields}
25
  logger.error(json.dumps(payload, default=str))
26
 
27
- def load_image(source: str):
 
 
 
 
 
 
 
28
  """
29
- Load an image from a URL, base64 data URI, or local file path into a numpy array (BGR).
 
 
30
  """
31
- if isinstance(source, str):
32
- if source.startswith("http://") or source.startswith("https://"):
33
- # Download and decode
34
- resp = requests.get(source, headers={"User-Agent": "Mozilla/5.0"}, timeout=20)
35
- resp.raise_for_status()
36
- data = np.frombuffer(resp.content, dtype=np.uint8)
37
- img = cv2.imdecode(data, cv2.IMREAD_COLOR)
38
- if img is None:
39
- raise ValueError(f"Failed to decode image from URL: {source}")
40
- return img
41
- if source.startswith("data:image"):
42
- # data URI: data:image/<type>;base64,<payload>
43
- b64_payload = source.split(",", 1)[1] if "," in source else source
44
- binary = base64.b64decode(b64_payload)
45
- data = np.frombuffer(binary, dtype=np.uint8)
46
- img = cv2.imdecode(data, cv2.IMREAD_COLOR)
47
- if img is None:
48
- raise ValueError("Failed to decode image from base64 data")
49
- return img
50
- # Fallback: treat as local path
51
  img = cv2.imread(source)
52
  if img is None:
53
  raise ValueError(f"Failed to load local image: {source}")
54
- return img
55
- raise TypeError("Unsupported image source type")
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  @app.get("/")
58
  def greet_json():
@@ -66,69 +81,63 @@ def verify(v: Verify):
66
 
67
  true_count = 0
68
  print(selfie)
 
 
69
  try:
70
- selfie_img = load_image(selfie)
71
  except Exception as e:
72
  print(f"Failed to load selfie image: {e}")
73
  log_event("load_error", target="selfie", source=selfie, error=str(e))
74
  return JSONResponse(content={"verified": False, "image": None, "error": "failed_to_load_selfie"})
75
 
76
- for image in gallery:
77
- print(image)
78
- try:
79
- gallery_img = load_image(image)
80
- except Exception as e:
81
- print(f"Failed to load gallery image {image}: {e}")
82
- log_event("load_error", target="gallery", source=image, error=str(e))
83
- continue
84
- try:
85
- selfie_candidate = selfie_img.copy()
86
- gallery_candidate = gallery_img.copy()
87
- # Use a more robust detector; fall back if detection fails
88
- result = DeepFace.verify(
89
- img1_path=selfie_candidate,
90
- img2_path=gallery_candidate,
91
- detector_backend="retinaface"
92
- )
93
- if result.get("verified", False):
94
- true_count += 1
95
- if true_count >= 2:
96
- return JSONResponse(content={"verified": True, "image": image})
97
- except Exception as e:
98
- msg = str(e)
99
- print(f"DeepFace verification error for {image}: {msg}")
100
- # Retry once when DeepFace specifically fails while processing img1_path.
101
- # Re-load selfie to avoid potential in-place mutation side effects.
102
- if "img1_path" in msg:
103
- try:
104
- selfie_retry = load_image(selfie)
105
- result = DeepFace.verify(
106
- img1_path=selfie_retry,
107
- img2_path=gallery_img.copy(),
108
- detector_backend="retinaface"
109
- )
110
- if result.get("verified", False):
111
- true_count += 1
112
- if true_count >= 2:
113
- return JSONResponse(content={"verified": True, "image": image})
114
- continue
115
- except Exception as e_retry:
116
- print(f"DeepFace img1_path retry error for {image}: {e_retry}")
117
- log_event("img1_path_error", gallery_image=image, error=str(e_retry))
118
- # Optional fallback without strict detection to avoid generic img2_path errors
119
- if "Face could not be detected" in msg or "No face" in msg:
120
- log_event("face_not_detected", gallery_image=image, error=msg)
121
- try:
122
- result = DeepFace.verify(
123
- img1_path=selfie_img.copy(),
124
- img2_path=gallery_img.copy(),
125
- detector_backend="retinaface",
126
- enforce_detection=False
127
- )
128
- if result.get("verified", False):
129
- true_count += 1
130
- if true_count >= 2:
131
- return JSONResponse(content={"verified": True, "image": image})
132
- except Exception as e2:
133
- print(f"DeepFace fallback error for {image}: {e2}")
134
- return JSONResponse(content={"verified": False, "image": None})
 
5
  import base64
6
  import json
7
  import logging
8
+ import os
9
+ import tempfile
10
  import cv2
11
  import numpy as np
12
  import requests
 
26
  payload = {"event": event_type, **fields}
27
  logger.error(json.dumps(payload, default=str))
28
 
29
+ def safe_remove(path: str):
30
+ try:
31
+ os.remove(path)
32
+ except OSError:
33
+ pass
34
+
35
+
36
+ def prepare_image_for_deepface(source: str):
37
  """
38
+ Return a filesystem path DeepFace can consume reliably.
39
+ For URLs / base64 we materialize a temp file and return (path, True).
40
+ For local paths we return (path, False).
41
  """
42
+ if not isinstance(source, str):
43
+ raise TypeError("Unsupported image source type")
44
+
45
+ if source.startswith("http://") or source.startswith("https://"):
46
+ resp = requests.get(source, headers={"User-Agent": "Mozilla/5.0"}, timeout=20)
47
+ resp.raise_for_status()
48
+ binary = resp.content
49
+ elif source.startswith("data:image"):
50
+ b64_payload = source.split(",", 1)[1] if "," in source else source
51
+ binary = base64.b64decode(b64_payload)
52
+ else:
 
 
 
 
 
 
 
 
 
53
  img = cv2.imread(source)
54
  if img is None:
55
  raise ValueError(f"Failed to load local image: {source}")
56
+ return source, False
57
+
58
+ data = np.frombuffer(binary, dtype=np.uint8)
59
+ img = cv2.imdecode(data, cv2.IMREAD_COLOR)
60
+ if img is None:
61
+ raise ValueError(f"Failed to decode image: {source}")
62
+
63
+ tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg")
64
+ tmp_file_path = tmp_file.name
65
+ tmp_file.close()
66
+ wrote = cv2.imwrite(tmp_file_path, img)
67
+ if not wrote:
68
+ safe_remove(tmp_file_path)
69
+ raise ValueError(f"Failed to write temp image: {source}")
70
+ return tmp_file_path, True
71
 
72
  @app.get("/")
73
  def greet_json():
 
81
 
82
  true_count = 0
83
  print(selfie)
84
+ selfie_path = None
85
+ selfie_is_temp = False
86
  try:
87
+ selfie_path, selfie_is_temp = prepare_image_for_deepface(selfie)
88
  except Exception as e:
89
  print(f"Failed to load selfie image: {e}")
90
  log_event("load_error", target="selfie", source=selfie, error=str(e))
91
  return JSONResponse(content={"verified": False, "image": None, "error": "failed_to_load_selfie"})
92
 
93
+ try:
94
+ for image in gallery:
95
+ print(image)
96
+ gallery_path = None
97
+ gallery_is_temp = False
98
+ try:
99
+ gallery_path, gallery_is_temp = prepare_image_for_deepface(image)
100
+ except Exception as e:
101
+ print(f"Failed to load gallery image {image}: {e}")
102
+ log_event("load_error", target="gallery", source=image, error=str(e))
103
+ continue
104
+
105
+ try:
106
+ result = DeepFace.verify(
107
+ img1_path=selfie_path,
108
+ img2_path=gallery_path,
109
+ detector_backend="retinaface"
110
+ )
111
+ if result.get("verified", False):
112
+ true_count += 1
113
+ if true_count >= 2:
114
+ return JSONResponse(content={"verified": True, "image": image})
115
+ except Exception as e:
116
+ msg = str(e)
117
+ print(f"DeepFace verification error for {image}: {msg}")
118
+ if "img1_path" in msg:
119
+ log_event("img1_path_error", gallery_image=image, error=msg)
120
+ if "Face could not be detected" in msg or "No face" in msg:
121
+ log_event("face_not_detected", gallery_image=image, error=msg)
122
+ # Fallback path on generic processing or face-detection errors.
123
+ if "img1_path" in msg or "Face could not be detected" in msg or "No face" in msg:
124
+ try:
125
+ result = DeepFace.verify(
126
+ img1_path=selfie_path,
127
+ img2_path=gallery_path,
128
+ detector_backend="opencv",
129
+ enforce_detection=False
130
+ )
131
+ if result.get("verified", False):
132
+ true_count += 1
133
+ if true_count >= 2:
134
+ return JSONResponse(content={"verified": True, "image": image})
135
+ except Exception as e2:
136
+ print(f"DeepFace fallback error for {image}: {e2}")
137
+ finally:
138
+ if gallery_is_temp and gallery_path:
139
+ safe_remove(gallery_path)
140
+ return JSONResponse(content={"verified": False, "image": None})
141
+ finally:
142
+ if selfie_is_temp and selfie_path:
143
+ safe_remove(selfie_path)