matrice-analytics 0.1.44__tar.gz → 0.1.45__tar.gz

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.

Files changed (201) hide show
  1. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/PKG-INFO +1 -1
  2. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/matrice_analytics.egg-info/PKG-INFO +1 -1
  3. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/matrice_analytics.egg-info/SOURCES.txt +1 -0
  4. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/config.py +1 -1
  5. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/face_reg/face_recognition.py +75 -64
  6. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/face_reg/face_recognition_client.py +24 -19
  7. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/face_reg/people_activity_logging.py +6 -4
  8. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/easyocr_extractor.py +3 -1
  9. matrice_analytics-0.1.45/src/matrice_analytics/post_processing/test_cases/test_usecases.py +165 -0
  10. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip.py +4 -3
  11. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/color_mapper.py +1 -1
  12. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/fire_detection.py +0 -1
  13. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/LICENSE.txt +0 -0
  14. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/README.md +0 -0
  15. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/matrice_analytics.egg-info/dependency_links.txt +0 -0
  16. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/matrice_analytics.egg-info/not-zip-safe +0 -0
  17. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/matrice_analytics.egg-info/top_level.txt +0 -0
  18. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/pyproject.toml +0 -0
  19. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/setup.cfg +0 -0
  20. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/setup.py +0 -0
  21. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/__init__.py +0 -0
  22. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/README.md +0 -0
  23. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/__init__.py +0 -0
  24. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_internal.py +0 -0
  25. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_tool.py +0 -0
  26. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/boundary_tool_template.html +0 -0
  27. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/example_usage.py +0 -0
  28. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/usage/README.md +0 -0
  29. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/usage/boundary_drawer_launcher.py +0 -0
  30. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py +0 -0
  31. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/README.md +0 -0
  32. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/__init__.py +0 -0
  33. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/README.md +0 -0
  34. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/__init__.py +0 -0
  35. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/base.py +0 -0
  36. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/config.py +0 -0
  37. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/kalman_filter.py +0 -0
  38. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/matching.py +0 -0
  39. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/strack.py +0 -0
  40. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/advanced_tracker/tracker.py +0 -0
  41. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/core/__init__.py +0 -0
  42. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/core/base.py +0 -0
  43. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/core/config.py +0 -0
  44. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/core/config_utils.py +0 -0
  45. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/face_reg/__init__.py +0 -0
  46. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/face_reg/compare_similarity.py +0 -0
  47. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/face_reg/embedding_manager.py +0 -0
  48. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/__init__.py +0 -0
  49. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/__init__.py +0 -0
  50. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/__init__.py +0 -0
  51. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/cli.py +0 -0
  52. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/dataset_stats.py +0 -0
  53. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/export.py +0 -0
  54. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/train.py +0 -0
  55. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/utils.py +0 -0
  56. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/valid.py +0 -0
  57. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/validate_dataset.py +0 -0
  58. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_augmentation.py +0 -0
  59. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_predictions.py +0 -0
  60. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/__init__.py +0 -0
  61. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/process.py +0 -0
  62. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/types.py +0 -0
  63. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/utils.py +0 -0
  64. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/__init__.py +0 -0
  65. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/config.py +0 -0
  66. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/hub.py +0 -0
  67. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/plate_recognizer.py +0 -0
  68. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/py.typed +0 -0
  69. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/__init__.py +0 -0
  70. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/__init__.py +0 -0
  71. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/augmentation.py +0 -0
  72. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/dataset.py +0 -0
  73. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/__init__.py +0 -0
  74. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/config.py +0 -0
  75. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/layers.py +0 -0
  76. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/loss.py +0 -0
  77. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/metric.py +0 -0
  78. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_builders.py +0 -0
  79. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_schema.py +0 -0
  80. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/__init__.py +0 -0
  81. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/backend_utils.py +0 -0
  82. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/utils.py +0 -0
  83. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/postprocessing.py +0 -0
  84. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/ocr/preprocessing.py +0 -0
  85. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/post_processor.py +0 -0
  86. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/__init__.py +0 -0
  87. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/run_tests.py +0 -0
  88. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_advanced_customer_service.py +0 -0
  89. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_basic_counting_tracking.py +0 -0
  90. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_comprehensive.py +0 -0
  91. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_config.py +0 -0
  92. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_customer_service.py +0 -0
  93. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_data_generators.py +0 -0
  94. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_people_counting.py +0 -0
  95. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_processor.py +0 -0
  96. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_utilities.py +0 -0
  97. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/test_cases/test_utils.py +0 -0
  98. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py +0 -0
  99. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/__init__.py +0 -0
  100. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/abandoned_object_detection.py +0 -0
  101. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/advanced_customer_service.py +0 -0
  102. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/age_detection.py +0 -0
  103. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/age_gender_detection.py +0 -0
  104. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/anti_spoofing_detection.py +0 -0
  105. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/assembly_line_detection.py +0 -0
  106. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/banana_defect_detection.py +0 -0
  107. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/basic_counting_tracking.py +0 -0
  108. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/blood_cancer_detection_img.py +0 -0
  109. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/car_damage_detection.py +0 -0
  110. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/car_part_segmentation.py +0 -0
  111. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/car_service.py +0 -0
  112. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/cardiomegaly_classification.py +0 -0
  113. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/cell_microscopy_segmentation.py +0 -0
  114. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/chicken_pose_detection.py +0 -0
  115. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/child_monitoring.py +0 -0
  116. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip_processor/merges.txt +0 -0
  117. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip_processor/preprocessor_config.json +0 -0
  118. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip_processor/special_tokens_map.json +0 -0
  119. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer.json +0 -0
  120. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer_config.json +0 -0
  121. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/clip_processor/vocab.json +0 -0
  122. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color/color_map_utils.py +0 -0
  123. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color_detection.py +0 -0
  124. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/color_map_utils.py +0 -0
  125. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/concrete_crack_detection.py +0 -0
  126. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/crop_weed_detection.py +0 -0
  127. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/customer_service.py +0 -0
  128. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/defect_detection_products.py +0 -0
  129. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/distracted_driver_detection.py +0 -0
  130. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/drone_traffic_monitoring.py +0 -0
  131. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/drowsy_driver_detection.py +0 -0
  132. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/dwell_detection.py +0 -0
  133. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/emergency_vehicle_detection.py +0 -0
  134. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/face_emotion.py +0 -0
  135. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/face_recognition.py +0 -0
  136. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/fashion_detection.py +0 -0
  137. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/field_mapping.py +0 -0
  138. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/flare_analysis.py +0 -0
  139. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/flower_segmentation.py +0 -0
  140. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/gas_leak_detection.py +0 -0
  141. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/gender_detection.py +0 -0
  142. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/human_activity_recognition.py +0 -0
  143. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/intrusion_detection.py +0 -0
  144. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/leaf.py +0 -0
  145. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/leaf_disease.py +0 -0
  146. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/leak_detection.py +0 -0
  147. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/license_plate_detection.py +0 -0
  148. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/license_plate_monitoring.py +0 -0
  149. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/litter_monitoring.py +0 -0
  150. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/mask_detection.py +0 -0
  151. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/natural_disaster.py +0 -0
  152. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/parking.py +0 -0
  153. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/parking_space_detection.py +0 -0
  154. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/pcb_defect_detection.py +0 -0
  155. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/pedestrian_detection.py +0 -0
  156. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/people_counting.py +0 -0
  157. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/people_counting_bckp.py +0 -0
  158. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/people_tracking.py +0 -0
  159. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/pipeline_detection.py +0 -0
  160. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/plaque_segmentation_img.py +0 -0
  161. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/pothole_segmentation.py +0 -0
  162. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/ppe_compliance.py +0 -0
  163. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/price_tag_detection.py +0 -0
  164. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/proximity_detection.py +0 -0
  165. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/road_lane_detection.py +0 -0
  166. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/road_traffic_density.py +0 -0
  167. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/road_view_segmentation.py +0 -0
  168. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/shelf_inventory_detection.py +0 -0
  169. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/shoplifting_detection.py +0 -0
  170. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/shopping_cart_analysis.py +0 -0
  171. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/skin_cancer_classification_img.py +0 -0
  172. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/smoker_detection.py +0 -0
  173. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/solar_panel.py +0 -0
  174. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/suspicious_activity_detection.py +0 -0
  175. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/template_usecase.py +0 -0
  176. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/theft_detection.py +0 -0
  177. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/traffic_sign_monitoring.py +0 -0
  178. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/underground_pipeline_defect_detection.py +0 -0
  179. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/underwater_pollution_detection.py +0 -0
  180. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/vehicle_monitoring.py +0 -0
  181. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/warehouse_object_segmentation.py +0 -0
  182. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/waterbody_segmentation.py +0 -0
  183. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/weapon_detection.py +0 -0
  184. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/weld_defect_detection.py +0 -0
  185. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/wildlife_monitoring.py +0 -0
  186. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/windmill_maintenance.py +0 -0
  187. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/usecases/wound_segmentation.py +0 -0
  188. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/__init__.py +0 -0
  189. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/advanced_counting_utils.py +0 -0
  190. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/advanced_helper_utils.py +0 -0
  191. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/advanced_tracking_utils.py +0 -0
  192. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/alerting_utils.py +0 -0
  193. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/category_mapping_utils.py +0 -0
  194. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/color_utils.py +0 -0
  195. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/counting_utils.py +0 -0
  196. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/filter_utils.py +0 -0
  197. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/format_utils.py +0 -0
  198. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/geometry_utils.py +0 -0
  199. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/smoothing_utils.py +0 -0
  200. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/post_processing/utils/tracking_utils.py +0 -0
  201. {matrice_analytics-0.1.44 → matrice_analytics-0.1.45}/src/matrice_analytics/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice_analytics
