matrice-analytics 0.1.42__tar.gz → 0.1.44__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 (200) hide show
  1. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/PKG-INFO +1 -1
  2. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/PKG-INFO +1 -1
  3. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/face_recognition.py +70 -35
  4. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip.py +50 -5
  5. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color_detection.py +89 -54
  6. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/fire_detection.py +89 -54
  7. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/license_plate_monitoring.py +81 -46
  8. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/people_counting.py +29 -28
  9. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/vehicle_monitoring.py +89 -54
  10. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/LICENSE.txt +0 -0
  11. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/README.md +0 -0
  12. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/SOURCES.txt +0 -0
  13. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/dependency_links.txt +0 -0
  14. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/not-zip-safe +0 -0
  15. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/top_level.txt +0 -0
  16. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/pyproject.toml +0 -0
  17. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/setup.cfg +0 -0
  18. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/setup.py +0 -0
  19. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/__init__.py +0 -0
  20. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/README.md +0 -0
  21. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/__init__.py +0 -0
  22. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_internal.py +0 -0
  23. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_tool.py +0 -0
  24. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/boundary_tool_template.html +0 -0
  25. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/example_usage.py +0 -0
  26. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/usage/README.md +0 -0
  27. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/usage/boundary_drawer_launcher.py +0 -0
  28. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py +0 -0
  29. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/README.md +0 -0
  30. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/__init__.py +0 -0
  31. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/README.md +0 -0
  32. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/__init__.py +0 -0
  33. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/base.py +0 -0
  34. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/config.py +0 -0
  35. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/kalman_filter.py +0 -0
  36. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/matching.py +0 -0
  37. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/strack.py +0 -0
  38. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/tracker.py +0 -0
  39. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/config.py +0 -0
  40. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/__init__.py +0 -0
  41. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/base.py +0 -0
  42. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/config.py +0 -0
  43. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/config_utils.py +0 -0
  44. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/__init__.py +0 -0
  45. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/compare_similarity.py +0 -0
  46. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/embedding_manager.py +0 -0
  47. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/face_recognition_client.py +0 -0
  48. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/people_activity_logging.py +0 -0
  49. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/__init__.py +0 -0
  50. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/easyocr_extractor.py +0 -0
  51. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/__init__.py +0 -0
  52. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/__init__.py +0 -0
  53. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/cli.py +0 -0
  54. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/dataset_stats.py +0 -0
  55. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/export.py +0 -0
  56. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/train.py +0 -0
  57. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/utils.py +0 -0
  58. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/valid.py +0 -0
  59. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/validate_dataset.py +0 -0
  60. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_augmentation.py +0 -0
  61. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_predictions.py +0 -0
  62. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/__init__.py +0 -0
  63. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/process.py +0 -0
  64. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/types.py +0 -0
  65. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/utils.py +0 -0
  66. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/__init__.py +0 -0
  67. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/config.py +0 -0
  68. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/hub.py +0 -0
  69. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/plate_recognizer.py +0 -0
  70. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/py.typed +0 -0
  71. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/__init__.py +0 -0
  72. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/__init__.py +0 -0
  73. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/augmentation.py +0 -0
  74. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/dataset.py +0 -0
  75. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/__init__.py +0 -0
  76. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/config.py +0 -0
  77. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/layers.py +0 -0
  78. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/loss.py +0 -0
  79. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/metric.py +0 -0
  80. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_builders.py +0 -0
  81. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_schema.py +0 -0
  82. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/__init__.py +0 -0
  83. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/backend_utils.py +0 -0
  84. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/utils.py +0 -0
  85. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/postprocessing.py +0 -0
  86. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/preprocessing.py +0 -0
  87. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/post_processor.py +0 -0
  88. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/__init__.py +0 -0
  89. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/run_tests.py +0 -0
  90. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_advanced_customer_service.py +0 -0
  91. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_basic_counting_tracking.py +0 -0
  92. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_comprehensive.py +0 -0
  93. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_config.py +0 -0
  94. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_customer_service.py +0 -0
  95. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_data_generators.py +0 -0
  96. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_people_counting.py +0 -0
  97. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_processor.py +0 -0
  98. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_utilities.py +0 -0
  99. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_utils.py +0 -0
  100. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py +0 -0
  101. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/__init__.py +0 -0
  102. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/abandoned_object_detection.py +0 -0
  103. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/advanced_customer_service.py +0 -0
  104. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/age_detection.py +0 -0
  105. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/age_gender_detection.py +0 -0
  106. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/anti_spoofing_detection.py +0 -0
  107. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/assembly_line_detection.py +0 -0
  108. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/banana_defect_detection.py +0 -0
  109. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/basic_counting_tracking.py +0 -0
  110. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/blood_cancer_detection_img.py +0 -0
  111. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/car_damage_detection.py +0 -0
  112. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/car_part_segmentation.py +0 -0
  113. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/car_service.py +0 -0
  114. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/cardiomegaly_classification.py +0 -0
  115. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/cell_microscopy_segmentation.py +0 -0
  116. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/chicken_pose_detection.py +0 -0
  117. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/child_monitoring.py +0 -0
  118. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/merges.txt +0 -0
  119. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/preprocessor_config.json +0 -0
  120. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/special_tokens_map.json +0 -0
  121. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer.json +0 -0
  122. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer_config.json +0 -0
  123. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/vocab.json +0 -0
  124. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/color_map_utils.py +0 -0
  125. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/color_mapper.py +0 -0
  126. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color_map_utils.py +0 -0
  127. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/concrete_crack_detection.py +0 -0
  128. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/crop_weed_detection.py +0 -0
  129. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/customer_service.py +0 -0
  130. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/defect_detection_products.py +0 -0
  131. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/distracted_driver_detection.py +0 -0
  132. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/drone_traffic_monitoring.py +0 -0
  133. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/drowsy_driver_detection.py +0 -0
  134. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/dwell_detection.py +0 -0
  135. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/emergency_vehicle_detection.py +0 -0
  136. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/face_emotion.py +0 -0
  137. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/face_recognition.py +0 -0
  138. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/fashion_detection.py +0 -0
  139. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/field_mapping.py +0 -0
  140. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/flare_analysis.py +0 -0
  141. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/flower_segmentation.py +0 -0
  142. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/gas_leak_detection.py +0 -0
  143. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/gender_detection.py +0 -0
  144. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/human_activity_recognition.py +0 -0
  145. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/intrusion_detection.py +0 -0
  146. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/leaf.py +0 -0
  147. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/leaf_disease.py +0 -0
  148. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/leak_detection.py +0 -0
  149. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/license_plate_detection.py +0 -0
  150. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/litter_monitoring.py +0 -0
  151. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/mask_detection.py +0 -0
  152. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/natural_disaster.py +0 -0
  153. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/parking.py +0 -0
  154. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/parking_space_detection.py +0 -0
  155. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pcb_defect_detection.py +0 -0
  156. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pedestrian_detection.py +0 -0
  157. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/people_counting_bckp.py +0 -0
  158. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/people_tracking.py +0 -0
  159. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pipeline_detection.py +0 -0
  160. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/plaque_segmentation_img.py +0 -0
  161. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pothole_segmentation.py +0 -0
  162. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/ppe_compliance.py +0 -0
  163. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/price_tag_detection.py +0 -0
  164. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/proximity_detection.py +0 -0
  165. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/road_lane_detection.py +0 -0
  166. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/road_traffic_density.py +0 -0
  167. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/road_view_segmentation.py +0 -0
  168. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/shelf_inventory_detection.py +0 -0
  169. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/shoplifting_detection.py +0 -0
  170. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/shopping_cart_analysis.py +0 -0
  171. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/skin_cancer_classification_img.py +0 -0
  172. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/smoker_detection.py +0 -0
  173. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/solar_panel.py +0 -0
  174. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/suspicious_activity_detection.py +0 -0
  175. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/template_usecase.py +0 -0
  176. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/theft_detection.py +0 -0
  177. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/traffic_sign_monitoring.py +0 -0
  178. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/underground_pipeline_defect_detection.py +0 -0
  179. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/underwater_pollution_detection.py +0 -0
  180. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/warehouse_object_segmentation.py +0 -0
  181. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/waterbody_segmentation.py +0 -0
  182. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/weapon_detection.py +0 -0
  183. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/weld_defect_detection.py +0 -0
  184. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/wildlife_monitoring.py +0 -0
  185. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/windmill_maintenance.py +0 -0
  186. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/wound_segmentation.py +0 -0
  187. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/__init__.py +0 -0
  188. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/advanced_counting_utils.py +0 -0
  189. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/advanced_helper_utils.py +0 -0
  190. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/advanced_tracking_utils.py +0 -0
  191. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/alerting_utils.py +0 -0
  192. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/category_mapping_utils.py +0 -0
  193. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/color_utils.py +0 -0
  194. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/counting_utils.py +0 -0
  195. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/filter_utils.py +0 -0
  196. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/format_utils.py +0 -0
  197. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/geometry_utils.py +0 -0
  198. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/smoothing_utils.py +0 -0
  199. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/tracking_utils.py +0 -0
  200. {matrice_analytics-0.1.42 → matrice_analytics-0.1.44}/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.42
