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.

@@ -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
- if not response.get("success", False):
185
- self.logger.error(f"Failed to get staff embeddings from API: {response.get('error', 'Unknown error')}")
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
- self.logger.debug("No local match found - returning unknown")
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
- # Expect client to be initialized in initialize(); fail fast if not
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
- try:
994
- self.face_client = self._get_facial_recognition_client(config)
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.get("error", "Unknown RPC error")
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice_analytics
3
- Version: 0.1.52
3
+ Version: 0.1.54
4
4
  Summary: Common server utilities for Matrice.ai services
5
5
  Author-email: "Matrice.ai" <dipendra@matrice.ai>
6
6
  License-Expression: MIT
@@ -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=hv4WIUQg-PiSZ_H_jo8bbU8hvsAdF7E9KxUhdYcqi7Y,35815
32
- matrice_analytics/post_processing/face_reg/face_recognition.py,sha256=rmBwr725V849OfMmQfxGEvGkPacV9ztc547b-Gms3kY,103735
33
- matrice_analytics/post_processing/face_reg/face_recognition_client.py,sha256=aWuGC6dRGaf5nN2xhyDIZOeg59r3DFNajcmc3AOxIdI,27594
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.52.dist-info/licenses/LICENSE.txt,sha256=_uQUZpgO0mRYL5-fPoEvLSbNnLPv6OmbeEDCHXhK6Qc,1066
193
- matrice_analytics-0.1.52.dist-info/METADATA,sha256=ZsZbFhw3tjjB3hyW9ZzwqdI4K6cA5cHwJmAbkFnb7fo,14378
194
- matrice_analytics-0.1.52.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
195
- matrice_analytics-0.1.52.dist-info/top_level.txt,sha256=STAPEU-e-rWTerXaspdi76T_eVRSrEfFpURSP7_Dt8E,18
196
- matrice_analytics-0.1.52.dist-info/RECORD,,
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,,