3
- Version: 0.1.44
3
+ Version: 0.1.45
4
4
  Summary: Common server utilities for Matrice.ai services
5
5
  Author-email: "Matrice.ai" <dipendra@matrice.ai>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice_analytics
3
- Version: 0.1.44
3
+ Version: 0.1.45
4
4
  Summary: Common server utilities for Matrice.ai services
5
5
  Author-email: "Matrice.ai" <dipendra@matrice.ai>
6
6
  License-Expression: MIT
@@ -88,6 +88,7 @@ src/matrice_analytics/post_processing/test_cases/test_customer_service.py
88
88
  src/matrice_analytics/post_processing/test_cases/test_data_generators.py
89
89
  src/matrice_analytics/post_processing/test_cases/test_people_counting.py
90
90
  src/matrice_analytics/post_processing/test_cases/test_processor.py
91
+ src/matrice_analytics/post_processing/test_cases/test_usecases.py
91
92
  src/matrice_analytics/post_processing/test_cases/test_utilities.py
92
93
  src/matrice_analytics/post_processing/test_cases/test_utils.py
93
94
  src/matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py
@@ -143,4 +143,4 @@ def get_usecase_from_app_name(app_name: str) -> str:
143
143
 
144
144
  def get_category_from_app_name(app_name: str) -> str:
