matrice-analytics 0.1.43__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.43 → matrice_analytics-0.1.44}/PKG-INFO +1 -1
  2. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/PKG-INFO +1 -1
  3. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/face_recognition.py +70 -35
  4. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color_detection.py +89 -54
  5. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/fire_detection.py +89 -54
  6. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/license_plate_monitoring.py +81 -46
  7. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/people_counting.py +29 -28
  8. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/vehicle_monitoring.py +89 -54
  9. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/LICENSE.txt +0 -0
  10. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/README.md +0 -0
  11. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/SOURCES.txt +0 -0
  12. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/dependency_links.txt +0 -0
  13. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/not-zip-safe +0 -0
  14. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/matrice_analytics.egg-info/top_level.txt +0 -0
  15. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/pyproject.toml +0 -0
  16. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/setup.cfg +0 -0
  17. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/setup.py +0 -0
  18. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/__init__.py +0 -0
  19. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/README.md +0 -0
  20. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/__init__.py +0 -0
  21. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_internal.py +0 -0
  22. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_tool.py +0 -0
  23. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/boundary_tool_template.html +0 -0
  24. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/example_usage.py +0 -0
  25. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/usage/README.md +0 -0
  26. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/usage/boundary_drawer_launcher.py +0 -0
  27. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py +0 -0
  28. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/README.md +0 -0
  29. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/__init__.py +0 -0
  30. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/README.md +0 -0
  31. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/__init__.py +0 -0
  32. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/base.py +0 -0
  33. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/config.py +0 -0
  34. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/kalman_filter.py +0 -0
  35. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/matching.py +0 -0
  36. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/strack.py +0 -0
  37. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/advanced_tracker/tracker.py +0 -0
  38. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/config.py +0 -0
  39. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/__init__.py +0 -0
  40. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/base.py +0 -0
  41. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/config.py +0 -0
  42. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/core/config_utils.py +0 -0
  43. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/__init__.py +0 -0
  44. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/compare_similarity.py +0 -0
  45. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/embedding_manager.py +0 -0
  46. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/face_recognition_client.py +0 -0
  47. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/face_reg/people_activity_logging.py +0 -0
  48. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/__init__.py +0 -0
  49. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/easyocr_extractor.py +0 -0
  50. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/__init__.py +0 -0
  51. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/__init__.py +0 -0
  52. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/cli.py +0 -0
  53. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/dataset_stats.py +0 -0
  54. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/export.py +0 -0
  55. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/train.py +0 -0
  56. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/utils.py +0 -0
  57. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/valid.py +0 -0
  58. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/validate_dataset.py +0 -0
  59. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_augmentation.py +0 -0
  60. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_predictions.py +0 -0
  61. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/__init__.py +0 -0
  62. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/process.py +0 -0
  63. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/types.py +0 -0
  64. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/utils.py +0 -0
  65. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/__init__.py +0 -0
  66. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/config.py +0 -0
  67. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/hub.py +0 -0
  68. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/plate_recognizer.py +0 -0
  69. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/py.typed +0 -0
  70. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/__init__.py +0 -0
  71. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/__init__.py +0 -0
  72. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/augmentation.py +0 -0
  73. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/dataset.py +0 -0
  74. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/__init__.py +0 -0
  75. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/config.py +0 -0
  76. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/layers.py +0 -0
  77. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/loss.py +0 -0
  78. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/metric.py +0 -0
  79. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_builders.py +0 -0
  80. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_schema.py +0 -0
  81. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/__init__.py +0 -0
  82. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/backend_utils.py +0 -0
  83. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/utils.py +0 -0
  84. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/postprocessing.py +0 -0
  85. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/ocr/preprocessing.py +0 -0
  86. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/post_processor.py +0 -0
  87. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/__init__.py +0 -0
  88. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/run_tests.py +0 -0
  89. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_advanced_customer_service.py +0 -0
  90. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_basic_counting_tracking.py +0 -0
  91. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_comprehensive.py +0 -0
  92. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_config.py +0 -0
  93. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_customer_service.py +0 -0
  94. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_data_generators.py +0 -0
  95. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_people_counting.py +0 -0
  96. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_processor.py +0 -0
  97. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_utilities.py +0 -0
  98. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/test_cases/test_utils.py +0 -0
  99. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py +0 -0
  100. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/__init__.py +0 -0
  101. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/abandoned_object_detection.py +0 -0
  102. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/advanced_customer_service.py +0 -0
  103. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/age_detection.py +0 -0
  104. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/age_gender_detection.py +0 -0
  105. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/anti_spoofing_detection.py +0 -0
  106. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/assembly_line_detection.py +0 -0
  107. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/banana_defect_detection.py +0 -0
  108. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/basic_counting_tracking.py +0 -0
  109. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/blood_cancer_detection_img.py +0 -0
  110. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/car_damage_detection.py +0 -0
  111. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/car_part_segmentation.py +0 -0
  112. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/car_service.py +0 -0
  113. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/cardiomegaly_classification.py +0 -0
  114. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/cell_microscopy_segmentation.py +0 -0
  115. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/chicken_pose_detection.py +0 -0
  116. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/child_monitoring.py +0 -0
  117. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip.py +0 -0
  118. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/merges.txt +0 -0
  119. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/preprocessor_config.json +0 -0
  120. {matrice_analytics-0.1.43 → 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.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer.json +0 -0
  122. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer_config.json +0 -0
  123. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/clip_processor/vocab.json +0 -0
  124. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/color_map_utils.py +0 -0
  125. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color/color_mapper.py +0 -0
  126. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/color_map_utils.py +0 -0
  127. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/concrete_crack_detection.py +0 -0
  128. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/crop_weed_detection.py +0 -0
  129. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/customer_service.py +0 -0
  130. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/defect_detection_products.py +0 -0
  131. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/distracted_driver_detection.py +0 -0
  132. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/drone_traffic_monitoring.py +0 -0
  133. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/drowsy_driver_detection.py +0 -0
  134. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/dwell_detection.py +0 -0
  135. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/emergency_vehicle_detection.py +0 -0
  136. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/face_emotion.py +0 -0
  137. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/face_recognition.py +0 -0
  138. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/fashion_detection.py +0 -0
  139. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/field_mapping.py +0 -0
  140. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/flare_analysis.py +0 -0
  141. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/flower_segmentation.py +0 -0
  142. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/gas_leak_detection.py +0 -0
  143. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/gender_detection.py +0 -0
  144. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/human_activity_recognition.py +0 -0
  145. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/intrusion_detection.py +0 -0
  146. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/leaf.py +0 -0
  147. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/leaf_disease.py +0 -0
  148. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/leak_detection.py +0 -0
  149. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/license_plate_detection.py +0 -0
  150. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/litter_monitoring.py +0 -0
  151. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/mask_detection.py +0 -0
  152. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/natural_disaster.py +0 -0
  153. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/parking.py +0 -0
  154. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/parking_space_detection.py +0 -0
  155. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pcb_defect_detection.py +0 -0
  156. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pedestrian_detection.py +0 -0
  157. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/people_counting_bckp.py +0 -0
  158. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/people_tracking.py +0 -0
  159. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pipeline_detection.py +0 -0
  160. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/plaque_segmentation_img.py +0 -0
  161. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/pothole_segmentation.py +0 -0
  162. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/ppe_compliance.py +0 -0
  163. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/price_tag_detection.py +0 -0
  164. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/proximity_detection.py +0 -0
  165. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/road_lane_detection.py +0 -0
  166. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/road_traffic_density.py +0 -0
  167. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/road_view_segmentation.py +0 -0
  168. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/shelf_inventory_detection.py +0 -0
  169. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/shoplifting_detection.py +0 -0
  170. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/shopping_cart_analysis.py +0 -0
  171. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/skin_cancer_classification_img.py +0 -0
  172. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/smoker_detection.py +0 -0
  173. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/solar_panel.py +0 -0
  174. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/suspicious_activity_detection.py +0 -0
  175. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/template_usecase.py +0 -0
  176. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/theft_detection.py +0 -0
  177. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/traffic_sign_monitoring.py +0 -0
  178. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/underground_pipeline_defect_detection.py +0 -0
  179. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/underwater_pollution_detection.py +0 -0
  180. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/warehouse_object_segmentation.py +0 -0
  181. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/waterbody_segmentation.py +0 -0
  182. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/weapon_detection.py +0 -0
  183. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/weld_defect_detection.py +0 -0
  184. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/wildlife_monitoring.py +0 -0
  185. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/windmill_maintenance.py +0 -0
  186. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/usecases/wound_segmentation.py +0 -0
  187. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/__init__.py +0 -0
  188. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/advanced_counting_utils.py +0 -0
  189. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/advanced_helper_utils.py +0 -0
  190. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/advanced_tracking_utils.py +0 -0
  191. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/alerting_utils.py +0 -0
  192. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/category_mapping_utils.py +0 -0
  193. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/color_utils.py +0 -0
  194. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/counting_utils.py +0 -0
  195. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/filter_utils.py +0 -0
  196. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/format_utils.py +0 -0
  197. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/geometry_utils.py +0 -0
  198. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/smoothing_utils.py +0 -0
  199. {matrice_analytics-0.1.43 → matrice_analytics-0.1.44}/src/matrice_analytics/post_processing/utils/tracking_utils.py +0 -0
  200. {matrice_analytics-0.1.43 → 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.43
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.43
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:
@@ -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:
@@ -892,11 +892,58 @@ class FireSmokeUseCase(BaseProcessor):
892
892
  seconds = round(float(timestamp % 60), 2)
893
893
  return f"{hours:02d}:{minutes:02d}:{seconds:.1f}"
894
894
 
895
+ def _format_timestamp(self, timestamp: Any) -> str:
896
+ """Format a timestamp to match the current timestamp format: YYYY:MM:DD HH:MM:SS.
897
+
898
+ The input can be either:
899
+ 1. A numeric Unix timestamp (``float`` / ``int``) – it will be converted to datetime.
900
+ 2. A string in the format ``YYYY-MM-DD-HH:MM:SS.ffffff UTC``.
901
+
902
+ The returned value will be in the format: YYYY:MM:DD HH:MM:SS (no milliseconds, no UTC suffix).
903
+
904
+ Example
905
+ -------
906
+ >>> self._format_timestamp("2025-10-27-19:31:20.187574 UTC")
907
+ '2025:10:27 19:31:20'
908
+ """
909
+
910
+ # Convert numeric timestamps to datetime first
911
+ if isinstance(timestamp, (int, float)):
912
+ dt = datetime.fromtimestamp(timestamp, timezone.utc)
913
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
914
+
915
+ # Ensure we are working with a string from here on
916
+ if not isinstance(timestamp, str):
917
+ return str(timestamp)
918
+
919
+ # Remove ' UTC' suffix if present
920
+ timestamp_clean = timestamp.replace(' UTC', '').strip()
921
+
922
+ # Remove milliseconds if present (everything after the last dot)
923
+ if '.' in timestamp_clean:
924
+ timestamp_clean = timestamp_clean.split('.')[0]
925
+
926
+ # Parse the timestamp string and convert to desired format
927
+ try:
928
+ # Handle format: YYYY-MM-DD-HH:MM:SS
929
+ if timestamp_clean.count('-') >= 2:
930
+ # Replace first two dashes with colons for date part, third with space
931
+ parts = timestamp_clean.split('-')
932
+ if len(parts) >= 4:
933
+ # parts = ['2025', '10', '27', '19:31:20']
934
+ formatted = f"{parts[0]}:{parts[1]}:{parts[2]} {'-'.join(parts[3:])}"
935
+ return formatted
936
+ except Exception:
937
+ pass
938
+
939
+ # If parsing fails, return the cleaned string as-is
940
+ return timestamp_clean
941
+
895
942
  def _get_current_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False, frame_id: Optional[str]=None) -> str:
896
943
  """Get formatted current timestamp based on stream type."""
944
+
897
945
  if not stream_info:
898
946
  return "00:00:00.00"
899
-
900
947
  if precision:
901
948
  if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
902
949
  if frame_id:
@@ -905,7 +952,6 @@ class FireSmokeUseCase(BaseProcessor):
905
952
  start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
906
953
  stream_time_str = self._format_timestamp_for_video(start_time)
907
954
 
908
-
909
955
  return self._format_timestamp(stream_info.get("input_settings", {}).get("stream_time", "NA"))
910
956
  else:
911
957
  return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
@@ -917,7 +963,8 @@ class FireSmokeUseCase(BaseProcessor):
917
963
  start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
918
964
 
919
965
  stream_time_str = self._format_timestamp_for_video(start_time)
920
-
966
+
967
+
921
968
  return self._format_timestamp(stream_info.get("input_settings", {}).get("stream_time", "NA"))
922
969
  else:
923
970
  stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
@@ -939,23 +986,57 @@ class FireSmokeUseCase(BaseProcessor):
939
986
 
940
987
  if precision:
941
988
  if self.start_timer is None:
942
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
989
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
990
+ if not candidate or candidate == "NA":
991
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
992
+ self.start_timer = candidate
943
993
  return self._format_timestamp(self.start_timer)
944
994
  elif stream_info.get("input_settings", {}).get("start_frame", "na") == 1:
945
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
995
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
996
+ if not candidate or candidate == "NA":
997
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
998
+ self.start_timer = candidate
946
999
  return self._format_timestamp(self.start_timer)
947
1000
  else:
948
1001
  return self._format_timestamp(self.start_timer)
949
1002
 
950
1003
  if self.start_timer is None:
951
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
1004
+ # Prefer direct input_settings.stream_time if available and not NA
1005
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1006
+ if not candidate or candidate == "NA":
1007
+ # Fallback to nested stream_info.stream_time used by current timestamp path
1008
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
1009
+ if stream_time_str:
1010
+ try:
1011
+ timestamp_str = stream_time_str.replace(" UTC", "")
1012
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
1013
+ self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
1014
+ candidate = datetime.fromtimestamp(self._tracking_start_time, timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1015
+ except:
1016
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1017
+ else:
1018
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1019
+ self.start_timer = candidate
952
1020
  return self._format_timestamp(self.start_timer)
953
1021
  elif stream_info.get("input_settings", {}).get("start_frame", "na") == 1:
954
- self.start_timer = stream_info.get("input_settings", {}).get("stream_time", "NA")
1022
+ candidate = stream_info.get("input_settings", {}).get("stream_time")
1023
+ if not candidate or candidate == "NA":
1024
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
1025
+ if stream_time_str:
1026
+ try:
1027
+ timestamp_str = stream_time_str.replace(" UTC", "")
1028
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
1029
+ ts = dt.replace(tzinfo=timezone.utc).timestamp()
1030
+ candidate = datetime.fromtimestamp(ts, timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1031
+ except:
1032
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1033
+ else:
1034
+ candidate = datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
1035
+ self.start_timer = candidate
955
1036
  return self._format_timestamp(self.start_timer)
956
1037
 
957
1038
  else:
958
- if self.start_timer is not None:
1039
+ if self.start_timer is not None and self.start_timer != "NA":
959
1040
  return self._format_timestamp(self.start_timer)
960
1041
 
961
1042
  if self._tracking_start_time is None:
@@ -974,52 +1055,6 @@ class FireSmokeUseCase(BaseProcessor):
974
1055
  dt = dt.replace(minute=0, second=0, microsecond=0)
975
1056
  return dt.strftime('%Y:%m:%d %H:%M:%S')
976
1057
 
977
- def _format_timestamp(self, timestamp: Any) -> str:
978
- """Format a timestamp so that exactly two digits follow the decimal point (milliseconds).
979
-
980
- The input can be either:
981
- 1. A numeric Unix timestamp (``float`` / ``int``) – it will first be converted to a
982
- string in the format ``YYYY-MM-DD-HH:MM:SS.ffffff UTC``.
983
- 2. A string already following the same layout.
984
-
985
- The returned value preserves the overall format of the input but truncates or pads
986
- the fractional seconds portion to **exactly two digits**.
987
-
988
- Example
989
- -------
990
- >>> self._format_timestamp("2025-08-19-04:22:47.187574 UTC")
991
- '2025-08-19-04:22:47.18 UTC'
992
- """
993
-
994
- # Convert numeric timestamps to the expected string representation first
995
- if isinstance(timestamp, (int, float)):
996
- timestamp = datetime.fromtimestamp(timestamp, timezone.utc).strftime(
997
- '%Y-%m-%d-%H:%M:%S.%f UTC'
998
- )
999
-
1000
- # Ensure we are working with a string from here on
1001
- if not isinstance(timestamp, str):
1002
- return str(timestamp)
1003
-
1004
- # If there is no fractional component, simply return the original string
1005
- if '.' not in timestamp:
1006
- return timestamp
1007
-
1008
- # Split out the main portion (up to the decimal point)
1009
- main_part, fractional_and_suffix = timestamp.split('.', 1)
1010
-
1011
- # Separate fractional digits from the suffix (typically ' UTC')
1012
- if ' ' in fractional_and_suffix:
1013
- fractional_part, suffix = fractional_and_suffix.split(' ', 1)
1014
- suffix = ' ' + suffix # Re-attach the space removed by split
1015
- else:
1016
- fractional_part, suffix = fractional_and_suffix, ''
1017
-
1018
- # Guarantee exactly two digits for the fractional part
1019
- fractional_part = (fractional_part + '00')[:2]
1020
-
1021
- return f"{main_part}.{fractional_part}{suffix}"
1022
-
1023
1058
  def get_duration_seconds(self, start_time, end_time):
1024
1059
  def parse_relative_time(t):
1025
1060
  """Parse HH:MM:SS(.f) manually into timedelta"""