matrice-analytics 0.1.52__py3-none-any.whl → 0.1.54__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of matrice-analytics might be problematic. Click here for more details.
- matrice_analytics/post_processing/face_reg/embedding_manager.py +39 -6
- matrice_analytics/post_processing/face_reg/face_recognition.py +11 -15
- matrice_analytics/post_processing/face_reg/face_recognition_client.py +1 -1
- {matrice_analytics-0.1.52.dist-info → matrice_analytics-0.1.54.dist-info}/METADATA +1 -1
- {matrice_analytics-0.1.52.dist-info → matrice_analytics-0.1.54.dist-info}/RECORD +8 -8
- {matrice_analytics-0.1.52.dist-info → matrice_analytics-0.1.54.dist-info}/WHEEL +0 -0
- {matrice_analytics-0.1.52.dist-info → matrice_analytics-0.1.54.dist-info}/licenses/LICENSE.txt +0 -0
- {matrice_analytics-0.1.52.dist-info → matrice_analytics-0.1.54.dist-info}/top_level.txt +0 -0
|
@@ -181,13 +181,27 @@ class EmbeddingManager:
|
|
|
181
181
|
self.logger.info("Loading staff embeddings from API...")
|
|
182
182
|
response = await self.face_client.get_all_staff_embeddings()
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
184
|
+
# Robust response handling: accept dict with data or raw list
|
|
185
|
+
embeddings_data: List[Dict[str, Any]] = []
|
|
186
|
+
if isinstance(response, dict):
|
|
187
|
+
# Typical: { success: True, data: [...] }
|
|
188
|
+
if response.get("success", False) and isinstance(response.get("data"), list):
|
|
189
|
+
embeddings_data = response.get("data", [])
|
|
190
|
+
# Alternate: { data: [...] } without success flag
|
|
191
|
+
elif isinstance(response.get("data"), list):
|
|
192
|
+
embeddings_data = response.get("data", [])
|
|
193
|
+
# Fallback keys sometimes used
|
|
194
|
+
elif isinstance(response.get("items"), list):
|
|
195
|
+
embeddings_data = response.get("items", [])
|
|
196
|
+
else:
|
|
197
|
+
self.logger.error(f"Unexpected embeddings response shape (dict): keys={list(response.keys())}")
|
|
198
|
+
return False
|
|
199
|
+
elif isinstance(response, list):
|
|
200
|
+
# Some deployments return raw list directly
|
|
201
|
+
embeddings_data = response
|
|
202
|
+
else:
|
|
203
|
+
self.logger.error(f"Unexpected embeddings response type: {type(response)}")
|
|
186
204
|
return False
|
|
187
|
-
|
|
188
|
-
# The API response has the format: {"success": True, "data": [embedding_items]}
|
|
189
|
-
# Each item has the structure shown in the sample response
|
|
190
|
-
embeddings_data = response.get("data", [])
|
|
191
205
|
|
|
192
206
|
self.staff_embeddings = []
|
|
193
207
|
embeddings_list = []
|
|
@@ -302,6 +316,25 @@ class EmbeddingManager:
|
|
|
302
316
|
except Exception as e:
|
|
303
317
|
self.logger.error(f"Error in local similarity search: {e}", exc_info=True)
|
|
304
318
|
return None
|
|
319
|
+
|
|
320
|
+
def get_best_similarity(self, query_embedding: List[float]) -> float:
|
|
321
|
+
"""Return the best cosine similarity for debugging/observability (no threshold gating)."""
|
|
322
|
+
with self._embeddings_lock:
|
|
323
|
+
if self.embeddings_matrix is None or len(self.embedding_metadata) == 0:
|
|
324
|
+
return 0.0
|
|
325
|
+
embeddings_matrix = self.embeddings_matrix.copy() if self.embeddings_matrix is not None else None
|
|
326
|
+
if embeddings_matrix is None:
|
|
327
|
+
return 0.0
|
|
328
|
+
try:
|
|
329
|
+
query_array = np.array(query_embedding, dtype=np.float32).reshape(1, -1)
|
|
330
|
+
qn = np.linalg.norm(query_array)
|
|
331
|
+
if qn == 0:
|
|
332
|
+
return 0.0
|
|
333
|
+
query_array = query_array / qn
|
|
334
|
+
similarities = np.dot(embeddings_matrix, query_array.T).flatten()
|
|
335
|
+
return float(np.max(similarities)) if similarities.size > 0 else 0.0
|
|
336
|
+
except Exception:
|
|
337
|
+
return 0.0
|
|
305
338
|
|
|
306
339
|
def extract_embedding_from_detection(self, detection: Dict) -> Tuple[Dict, Optional[List[float]]]:
|
|
307
340
|
"""Extract and validate embedding from detection."""
|
|
@@ -178,10 +178,16 @@ class TemporalIdentityManager:
|
|
|
178
178
|
"known"
|
|
179
179
|
)
|
|
180
180
|
else:
|
|
181
|
-
# No local match found
|
|
182
|
-
|
|
181
|
+
# No local match found; log best similarity for observability
|
|
182
|
+
best_sim = 0.0
|
|
183
|
+
try:
|
|
184
|
+
best_sim = float(self.embedding_manager.get_best_similarity(emb))
|
|
185
|
+
except Exception:
|
|
186
|
+
pass
|
|
187
|
+
self.logger.debug(f"No local match found - best_similarity={best_sim:.3f}, threshold={self.threshold:.3f}")
|
|
183
188
|
print("------------------FACE RECOG TEMPORAL IDENTITY MANAGER UPDATE - COMPUTE BEST IDENTITY (LOCAL - NO MATCH)----------------------------")
|
|
184
189
|
print("LATENCY:",(time.time() - st10)*1000,"| Throughput fps:",(1.0 / (time.time() - st10)) if (time.time() - st10) > 0 else None)
|
|
190
|
+
print(f"BEST_SIM={best_sim:.3f} THRESH={self.threshold:.3f}")
|
|
185
191
|
print("------------------FACE RECOG TEMPORAL IDENTITY MANAGER UPDATE - COMPUTE BEST IDENTITY (LOCAL - NO MATCH)----------------------------")
|
|
186
192
|
|
|
187
193
|
return None, "Unknown", 0.0, None, {}, "unknown"
|
|
@@ -987,20 +993,10 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
|
|
|
987
993
|
) -> List[Dict]:
|
|
988
994
|
"""Process face recognition for each detection with embeddings"""
|
|
989
995
|
|
|
990
|
-
#
|
|
991
|
-
st0=time.time()
|
|
996
|
+
# Face client is initialized in initialize(); if absent, this indicates a prior init failure
|
|
992
997
|
if not self.face_client:
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
except Exception as e:
|
|
996
|
-
self.logger.warning(
|
|
997
|
-
f"Could not initialize face recognition client: {e}"
|
|
998
|
-
)
|
|
999
|
-
# No client available, return empty list (no results)
|
|
1000
|
-
return []
|
|
1001
|
-
print("------------------FACE RECOG CLIENT INIT----------------------------")
|
|
1002
|
-
print("LATENCY:",(time.time() - st0)*1000,"| Throughput fps:",(1.0 / (time.time() - st0)) if (time.time() - st0) > 0 else None)
|
|
1003
|
-
print("------------------FACE RECOG CLIENT INIT----------------------------")
|
|
998
|
+
self.logger.error("Face client not initialized; initialize() must succeed before processing")
|
|
999
|
+
return []
|
|
1004
1000
|
|
|
1005
1001
|
# Initialize unknown faces storage if not exists
|
|
1006
1002
|
if not hasattr(self, "unknown_faces_storage"):
|
|
@@ -568,7 +568,7 @@ class FacialRecognitionClient:
|
|
|
568
568
|
if response:
|
|
569
569
|
return response
|
|
570
570
|
else:
|
|
571
|
-
error_msg = response
|
|
571
|
+
error_msg = response #.get("error", "Unknown RPC error")
|
|
572
572
|
self.logger.error(f"RPC Error: {error_msg}", exc_info=True)
|
|
573
573
|
return {"success": False, "error": error_msg}
|
|
574
574
|
except Exception as e:
|
|
@@ -28,9 +28,9 @@ matrice_analytics/post_processing/core/config.py,sha256=uyxWndO-DE9PeGD_h5K3TeB0
|
|
|
28
28
|
matrice_analytics/post_processing/core/config_utils.py,sha256=QuAS-_JKSoNOtfUWgr7Alf_wsqODzN2rHlQu-cHRK0s,34311
|
|
29
29
|
matrice_analytics/post_processing/face_reg/__init__.py,sha256=yntaiGlW9vdjBpPZQXNuovALihJPzRlFyUE88l3MhBA,1364
|
|
30
30
|
matrice_analytics/post_processing/face_reg/compare_similarity.py,sha256=NlFc8b2a74k0PqSFAbuM_fUbA1BT3pr3VUgvSqRpJzQ,23396
|
|
31
|
-
matrice_analytics/post_processing/face_reg/embedding_manager.py,sha256=
|
|
32
|
-
matrice_analytics/post_processing/face_reg/face_recognition.py,sha256=
|
|
33
|
-
matrice_analytics/post_processing/face_reg/face_recognition_client.py,sha256=
|
|
31
|
+
matrice_analytics/post_processing/face_reg/embedding_manager.py,sha256=lt6BSRylvCzPVsKBpYBrDBZ7-LkJOf_aGbsl_5422Ps,37525
|
|
32
|
+
matrice_analytics/post_processing/face_reg/face_recognition.py,sha256=ILkQumMY2ij_QrhJxzLifOv_q5rXh7N4mW94hr6EcgQ,103585
|
|
33
|
+
matrice_analytics/post_processing/face_reg/face_recognition_client.py,sha256=eF2NYju1uWKXhILndI1rh4_VhWrKSGidui2jjbPQXgM,27596
|
|
34
34
|
matrice_analytics/post_processing/face_reg/people_activity_logging.py,sha256=vZbIvkK1h3h58ROeF0_ygF3lqr19O2h5222bN8XyIis,13675
|
|
35
35
|
matrice_analytics/post_processing/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
36
|
matrice_analytics/post_processing/ocr/easyocr_extractor.py,sha256=RMrRoGb2gMcJEGouQn8U9cCgCLXPT7qRa8liI4LNxFM,11555
|
|
@@ -189,8 +189,8 @@ matrice_analytics/post_processing/utils/format_utils.py,sha256=UTF7A5h9j0_S12xH9
|
|
|
189
189
|
matrice_analytics/post_processing/utils/geometry_utils.py,sha256=BWfdM6RsdJTTLR1GqkWfdwpjMEjTCJyuBxA4zVGKdfk,9623
|
|
190
190
|
matrice_analytics/post_processing/utils/smoothing_utils.py,sha256=78U-yucAcjUiZ0NIAc9NOUSIT0PWP1cqyIPA_Fdrjp0,14699
|
|
191
191
|
matrice_analytics/post_processing/utils/tracking_utils.py,sha256=rWxuotnJ3VLMHIBOud2KLcu4yZfDp7hVPWUtNAq_2xw,8288
|
|
192
|
-
matrice_analytics-0.1.
|
|
193
|
-
matrice_analytics-0.1.
|
|
194
|
-
matrice_analytics-0.1.
|
|
195
|
-
matrice_analytics-0.1.
|
|
196
|
-
matrice_analytics-0.1.
|
|
192
|
+
matrice_analytics-0.1.54.dist-info/licenses/LICENSE.txt,sha256=_uQUZpgO0mRYL5-fPoEvLSbNnLPv6OmbeEDCHXhK6Qc,1066
|
|
193
|
+
matrice_analytics-0.1.54.dist-info/METADATA,sha256=1RfM8nWJEoj9BnNP4ehKraPM8ZSReG7D2dZ8JYjxqew,14378
|
|
194
|
+
matrice_analytics-0.1.54.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
195
|
+
matrice_analytics-0.1.54.dist-info/top_level.txt,sha256=STAPEU-e-rWTerXaspdi76T_eVRSrEfFpURSP7_Dt8E,18
|
|
196
|
+
matrice_analytics-0.1.54.dist-info/RECORD,,
|
|
File without changes
|
{matrice_analytics-0.1.52.dist-info → matrice_analytics-0.1.54.dist-info}/licenses/LICENSE.txt
RENAMED
|
File without changes
|
|
File without changes
|