145
145
  normalized_app_name = app_name.lower().replace(" ", "_").replace("-", "_")
146
- return APP_NAME_TO_CATEGORY.get(app_name, APP_NAME_TO_CATEGORY.get(normalized_app_name))
146
+ return APP_NAME_TO_CATEGORY.get(app_name, APP_NAME_TO_CATEGORY.get(normalized_app_name))
@@ -24,7 +24,7 @@ subprocess.run(
24
24
  cmd,
25
25
  stdout=log_file,
26
26
  stderr=subprocess.STDOUT,
27
- preexec_fn=os.setpgrp
27
+ # preexec_fn=os.setpgrp
28
28
  )
29
29
  log_file.close()
30
30
 
@@ -81,13 +81,13 @@ class TemporalIdentityManager:
81
81
  """
82
82
  Maintains stable identity labels per tracker ID using temporal smoothing and embedding history.
83
83
 
84
- Adaptation for production: _compute_best_identity queries the face recognition API
85
- via search_similar_faces(embedding, threshold=0.01, limit=1) to obtain top-1 match and score.
84
+ Uses local embedding similarity search via EmbeddingManager instead of API calls.
86
85
  """
87
86
 
88
87
  def __init__(
89
88
  self,
90
89
  face_client: FacialRecognitionClient,
90
+ embedding_manager: Optional[Any] = None, # EmbeddingManager instance
91
91
  recognition_threshold: float = 0.35,
92
92
  history_size: int = 20,
93
93
  unknown_patience: int = 7,
@@ -96,6 +96,7 @@ class TemporalIdentityManager:
96
96
  ) -> None:
97
97
  self.logger = logging.getLogger(__name__)
98
98
  self.face_client = face_client
99
+ self.embedding_manager = embedding_manager
99
100
  self.threshold = float(recognition_threshold)
100
101
  self.history_size = int(history_size)
101
102
  self.unknown_patience = int(unknown_patience)
@@ -119,69 +120,65 @@ class TemporalIdentityManager:
119
120
 
120
121
  async def _compute_best_identity(self, emb: List[float], location: str = "", timestamp: str = "") -> Tuple[Optional[str], str, float, Optional[str], Dict[str, Any], str]:
121
122
  """
122
- Query backend for top-1 match for the given embedding.
123
+ Query embedding manager for top-1 match using local similarity search.
123
124
  Returns (staff_id, person_name, score, employee_id, staff_details, detection_type).
124
- Robust to varying response shapes.
125
+
126
+ NOTE: API call to search_similar_faces is commented out - using local embeddings only.
125
127
  """
126
128
  if not emb or not isinstance(emb, list):
127
129
  return None, "Unknown", 0.0, None, {}, "unknown"
130
+
131
+ # COMMENTED OUT: API-based search - now using local embedding similarity search
132
+ # try:
133
+ # resp = await self.face_client.search_similar_faces(
134
+ # face_embedding=emb,
135
+ # threshold=0.01, # low threshold to always get top-1
136
+ # limit=1,
137
+ # collection="staff_enrollment",
138
+ # location=location,
139
+ # timestamp=timestamp,
140
+ # )
141
+ # except Exception as e:
142
+ # self.logger.error(f"API ERROR: Failed to search similar faces in _compute_best_identity: {e}", exc_info=True)
143
+ # return None, "Unknown", 0.0, None, {}, "unknown"
144
+ #
145
+ # [API response parsing code removed - see git history]
146
+
147
+ # NEW: Use local embedding manager for similarity search
128
148
  try:
129
- resp = await self.face_client.search_similar_faces(
130
- face_embedding=emb,
131
- threshold=0.01, # low threshold to always get top-1
132
- limit=1,
133
- collection="staff_enrollment",
149
+ if not self.embedding_manager:
150
+ self.logger.warning("Embedding manager not available for local similarity search")
151
+ return None, "Unknown", 0.0, None, {}, "unknown"
152
+
153
+ # Perform local similarity search using embedding manager
154
+ search_result = await self.embedding_manager.search_face_embedding(
155
+ embedding=emb,
156
+ track_id=None, # No track_id needed for this search
134
157
  location=location,
135
158
  timestamp=timestamp,
136
159
  )
137
- except Exception as e:
138
- self.logger.error(f"API ERROR: Failed to search similar faces in _compute_best_identity: {e}", exc_info=True)
139
- return None, "Unknown", 0.0, None, {}, "unknown"
140
-
141
- try:
142
- results: List[Any] = []
143
- self.logger.debug('API Response received for identity search')
144
- if isinstance(resp, dict):
145
- if isinstance(resp.get("data"), list):
146
- results = resp.get("data", [])
147
- elif isinstance(resp.get("results"), list):
148
- results = resp.get("results", [])
149
- elif isinstance(resp.get("items"), list):
150
- results = resp.get("items", [])
151
- elif isinstance(resp, list):
152
- results = resp
153
-
154
- if not results:
155
- self.logger.debug("No identity match found from API")
160
+
161
+ if not search_result:
162
+ self.logger.debug("No identity match found from local embeddings")
156
163
  return None, "Unknown", 0.0, None, {}, "unknown"
157
-
158
- item = results[0] if isinstance(results, list) else results
159
- self.logger.debug(f'Top-1 match from API: {item}')
160
- # Be defensive with keys and types
161
- staff_id = item.get("staffId") if isinstance(item, dict) else None
162
- employee_id = str(item.get("_id")) if isinstance(item, dict) and item.get("_id") is not None else None
163
- score = float(item.get("score", 0.0)) if isinstance(item, dict) else 0.0
164
- detection_type = str(item.get("detectionType", "unknown")) if isinstance(item, dict) else "unknown"
165
- staff_details = item.get("staffDetails", {}) if isinstance(item, dict) else {}
166
- # Extract a person name from staff_details
167
- person_name = "Unknown"
168
- if isinstance(staff_details, dict) and staff_details:
169
- first_name = staff_details.get("firstName")
170
- last_name = staff_details.get("lastName")
171
- name = staff_details.get("name")
172
- if name:
173
- person_name = str(name)
174
- else:
175
- if first_name or last_name:
176
- person_name = f"{first_name or ''} {last_name or ''}".strip() or "UnknowNN" #TODO:ebugging change to normal once done
177
- # If API says unknown or missing staff_id, treat as unknown
178
- if not staff_id: #or detection_type == "unknown"
179
- self.logger.debug(f"API returned unknown or missing staff_id - score={score}, employee_id={employee_id}")
164
+
165
+ # Extract data from SearchResult
166
+ staff_id = search_result.staff_id
167
+ person_name = search_result.person_name
168
+ score = search_result.similarity_score
169
+ employee_id = search_result.employee_id
170
+ staff_details = search_result.staff_details
171
+ detection_type = search_result.detection_type
172
+
173
+ if not staff_id or detection_type == "unknown":
174
+ self.logger.debug(f"Local search returned unknown or missing staff_id - score={score}, employee_id={employee_id}")
180
175
  return None, "Unknown", float(score), employee_id, staff_details if isinstance(staff_details, dict) else {}, "unknown"
181
- self.logger.info(f"API identified face - staff_id={staff_id}, person_name={person_name}, score={score:.3f}")
176
+
177
+ self.logger.info(f"Local embedding identified face - staff_id={staff_id}, person_name={person_name}, score={score:.3f}")
182
178
  return str(staff_id), person_name, float(score), employee_id, staff_details if isinstance(staff_details, dict) else {}, "known"
179
+
183
180
  except Exception as e:
184
- self.logger.error(f"Error parsing API response in _compute_best_identity: {e}", exc_info=True)
181
+ self.logger.error(f"Error in local embedding similarity search: {e}", exc_info=True)
185
182
  return None, "Unknown", 0.0, None, {}, "unknown"
186
183
 
187
184
  async def _compute_best_identity_from_history(self, track_state: Dict[str, object], location: str = "", timestamp: str = "") -> Tuple[Optional[str], str, float, Optional[str], Dict[str, Any], str]:
@@ -488,16 +485,17 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
488
485
  self.embedding_manager = EmbeddingManager(init_config.embedding_config, self.face_client)
489
486
  self.logger.info("Embedding manager initialized")
490
487
 
491
- # Initialize TemporalIdentityManager
488
+ # Initialize TemporalIdentityManager with embedding_manager for local search
492
489
  self.temporal_identity_manager = TemporalIdentityManager(
493
490
  face_client=self.face_client,
491
+ embedding_manager=self.embedding_manager, # Pass embedding manager for local similarity search
494
492
  recognition_threshold=float(init_config.similarity_threshold),
495
493
  history_size=20,
496
494
  unknown_patience=7,
497
495
  switch_patience=5,
498
496
  fallback_margin=0.05,
499
497
  )
500
- self.logger.info("Temporal identity manager initialized")
498
+ self.logger.info("Temporal identity manager initialized with local embedding search")
501
499
 
502
500
  self._initialized = True
503
501
  self.logger.info("Face recognition use case fully initialized")
@@ -909,16 +907,28 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
909
907
  # Generate current timestamp
910
908
  current_timestamp = datetime.now(timezone.utc).isoformat()
911
909
 
912
- final_detections = []
913
- # Process detections sequentially to preserve order
914
- for detection in detections:
915
-
916
- # Process each detection sequentially with await to preserve order
917
- processed_detection = await self._process_face(
910
+ # Process all detections in parallel for better performance
911
+ # Create tasks for parallel processing
912
+ tasks = [
913
+ self._process_face(
918
914
  detection, current_frame, location, current_timestamp, config,
919
915
  current_recognized_count, current_unknown_count,
920
916
  recognized_persons, current_frame_staff_details
921
917
  )
918
+ for detection in detections
919
+ ]
920
+
921
+ # Process all faces in parallel
922
+ processed_detections = await asyncio.gather(*tasks, return_exceptions=True)
923
+
924
+ # Build final results and update counters (maintains order)
925
+ final_detections = []
926
+ for processed_detection in processed_detections:
927
+ # Handle exceptions from parallel processing
928
+ if isinstance(processed_detection, Exception):
929
+ self.logger.error(f"Error processing face detection: {processed_detection}", exc_info=True)
930
+ continue
931
+
922
932
  # Include both known and unknown faces in final detections (maintains original order)
923
933
  if processed_detection:
924
934
  final_detections.append(processed_detection)
@@ -1085,7 +1095,7 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
1085
1095
  # If it later becomes recognized, we'll remove it from unknown set above
1086
1096
  self._unknown_track_ids.add(internal_tid)
1087
1097
 
1088
- # Enqueue detection for background logging with all required parameters
1098
+ # Enqueue detection for background logging with all required parameters (non-blocking)
1089
1099
  try:
1090
1100
  # Log known faces for activity tracking (skip any employee_id starting with "unknown_")
1091
1101
  if (
@@ -1096,7 +1106,8 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
1096
1106
  and employee_id
1097
1107
  and not str(employee_id).startswith("unknown_")
1098
1108
  ):
1099
- await self.people_activity_logging.enqueue_detection(
1109
+ # Non-blocking enqueue - no await needed
1110
+ self.people_activity_logging.enqueue_detection(
1100
1111
  detection=detection,
1101
1112
  current_frame=current_frame,
1102
1113
  location=location,
@@ -182,9 +182,9 @@ class FacialRecognitionClient:
182
182
  payload=enrollment_request,
183
183
  base_url=self.server_base_url
184
184
  )
185
- self.logger.info(f"API RESPONSE: Staff enrollment completed - Success: {response.get('success', False)}")
186
- if not response.get('success', False):
187
- self.logger.warning(f"Staff enrollment failed: {response.get('error', 'Unknown error')}")
185
+ self.logger.info(f"API RESPONSE: Staff enrollment completed - Success: {response.get('success', False) if response else False}")
186
+ if not response or not response.get('success', False):
187
+ self.logger.warning(f"Staff enrollment failed: {response.get('error', 'Unknown error') if response else 'No response'}")
188
188
  return self._handle_response(response)
189
189
  except Exception as e:
190
190
  self.logger.error(f"API ERROR: Staff enrollment request failed - {e}", exc_info=True)
@@ -236,14 +236,14 @@ class FacialRecognitionClient:
236
236
  )
237
237
 
238
238
  results_count = 0
239
- if response.get('success', False):
239
+ if response and response.get('success', False):
240
240
  data = response.get('data', [])
241
241
  results_count = len(data) if isinstance(data, list) else 0
242
242
  self.logger.info(f"API RESPONSE: Face search completed - Found {results_count} matches")
243
243
  if results_count > 0:
244
244
  self.logger.debug(f"Top match: staff_id={data[0].get('staffId', 'N/A')}, score={data[0].get('score', 0):.3f}")
245
245
  else:
246
- self.logger.warning(f"Face search failed: {response.get('error', 'Unknown error')}")
246
+ self.logger.warning(f"Face search failed: {response.get('error', 'Unknown error') if response else 'No response'}")
247
247
 
248
248
  return self._handle_response(response)
249
249
  except Exception as e:
@@ -267,10 +267,10 @@ class FacialRecognitionClient:
267
267
  base_url=self.server_base_url
268
268
  )
269
269
 
270
- if response.get('success', False):
270
+ if response and response.get('success', False):
271
271
  self.logger.info(f"API RESPONSE: Staff details retrieved successfully - staff_id={staff_id}")
272
272
  else:
273
- self.logger.warning(f"Failed to get staff details for staff_id={staff_id}: {response.get('error', 'Unknown error')}")
273
+ self.logger.warning(f"Failed to get staff details for staff_id={staff_id}: {response.get('error', 'Unknown error') if response else 'No response'}")
274
274
 
275
275
  return self._handle_response(response)
276
276
  except Exception as e:
@@ -366,10 +366,10 @@ class FacialRecognitionClient:
366
366
  base_url=self.server_base_url
367
367
  )