3
+ Version: 0.1.44
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.42
3
+ Version: 0.1.44
4
4
  Summary: Common server utilities for Matrice.ai services
5
5
  Author-email: "Matrice.ai" <dipendra@matrice.ai>
6
6
  License-Expression: MIT
@@ -1743,56 +1743,57 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
1743
1743
  return f"{hours:02d}:{minutes:02d}:{seconds:.1f}"
1744
1744
 
1745
1745
  def _format_timestamp(self, timestamp: Any) -> str:
1746
- """Format a timestamp so that exactly two digits follow the decimal point (milliseconds).
1746
+ """Format a timestamp to match the current timestamp format: YYYY:MM:DD HH:MM:SS.
1747
1747
 
1748
1748
  The input can be either:
1749
- 1. A numeric Unix timestamp (``float`` / ``int``) – it will first be converted to a
1750
- string in the format ``YYYY-MM-DD-HH:MM:SS.ffffff UTC``.
1751
- 2. A string already following the same layout.
1749
+ 1. A numeric Unix timestamp (``float`` / ``int``) – it will be converted to datetime.
1750
+ 2. A string in the format ``YYYY-MM-DD-HH:MM:SS.ffffff UTC``.
1752
1751
 
1753
- The returned value preserves the overall format of the input but truncates or pads
1754
- the fractional seconds portion to **exactly two digits**.
1752
+ The returned value will be in the format: YYYY:MM:DD HH:MM:SS (no milliseconds, no UTC suffix).
1755
1753
 