368
368
 
369
- if response.get('success', False):
369
+ if response and response.get('success', False):
370
370
  self.logger.info(f"API RESPONSE: Staff images updated successfully - employee_id={employee_id}")
371
371
  else:
372
- self.logger.warning(f"Failed to update staff images for employee_id={employee_id}: {response.get('error', 'Unknown error')}")
372
+ self.logger.warning(f"Failed to update staff images for employee_id={employee_id}: {response.get('error', 'Unknown error') if response else 'No response'}")
373
373
 
374
374
  return self._handle_response(response)
375
375
  except Exception as e:
@@ -417,10 +417,10 @@ class FacialRecognitionClient:
417
417
  base_url=self.server_base_url
418
418
  )
419
419
 
420
- if response.get('success', False):
420
+ if response and response.get('success', False):
421
421
  self.logger.info(f"API RESPONSE: Service shutdown successful")
422
422
  else:
423
- self.logger.warning(f"Service shutdown failed: {response.get('error', 'Unknown error')}")
423
+ self.logger.warning(f"Service shutdown failed: {response.get('error', 'Unknown error') if response else 'No response'}")
424
424
 
425
425
  return self._handle_response(response)
426
426
  except Exception as e:
@@ -447,12 +447,12 @@ class FacialRecognitionClient:
447
447
  )