1756
1754
  Example
1757
1755
  -------
1758
- >>> self._format_timestamp("2025-08-19-04:22:47.187574 UTC")
1759
- '2025-08-19-04:22:47.18 UTC'
1756
+ >>> self._format_timestamp("2025-10-27-19:31:20.187574 UTC")
1757
+ '2025:10:27 19:31:20'
1760
1758
  """
1761
1759
 
1762
- # Convert numeric timestamps to the expected string representation first
1760
+ # Convert numeric timestamps to datetime first
1763
1761
  if isinstance(timestamp, (int, float)):
1764
- timestamp = datetime.fromtimestamp(timestamp, timezone.utc).strftime(
1765
- '%Y-%m-%d-%H:%M:%S.%f UTC'
1766
- )
1762
+ dt = datetime.fromtimestamp(timestamp, timezone.utc)
1763
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
1767
1764
 
1768
1765
  # Ensure we are working with a string from here on
1769
1766
  if not isinstance(timestamp, str):
1770
1767
  return str(timestamp)
1771
1768
 
1772
- # If there is no fractional component, simply return the original string
1773
- if '.' not in timestamp:
1774
- return timestamp
1769
+ # Remove ' UTC' suffix if present
1770
+ timestamp_clean = timestamp.replace(' UTC', '').strip()
1775
1771
 
1776
- # Split out the main portion (up to the decimal point)
1777
- main_part, fractional_and_suffix = timestamp.split('.', 1)
1778
-
1779
- # Separate fractional digits from the suffix (typically ' UTC')
1780
- if ' ' in fractional_and_suffix:
1781
- fractional_part, suffix = fractional_and_suffix.split(' ', 1)
1782
- suffix = ' ' + suffix # Re-attach the space removed by split
1783
- else:
1784
- fractional_part, suffix = fractional_and_suffix, ''
1772
+ # Remove milliseconds if present (everything after the last dot)
1773
+ if '.' in timestamp_clean:
1774
+ timestamp_clean = timestamp_clean.split('.')[0]
1785
1775
 
1786
- # Guarantee exactly two digits for the fractional part
1787
- fractional_part = (fractional_part + '00')[:2]
1776
+ # Parse the timestamp string and convert to desired format
1777
+ try:
1778
+ # Handle format: YYYY-MM-DD-HH:MM:SS
1779
+ if timestamp_clean.count('-') >= 2:
1780
+ # Replace first two dashes with colons for date part, third with space
1781
+ parts = timestamp_clean.split('-')
1782
+ if len(parts) >= 4:
1783
+ # parts = ['2025', '10', '27', '19:31:20']
1784
+ formatted = f"{parts[0]}:{parts[1]}:{parts[2]} {'-'.join(parts[3:])}"
1785
+ return formatted
1786
+ except Exception:
1787
+ pass
1788
1788
 
1789
- return f"{main_part}.{fractional_part}{suffix}"
1789
+ # If parsing fails, return the cleaned string as-is
1790
+ return timestamp_clean
1790
1791
 
1791
1792
  def _get_current_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False, frame_id: Optional[str]=None) -> str:
1792
1793
  """Get formatted current timestamp based on stream type."""
1794
+
1793
1795
  if not stream_info:
1794
1796
  return "00:00:00.00"
1795
-
1796
1797
  if precision:
1797
1798
  if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
1798
1799
  if frame_id:
@@ -1801,7 +1802,6 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
1801
1802
  start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
1802
1803
  stream_time_str = self._format_timestamp_for_video(start_time)
1803
1804
 
1804
-
1805
1805
  return self._format_timestamp(stream_info.get("input_settings", {}).get("stream_time", "NA"))
1806
1806
  else:
1807
1807
  return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
@@ -1813,7 +1813,8 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
1813
1813
  start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
1814
1814
 
1815
1815
  stream_time_str = self._format_timestamp_for_video(start_time)
1816
-
1816
+
1817
+
1817
1818
  return self._format_timestamp(stream_info.get("input_settings", {}).get("stream_time", "NA"))
1818
1819
  else:
1819
1820
  stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
@@ -1835,23 +1836,57 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
1835
1836
 
1836
1837
  if precision:
1837
1838
  if self.start_timer is None:
1838
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
1839
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1840
+ if not candidate or candidate == "NA":
1841
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1842
+ self.start_timer = candidate
1839
1843
  return self._format_timestamp(self.start_timer)
1840
1844
  elif stream_info.get("input_settings", {}).get("start_frame", "na") == 1:
1841
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
1845
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1846
+ if not candidate or candidate == "NA":
1847
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1848
+ self.start_timer = candidate
1842
1849
  return self._format_timestamp(self.start_timer)
1843
1850
  else:
1844
1851
  return self._format_timestamp(self.start_timer)
1845
1852
 
1846
1853
  if self.start_timer is None:
1847
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
1854
+ # Prefer direct input_settings.stream_time if available and not NA
1855
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1856
+ if not candidate or candidate == "NA":
1857
+ # Fallback to nested stream_info.stream_time used by current timestamp path
1858
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
1859
+ if stream_time_str:
1860
+ try:
1861
+ timestamp_str = stream_time_str.replace(" UTC", "")
1862
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
1863
+ self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
1864
+ candidate = datetime.fromtimestamp(self._tracking_start_time, timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1865
+ except:
1866
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1867
+ else:
1868
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1869
+ self.start_timer = candidate
1848
1870
  return self._format_timestamp(self.start_timer)
1849
1871
  elif stream_info.get("input_settings", {}).get("start_frame", "na") == 1:
1850
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
1872
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1873
+ if not candidate or candidate == "NA":
1874
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
1875
+ if stream_time_str:
1876
+ try:
1877
+ timestamp_str = stream_time_str.replace(" UTC", "")
1878
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
1879
+ ts = dt.replace(tzinfo=timezone.utc).timestamp()
1880
+ candidate = datetime.fromtimestamp(ts, timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1881
+ except:
1882
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1883
+ else:
1884
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1885
+ self.start_timer = candidate
1851
1886
  return self._format_timestamp(self.start_timer)
1852
1887
 
1853
1888
  else:
1854
- if self.start_timer is not None:
1889
+ if self.start_timer is not None and self.start_timer != "NA":
1855
1890
  return self._format_timestamp(self.start_timer)
1856
1891
 
1857
1892
  if self._tracking_start_time is None:
@@ -37,12 +37,18 @@ CLIPProcessor = None
37
37
  ir_files = None
38
38
  ir_as_file = None
39
39
 
40
+ # Track auto-installation status (singleton pattern to avoid repeated attempts)
41
+ _installation_attempted = False
42
+ _installation_successful = False
43
+ _installation_error = None
44
+
40
45
  try:
41
46
  import onnxruntime as ort
42
47
  from PIL import Image
43
48
  from transformers import CLIPProcessor
44
49
  from importlib.resources import files as ir_files, as_file as ir_as_file
45
50
  print("✓ CLIP dependencies available (onnxruntime, PIL, transformers)")
51
+ _installation_successful = True # Already available
46
52
  except ImportError as e:
47
53
  print(f"⚠ CLIP dependencies not available at import time: {e}")
48
54
  print("→ Will attempt auto-installation when color detection is first used")
@@ -54,10 +60,28 @@ def try_install_clip_dependencies():
54
60
  """