448
448
 
449
449
  embeddings_count = 0
450
- if response.get('success', False):
450
+ if response and response.get('success', False):
451
451
  data = response.get('data', [])
452
452
  embeddings_count = len(data) if isinstance(data, list) else 0
453
453
  self.logger.info(f"API RESPONSE: Retrieved {embeddings_count} staff embeddings")
454
454
  else:
455
- self.logger.warning(f"Failed to get staff embeddings: {response.get('error', 'Unknown error')}")
455
+ self.logger.warning(f"Failed to get staff embeddings: {response.get('error', 'Unknown error') if response else 'No response'}")
456
456
 
457
457
  return self._handle_response(response)
458
458
  except Exception as e:
@@ -485,10 +485,10 @@ class FacialRecognitionClient:
485
485
  base_url=self.server_base_url
486
486
  )
487
487
 
488
- if response.get('success', False):
488
+ if response and response.get('success', False):
489
489
  self.logger.info(f"API RESPONSE: Deployment updated successfully - deployment_id={deployment_id}")
490
490
  else:
491
- self.logger.warning(f"Failed to update deployment for deployment_id={deployment_id}: {response.get('error', 'Unknown error')}")
491
+ self.logger.warning(f"Failed to update deployment for deployment_id={deployment_id}: {response.get('error', 'Unknown error') if response else 'No response'}")
492
492
 
493
493
  return self._handle_response(response)
494
494
  except Exception as e:
@@ -527,10 +527,10 @@ class FacialRecognitionClient:
527
527
  base_url=self.server_base_url
528
528
  )
529
529
 
530
- if response.get('success', False):
530
+ if response and response.get('success', False):
531
531
  self.logger.info(f"API RESPONSE: Unknown person enrolled successfully")
532
532
  else:
533
- self.logger.warning(f"Failed to enroll unknown person: {response.get('error', 'Unknown error')}")
533
+ self.logger.warning(f"Failed to enroll unknown person: {response.get('error', 'Unknown error') if response else 'No response'}")
534
534
 
535
535
  return self._handle_response(response)
536
536
  except Exception as e:
@@ -551,10 +551,10 @@ class FacialRecognitionClient:
551
551
  base_url=self.server_base_url
552
552
  )
553
553
 
554
- if response.get('success', False):
554
+ if response and response.get('success', False):
555
555
  self.logger.info(f"API RESPONSE: Service is healthy")
556
556
  else:
557
- self.logger.warning(f"Health check failed: {response.get('error', 'Unknown error')}")
557
+ self.logger.warning(f"Health check failed: {response.get('error', 'Unknown error') if response else 'No response'}")
558
558
 
559
559
  return self._handle_response(response)
560
560
  except Exception as e:
@@ -564,6 +564,11 @@ class FacialRecognitionClient:
564
564
  def _handle_response(self, response: Dict[str, Any]) -> Dict[str, Any]:
565
565
  """Handle RPC response and errors"""
566
566
  try:
567
+ # Handle None response
568
+ if response is None:
569
+ self.logger.error("RPC Error: Received None response from API")
570
+ return {"success": False, "error": "No response received from API"}
571
+
567
572
  if response.get("success", True):
568
573
  return response
569
574
  else:
@@ -84,19 +84,20 @@ class PeopleActivityLogging:
84
84
  self.activity_queue.task_done()
85
85
  except queue.Empty:
86
86
  # Continue loop to check for empty detections
87
+ await asyncio.sleep(0.01)
87
88
  continue
88
89
 
89
90
  except Exception as e:
90
91
  self.logger.error(f"Error processing activity queue: {e}", exc_info=True)
91
92
  await asyncio.sleep(1.0)
92
93
 
93
- async def enqueue_detection(
94
+ def enqueue_detection(
94
95
  self,
95
96
  detection: Dict,
96
97
  current_frame: Optional[np.ndarray] = None,
97
98
  location: str = "",
98
99
  ):
99
- """Enqueue a detection for background processing"""
100
+ """Enqueue a detection for background processing (non-blocking)"""
100
101
  try:
101
102
  activity_data = {
102
103
  "detection_type": detection["recognition_status"], # known, unknown
@@ -135,8 +136,9 @@ class PeopleActivityLogging:
135
136
  self.last_detection_time = time.time()
136
137
  self.empty_detection_logged = False
137
138
 
138
- # Use thread-safe put (no await needed for queue.Queue)
139
- self.activity_queue.put(activity_data)
139
+ # Use thread-safe put_nowait to avoid any potential blocking
140
+ # queue.Queue.put() is already non-blocking with no timeout, but being explicit
141
+ self.activity_queue.put_nowait(activity_data)
140
142
  except Exception as e:
141
143
  self.logger.error(f"Error enqueueing detection: {e}", exc_info=True)
142
144
 
@@ -1,6 +1,7 @@
1
1
  import easyocr
2
2
  import numpy as np
3
3
  import torch
4
+ from matrice_common.utils import log_errors
4
5
 
5
6
  class EasyOCRExtractor:
6
7
  def __init__(self, lang=['en', 'hi', 'ar'], gpu=False, model_storage_directory=None,
@@ -30,7 +31,8 @@ class EasyOCRExtractor:
30
31
  self.recognizer = recognizer
31
32
  self.verbose = verbose
32
33
  self.reader = None
33
-
34
+
35
+ @log_errors(default_return=None, raise_exception=True, service_name="py_analytics", log_error=True)
34
36
  def setup(self):
35
37
  """
36
38
  Initializes the EasyOCR reader if not already initialized.
@@ -0,0 +1,165 @@
1
+ import os
2
+ import sys
3
+ import cv2
4
+ import json
5
+ import importlib
6
+ import argparse
7
+ from ultralytics import YOLO
8
+ from src.matrice_analytics.post_processing.core.base import ProcessingContext
9
+
10
+
11
+ class UseCaseTestProcessor:
12
+ """
13
+ A flexible YOLO-based video processor for testing different post-processing use cases.
14
+ """
15
+
16
+ def __init__(self, file_name, config_name, usecase_name, model_path, video_path, post_process=None, max_frames=None):
17
+ self.file_name = file_name
18
+ self.config_name = config_name
19
+ self.usecase_name = usecase_name
20
+ self.model_path = model_path
21
+ self.video_path = video_path
22
+ self.post_process = post_process
23
+ self.max_frames = max_frames
24
+ self.json_dir = "jsons"
25
+
26
+ self._setup_environment()
27
+ self.ConfigClass, self.UsecaseClass = self._load_usecase()
28
+ self.config = self._initialize_config()
29
+ self.processor = self.UsecaseClass()
30
+ self.model = YOLO(self.model_path)
31
+ os.makedirs(self.json_dir, exist_ok=True)
32
+
33
+ def _setup_environment(self):
34
+ """Ensure project root is added to sys.path."""
35
+ project_root = os.path.abspath("/content/py_analytics")
36
+ if project_root not in sys.path:
37
+ sys.path.append(project_root)
38
+
39
+ def _load_usecase(self):
40
+ """Dynamically import config and usecase classes."""
41
+ module_path = f"src.matrice_analytics.post_processing.usecases.{self.file_name}"
42
+ module = importlib.import_module(module_path)
43
+ return getattr(module, self.config_name), getattr(module, self.usecase_name)
44
+
45
+ def _initialize_config(self):
46
+ """Initialize config object, applying overrides if provided."""
47
+ if self.post_process:
48
+ return self.ConfigClass(**self.post_process)
49
+ return self.ConfigClass()
50
+
51
+ def _serialize_result(self, result):
52
+ """Convert result object into JSON-serializable dict."""
53
+ def to_serializable(obj):
54
+ if hasattr(obj, "to_dict"):
55
+ return obj.to_dict()
56
+ if hasattr(obj, "__dict__"):
57
+ return obj.__dict__
58
+ return str(obj)
59
+ return json.loads(json.dumps(result, default=to_serializable))
60
+
61
+
62
+ def process_video(self):
63
+ """Run YOLO inference on video and post-process frame by frame."""
64
+ cap = cv2.VideoCapture(self.video_path)
65
+ if not cap.isOpened():
66
+ raise ValueError(f"Failed to open video at {self.video_path}")
67
+
68
+ frame_idx = 0
69
+ stream_info = {
70
+ 'input_settings': {
71
+ 'start_frame': 0,
72
+ 'original_fps': cap.get(cv2.CAP_PROP_FPS),
73
+ 'camera_info': {'id': 'cam1', 'name': 'Test Camera'}
74
+ }
75
+ }
76
+
77
+ print(f"\nStarting video processing: {self.video_path}")
78
+ print(f"Model: {self.model_path}")
79
+ print(f"Output directory: {self.json_dir}\n")
80
+
81
+ while cap.isOpened():
82
+ ret, frame = cap.read()
83
+ if not ret:
84
+ break
85
+
86
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
87
+ results = self.model(frame_rgb)
88
+
89
+ detections = []
90
+ for xyxy, conf, cls in zip(results[0].boxes.xyxy, results[0].boxes.conf, results[0].boxes.cls):
91
+ x1, y1, x2, y2 = xyxy.tolist()
92
+ detections.append({
93
+ 'category_id': int(cls),
94
+ 'confidence': conf.item(),
95
+ 'bounding_box': {
96
+ 'xmin': int(x1),
97
+ 'ymin': int(y1),
98
+ 'xmax': int(x2),
99
+ 'ymax': int(y2)
100
+ }
101
+ })
102
+
103
+ success, encoded_image = cv2.imencode(".jpg", frame)
104
+ input_bytes = encoded_image.tobytes() if success else None
105
+
106
+ try:
107
+ result = self.processor.process(
108
+ detections, self.config, input_bytes, ProcessingContext(), stream_info
109
+ )
110
+ except TypeError:
111
+ result = self.processor.process(
112
+ detections, self.config, ProcessingContext(), stream_info
113
+ )
114
+
115
+ json_path = os.path.join(self.json_dir, f"frame_{frame_idx:04d}.json")
116
+ with open(json_path, "w") as f:
117
+ json.dump(self._serialize_result(result), f, indent=2)
118
+
119
+ print(f"Frame {frame_idx} processed — detections: {len(detections)} — saved: {json_path}")
120
+
121
+ frame_idx += 1
122
+ stream_info['input_settings']['start_frame'] += 1
123
+
124
+ if self.max_frames and frame_idx >= self.max_frames:
125
+ print(f"\nMax frame limit ({self.max_frames}) reached.")
126
+ break
127
+
128
+ cap.release()
129
+ print(f"\nProcessing complete. JSON outputs saved in: {self.json_dir}")
130
+
131
+
132
+ def main():
133
+ parser = argparse.ArgumentParser(description="YOLO Use Case Test Processor")
134
+
135
+ parser.add_argument("--file_name", type=str, required=True,
136
+ help="Usecase file name under src/matrice_analytics/post_processing/usecases/")
137
+ parser.add_argument("--config_name", type=str, required=True,
138
+ help="Config class name (e.g., PeopleCountingConfig)")
139
+ parser.add_argument("--usecase_name", type=str, required=True,
140
+ help="Use case class name (e.g., PeopleCountingUseCase)")
141
+ parser.add_argument("--model_path", type=str, required=True,
142
+ help="Path to YOLO model file (.pt)")
143
+ parser.add_argument("--video_path", type=str, required=True,
144
+ help="Path to input video")
145
+ parser.add_argument("--post_process", type=json.loads, default=None,
146
+ help="JSON string for config overrides, e.g. '{\"min_confidence\": 0.5}'")
147
+ parser.add_argument("--max_frames", type=int, default=None,
148
+ help="Limit number of frames processed")
149
+
150
+ args = parser.parse_args()
151
+
152
+ processor = UseCaseTestProcessor(
153
+ file_name=args.file_name,
154
+ config_name=args.config_name,
155
+ usecase_name=args.usecase_name,
156
+ model_path=args.model_path,
157
+ video_path=args.video_path,
158
+ post_process=args.post_process,
159
+ max_frames=args.max_frames
160
+ )
161
+ processor.process_video()
162
+
163
+
164
+ if __name__ == "__main__":
165
+ main()
@@ -11,20 +11,21 @@ subprocess.run(
11
11
  cmd,
12
12
  stdout=log_file,
13
13
  stderr=subprocess.STDOUT,
14
- preexec_fn=os.setpgrp
14
+ # preexec_fn=os.setpgrp
15
15
  )
16
16
  cmd = ["pip", "install", "httpx", "aiohttp", "filterpy"]
17
17
  subprocess.run(
18
18
  cmd,
19
19
  stdout=log_file,
20
20
  stderr=subprocess.STDOUT,
21
- preexec_fn=os.setpgrp
21
+ # preexec_fn=os.setpgrp
22
22
  )
23
23
  log_file.close()
24
24
 
25
25
  import numpy as np
26
26
  from typing import List, Dict, Tuple, Optional
27
27
  from dataclasses import dataclass, field
28
+ from pathlib import Path
28
29
  import cv2
29
30
  import io
30
31
  import threading
@@ -371,7 +372,7 @@ class ClipProcessor:
371
372
  cmd,
372
373
  stdout=log_file,
373
374
  stderr=subprocess.STDOUT,
374
- preexec_fn=os.setpgrp
375
+ # preexec_fn=os.setpgrp
375
376
  )
376
377
 
377
378
  # Determine and enforce providers (prefer CUDA only)
@@ -465,4 +465,4 @@ def process_video_with_color_detection(
465
465
  classifier = VideoColorClassifier(top_k_colors, min_confidence)
466
466
  return classifier.process_video_with_predictions(
467
467
  video_bytes, yolo_predictions, output_dir, fps
468
- )
468
+ )