55
61
  Attempt to install missing CLIP dependencies.
56
62
  Only called when ClipProcessor is actually instantiated (lazy installation).
63
+ Uses singleton pattern to ensure installation only happens ONCE per session.
57
64
  Returns True if successful, False otherwise.
58
65
  """
66
+ global _installation_attempted, _installation_successful, _installation_error
67
+
68
+ # Check if we already attempted installation
69
+ if _installation_attempted:
70
+ if _installation_successful:
71
+ print("✓ CLIP dependencies already available (from previous installation)")
72
+ return True
73
+ else:
74
+ print(f"✗ CLIP dependencies installation already failed previously")
75
+ if _installation_error:
76
+ print(f" Previous error: {_installation_error}")
77
+ print("→ Skipping repeated installation attempt")
78
+ return False
79
+
80
+ # Mark that we're attempting installation (prevents concurrent attempts)
81
+ _installation_attempted = True
82
+
59
83
  print("→ Color detection is being used but dependencies are missing")
60
- print("→ Attempting auto-installation of missing packages...")
84
+ print("→ Attempting ONE-TIME auto-installation of missing packages...")
61
85
 
62
86
  import platform
63
87
  import subprocess
@@ -128,6 +152,19 @@ def try_install_clip_dependencies():
128
152
  else:
129
153
  print("→ transformers is installed but import failed (may be incompatible with torch version)")
130
154
 
155
+ # Check for tqdm (required by transformers)
156
+ try:
157
+ import tqdm
158
+ print("→ tqdm imported successfully")
159
+ except ImportError:
160
+ if not is_package_installed("tqdm"):
161
+ print("→ tqdm not found, adding to install list")
162
+ packages_to_install.append("tqdm")
163
+ else:
164
+ print("→ tqdm is installed but import failed")
165
+ # Reinstall tqdm if it's broken
166
+ packages_to_install.append("tqdm")
167
+
131
168
  if not packages_to_install:
132
169
  print("→ All packages are available, retrying import...")
133
170
  else:
@@ -146,10 +183,14 @@ def try_install_clip_dependencies():
146
183
  if result.returncode == 0:
147
184
  print(f" ✓ {package} installed successfully")
148
185
  else:
149
- print(f"Failed to install {package}: {result.stderr}")
186
+ error_msg = f"Failed to install {package}: {result.stderr}"
187
+ print(f" ✗ {error_msg}")
188
+ _installation_error = error_msg
150
189
  return False
151
190
  except Exception as install_error:
152
- print(f"Installation failed: {install_error}")
191
+ error_msg = f"Installation failed: {install_error}"
192
+ print(f"✗ {error_msg}")
193
+ _installation_error = error_msg
153
194
  return False
154
195
 
155
196
  # Retry imports after installation (or if packages were already installed)
@@ -194,8 +235,10 @@ def try_install_clip_dependencies():
194
235
 
195
236
  # Check if we have at least the critical dependencies
196
237
  if ort_module is None or PILImage is None or CLIPProc is None:
197
- print(f"Critical dependencies missing after installation attempt")
198
- print(f" Errors: {'; '.join(import_errors)}")
238
+ error_msg = f"Critical dependencies missing: {'; '.join(import_errors)}"
239
+ print(f" {error_msg}")
240
+ _installation_error = error_msg
241
+ _installation_successful = False
199
242
  return False
200
243
 
201
244
  # Update global variables with successfully imported modules
@@ -206,6 +249,8 @@ def try_install_clip_dependencies():
206
249
  globals()['ir_as_file'] = ir_as_file_module
207
250
 
208
251
  print("✓ CLIP dependencies imported successfully!")
252
+ _installation_successful = True
253
+ _installation_error = None
209
254
  return True
210
255
 
211
256
  def load_model_from_checkpoint(checkpoint_url: str, providers: Optional[List] = None):
@@ -1617,6 +1617,53 @@ class ColorDetectionUseCase(BaseProcessor):
1617
1617
  seconds = round(float(timestamp % 60),2)
1618
1618
  return f"{hours:02d}:{minutes:02d}:{seconds:.1f}"
1619
1619
 
1620
+ def _format_timestamp(self, timestamp: Any) -> str:
1621
+ """Format a timestamp to match the current timestamp format: YYYY:MM:DD HH:MM:SS.
1622
+
1623
+ The input can be either:
1624
+ 1. A numeric Unix timestamp (``float`` / ``int``) – it will be converted to datetime.
1625
+ 2. A string in the format ``YYYY-MM-DD-HH:MM:SS.ffffff UTC``.
1626
+
1627
+ The returned value will be in the format: YYYY:MM:DD HH:MM:SS (no milliseconds, no UTC suffix).
1628
+
1629
+ Example
1630
+ -------
1631
+ >>> self._format_timestamp("2025-10-27-19:31:20.187574 UTC")
1632
+ '2025:10:27 19:31:20'
1633
+ """
1634
+
1635
+ # Convert numeric timestamps to datetime first
1636
+ if isinstance(timestamp, (int, float)):
1637
+ dt = datetime.fromtimestamp(timestamp, timezone.utc)
1638
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
1639
+
1640
+ # Ensure we are working with a string from here on
1641
+ if not isinstance(timestamp, str):
1642
+ return str(timestamp)
1643
+
1644
+ # Remove ' UTC' suffix if present
1645
+ timestamp_clean = timestamp.replace(' UTC', '').strip()
1646
+
1647
+ # Remove milliseconds if present (everything after the last dot)
1648
+ if '.' in timestamp_clean:
1649
+ timestamp_clean = timestamp_clean.split('.')[0]
1650
+
1651
+ # Parse the timestamp string and convert to desired format
1652
+ try:
1653
+ # Handle format: YYYY-MM-DD-HH:MM:SS
1654
+ if timestamp_clean.count('-') >= 2:
1655
+ # Replace first two dashes with colons for date part, third with space
1656
+ parts = timestamp_clean.split('-')
1657
+ if len(parts) >= 4:
1658
+ # parts = ['2025', '10', '27', '19:31:20']
1659
+ formatted = f"{parts[0]}:{parts[1]}:{parts[2]} {'-'.join(parts[3:])}"
1660
+ return formatted
1661
+ except Exception:
1662
+ pass
1663
+
1664
+ # If parsing fails, return the cleaned string as-is
1665
+ return timestamp_clean
1666
+
1620
1667
  def _get_current_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False, frame_id: Optional[str]=None) -> str:
1621
1668
  """Get formatted current timestamp based on stream type."""
1622
1669
 
@@ -1630,7 +1677,6 @@ class ColorDetectionUseCase(BaseProcessor):
1630
1677
  start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
1631
1678
  stream_time_str = self._format_timestamp_for_video(start_time)
1632
1679
 
1633
-
1634
1680
  return self._format_timestamp(stream_info.get("input_settings", {}).get("stream_time", "NA"))
1635
1681
  else:
1636
1682
  return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
@@ -1642,7 +1688,8 @@ class ColorDetectionUseCase(BaseProcessor):
1642
1688
  start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
1643
1689
 
1644
1690
  stream_time_str = self._format_timestamp_for_video(start_time)
1645
-
1691
+
1692
+
1646
1693
  return self._format_timestamp(stream_info.get("input_settings", {}).get("stream_time", "NA"))
1647
1694
  else:
1648
1695
  stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
@@ -1661,26 +1708,60 @@ class ColorDetectionUseCase(BaseProcessor):
1661
1708
  """Get formatted start timestamp for 'TOTAL SINCE' based on stream type."""
1662
1709
  if not stream_info:
1663
1710
  return "00:00:00"
1664
-
1711
+
1665
1712
  if precision:
1666
1713
  if self.start_timer is None:
1667
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC"))
1714
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1715
+ if not candidate or candidate == "NA":
1716
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1717
+ self.start_timer = candidate
1668
1718
  return self._format_timestamp(self.start_timer)
1669
1719
  elif stream_info.get("input_settings", {}).get("start_frame", "na") == 1:
1670
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC"))
1720
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1721
+ if not candidate or candidate == "NA":
1722
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1723
+ self.start_timer = candidate
1671
1724
  return self._format_timestamp(self.start_timer)
1672
1725
  else:
1673
1726
  return self._format_timestamp(self.start_timer)
1674
1727
 
1675
1728
  if self.start_timer is None:
1676
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC"))
1729
+ # Prefer direct input_settings.stream_time if available and not NA
1730
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1731
+ if not candidate or candidate == "NA":
1732
+ # Fallback to nested stream_info.stream_time used by current timestamp path
1733
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
1734
+ if stream_time_str:
1735
+ try:
1736
+ timestamp_str = stream_time_str.replace(" UTC", "")
1737
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
1738
+ self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
1739
+ candidate = datetime.fromtimestamp(self._tracking_start_time, timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1740
+ except:
1741
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1742
+ else:
1743
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1744
+ self.start_timer = candidate
1677
1745
  return self._format_timestamp(self.start_timer)
1678
1746
  elif stream_info.get("input_settings", {}).get("start_frame", "na") == 1:
1679
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC"))
1747
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1748
+ if not candidate or candidate == "NA":
1749
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
1750
+ if stream_time_str:
1751
+ try:
1752
+ timestamp_str = stream_time_str.replace(" UTC", "")
1753
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
1754
+ ts = dt.replace(tzinfo=timezone.utc).timestamp()
1755
+ candidate = datetime.fromtimestamp(ts, timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1756
+ except:
1757
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1758
+ else:
1759
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1760
+ self.start_timer = candidate
1680
1761
  return self._format_timestamp(self.start_timer)
1681
1762
 
1682
1763
  else:
1683
- if self.start_timer is not None:
1764
+ if self.start_timer is not None and self.start_timer != "NA":
1684
1765
  return self._format_timestamp(self.start_timer)
1685
1766
 
1686
1767
  if self._tracking_start_time is None:
@@ -1699,52 +1780,6 @@ class ColorDetectionUseCase(BaseProcessor):
1699
1780
  dt = dt.replace(minute=0, second=0, microsecond=0)
1700
1781
  return dt.strftime('%Y:%m:%d %H:%M:%S')
1701
1782
 
1702
- def _format_timestamp(self, timestamp: Any) -> str:
1703
- """Format a timestamp so that exactly two digits follow the decimal point (milliseconds).
1704
-
1705
- The input can be either:
1706
- 1. A numeric Unix timestamp (``float`` / ``int``) – it will first be converted to a
1707
- string in the format ``YYYY-MM-DD-HH:MM:SS.ffffff UTC``.
1708
- 2. A string already following the same layout.
1709
-
1710
- The returned value preserves the overall format of the input but truncates or pads
1711
- the fractional seconds portion to **exactly two digits**.
1712
-
1713
- Example
1714
- -------
1715
- >>> self._format_timestamp("2025-08-19-04:22:47.187574 UTC")
1716
- '2025-08-19-04:22:47.18 UTC'
1717
- """
1718
-
1719
- # Convert numeric timestamps to the expected string representation first
1720
- if isinstance(timestamp, (int, float)):
1721
- timestamp = datetime.fromtimestamp(timestamp, timezone.utc).strftime(
1722
- '%Y-%m-%d-%H:%M:%S.%f UTC'
1723
- )
1724
-
1725
- # Ensure we are working with a string from here on
1726
- if not isinstance(timestamp, str):
1727
- return str(timestamp)
1728
-
1729
- # If there is no fractional component, simply return the original string
1730
- if '.' not in timestamp:
1731
- return timestamp
1732
-
1733
- # Split out the main portion (up to the decimal point)
1734
- main_part, fractional_and_suffix = timestamp.split('.', 1)
1735
-
1736
- # Separate fractional digits from the suffix (typically ' UTC')
1737
- if ' ' in fractional_and_suffix:
1738
- fractional_part, suffix = fractional_and_suffix.split(' ', 1)
1739
- suffix = ' ' + suffix # Re-attach the space removed by split
1740
- else:
1741
- fractional_part, suffix = fractional_and_suffix, ''
1742
-
1743
- # Guarantee exactly two digits for the fractional part
1744
- fractional_part = (fractional_part + '00')[:2]
1745
-
1746
- return f"{main_part}.{fractional_part}{suffix}"
1747
-
1748
1783
  def _get_tracking_start_time(self) -> str:
1749
1784
  """Get the tracking start time, formatted as a string."""
1750
1785
  if self._tracking_start_time is None: