matrice 1.0.99141__tar.gz → 1.0.99143__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.
Files changed (239) hide show
  1. {matrice-1.0.99141/src/matrice.egg-info → matrice-1.0.99143}/PKG-INFO +1 -1
  2. {matrice-1.0.99141 → matrice-1.0.99143}/setup.py +1 -1
  3. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/config.py +4 -0
  4. matrice-1.0.99143/src/matrice/deploy/utils/post_processing/usecases/road_lane_detection.py +610 -0
  5. matrice-1.0.99143/src/matrice/deploy/utils/post_processing/usecases/shelf_inventory_detection.py +583 -0
  6. {matrice-1.0.99141 → matrice-1.0.99143/src/matrice.egg-info}/PKG-INFO +1 -1
  7. matrice-1.0.99141/src/matrice/deploy/utils/post_processing/usecases/road_lane_detection.py +0 -606
  8. matrice-1.0.99141/src/matrice/deploy/utils/post_processing/usecases/shelf_inventory_detection.py +0 -618
  9. {matrice-1.0.99141 → matrice-1.0.99143}/LICENSE.txt +0 -0
  10. {matrice-1.0.99141 → matrice-1.0.99143}/README.md +0 -0
  11. {matrice-1.0.99141 → matrice-1.0.99143}/setup.cfg +0 -0
  12. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/__init__.py +0 -0
  13. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/action.py +0 -0
  14. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/actionTracker.py +0 -0
  15. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/action_tracker.py +0 -0
  16. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/annotation.py +0 -0
  17. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/app_store.py +0 -0
  18. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/application.py +0 -0
  19. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute.py +0 -0
  20. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/__init__.py +0 -0
  21. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/action_instance.py +0 -0
  22. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/actions_manager.py +0 -0
  23. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/actions_scaledown_manager.py +0 -0
  24. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/instance_manager.py +0 -0
  25. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/instance_utils.py +0 -0
  26. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/prechecks.py +0 -0
  27. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/resources_tracker.py +0 -0
  28. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/scaling.py +0 -0
  29. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/shutdown_manager.py +0 -0
  30. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/compute_manager/task_utils.py +0 -0
  31. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/__init__.py +0 -0
  32. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/__init__.py +0 -0
  33. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/base.py +0 -0
  34. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/__init__.py +0 -0
  35. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/bit_depth_reduction.py +0 -0
  36. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/blur.py +0 -0
  37. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/brightness_contrast.py +0 -0
  38. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/color_jitter.py +0 -0
  39. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/compression_artifacts.py +0 -0
  40. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/downscale_upscale.py +0 -0
  41. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/film_grain.py +0 -0
  42. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/flip.py +0 -0
  43. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/fog.py +0 -0
  44. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/horizontal_flip.py +0 -0
  45. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/hsv.py +0 -0
  46. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/iso_noise.py +0 -0
  47. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/low_light.py +0 -0
  48. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/posterize.py +0 -0
  49. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/rain.py +0 -0
  50. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/random_affine.py +0 -0
  51. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/salt_pepper.py +0 -0
  52. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/shadows.py +0 -0
  53. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/snow.py +0 -0
  54. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/speckle.py +0 -0
  55. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/augmentation_utils/strategies/sunflare.py +0 -0
  56. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/client.py +0 -0
  57. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/client_utils.py +0 -0
  58. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/create_dataset.py +0 -0
  59. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_augmentation.py +0 -0
  60. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_augmentor.py +0 -0
  61. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/__init__.py +0 -0
  62. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/imagenet_classification.py +0 -0
  63. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/labelbox_classification.py +0 -0
  64. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/labelbox_detection.py +0 -0
  65. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/mscoco_detection.py +0 -0
  66. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/pascalvoc_detection.py +0 -0
  67. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/unlabelled.py +0 -0
  68. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_davis_segmentation.py +0 -0
  69. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_detection_mscoco.py +0 -0
  70. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_imagenet_classification.py +0 -0
  71. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_kinetics_activity_recognition.py +0 -0
  72. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_mot_tracking.py +0 -0
  73. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_mscoco_detection.py +0 -0
  74. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/video_youtube_bb_tracking.py +0 -0
  75. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_formats/yolo_detection.py +0 -0
  76. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_labelling.py +0 -0
  77. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_prep.py +0 -0
  78. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/data_processor.py +0 -0
  79. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/image_augmentations.py +0 -0
  80. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/image_data_augmentation.py +0 -0
  81. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/new_data_augmentation.py +0 -0
  82. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/pipeline.py +0 -0
  83. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/server.py +0 -0
  84. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/server_utils.py +0 -0
  85. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/data_processing/video_server.py +0 -0
  86. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/dataset.py +0 -0
  87. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/__init__.py +0 -0
  88. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/aggregator/__init__.py +0 -0
  89. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/aggregator/aggregator.py +0 -0
  90. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/aggregator/ingestor.py +0 -0
  91. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/aggregator/pipeline.py +0 -0
  92. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/aggregator/publisher.py +0 -0
  93. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/aggregator/synchronizer.py +0 -0
  94. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/__init__.py +0 -0
  95. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/auto_streaming/__init__.py +0 -0
  96. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/auto_streaming/auto_streaming.py +0 -0
  97. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/auto_streaming/auto_streaming_utils.py +0 -0
  98. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/client.py +0 -0
  99. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/client_stream_utils.py +0 -0
  100. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/client_utils.py +0 -0
  101. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/frame_comparators.py +0 -0
  102. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/streaming_gateway/__init__.py +0 -0
  103. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/streaming_gateway/streaming_gateway.py +0 -0
  104. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/streaming_gateway/streaming_gateway_utils.py +0 -0
  105. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/client/streaming_gateway/streaming_results_handler.py +0 -0
  106. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/__init__.py +0 -0
  107. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/inference/__init__.py +0 -0
  108. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/inference/batch_manager.py +0 -0
  109. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/inference/cache_manager.py +0 -0
  110. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/inference/inference_interface.py +0 -0
  111. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/inference/model_manager.py +0 -0
  112. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/inference/triton_utils.py +0 -0
  113. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/proxy/__init__.py +0 -0
  114. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/proxy/proxy_interface.py +0 -0
  115. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/proxy/proxy_utils.py +0 -0
  116. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/server.py +0 -0
  117. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/server/stream_worker.py +0 -0
  118. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/__init__.py +0 -0
  119. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/boundary_drawing_internal/__init__.py +0 -0
  120. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/boundary_drawing_internal/boundary_drawing_internal.py +0 -0
  121. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/boundary_drawing_internal/boundary_drawing_tool.py +0 -0
  122. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/boundary_drawing_internal/example_usage.py +0 -0
  123. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/kafka_utils.py +0 -0
  124. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/__init__.py +0 -0
  125. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/__init__.py +0 -0
  126. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/base.py +0 -0
  127. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/config.py +0 -0
  128. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/kalman_filter.py +0 -0
  129. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/matching.py +0 -0
  130. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/strack.py +0 -0
  131. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/advanced_tracker/tracker.py +0 -0
  132. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/core/__init__.py +0 -0
  133. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/core/base.py +0 -0
  134. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/core/config.py +0 -0
  135. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/core/config_utils.py +0 -0
  136. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/processor.py +0 -0
  137. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/__init__.py +0 -0
  138. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/run_tests.py +0 -0
  139. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_advanced_customer_service.py +0 -0
  140. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_basic_counting_tracking.py +0 -0
  141. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_comprehensive.py +0 -0
  142. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_config.py +0 -0
  143. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_customer_service.py +0 -0
  144. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_data_generators.py +0 -0
  145. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_people_counting.py +0 -0
  146. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_processor.py +0 -0
  147. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_utilities.py +0 -0
  148. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/test_cases/test_utils.py +0 -0
  149. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/__init__.py +0 -0
  150. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/advanced_customer_service.py +0 -0
  151. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/age_detection.py +0 -0
  152. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/anti_spoofing_detection.py +0 -0
  153. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/assembly_line_detection.py +0 -0
  154. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/banana_defect_detection.py +0 -0
  155. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/basic_counting_tracking.py +0 -0
  156. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/blood_cancer_detection_img.py +0 -0
  157. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/car_damage_detection.py +0 -0
  158. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/car_part_segmentation.py +0 -0
  159. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/chicken_pose_detection.py +0 -0
  160. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/child_monitoring.py +0 -0
  161. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/color_detection.py +0 -0
  162. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/color_map_utils.py +0 -0
  163. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/concrete_crack_detection.py +0 -0
  164. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/crop_weed_detection.py +0 -0
  165. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/customer_service.py +0 -0
  166. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/defect_detection_products.py +0 -0
  167. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/distracted_driver_detection.py +0 -0
  168. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/emergency_vehicle_detection.py +0 -0
  169. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/face_emotion.py +0 -0
  170. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/fashion_detection.py +0 -0
  171. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/field_mapping.py +0 -0
  172. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/fire_detection.py +0 -0
  173. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/flare_analysis.py +0 -0
  174. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/flower_segmentation.py +0 -0
  175. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/gender_detection.py +0 -0
  176. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/leaf.py +0 -0
  177. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/leaf_disease.py +0 -0
  178. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/license_plate_detection.py +0 -0
  179. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/mask_detection.py +0 -0
  180. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/parking.py +0 -0
  181. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/parking_space_detection.py +0 -0
  182. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/pedestrian_detection.py +0 -0
  183. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/people_counting.py +0 -0
  184. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/plaque_segmentation_img.py +0 -0
  185. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/pothole_segmentation.py +0 -0
  186. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/ppe_compliance.py +0 -0
  187. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/price_tag_detection.py +0 -0
  188. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/shoplifting_detection.py +0 -0
  189. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/shopping_cart_analysis.py +0 -0
  190. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/skin_cancer_classification_img.py +0 -0
  191. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/solar_panel.py +0 -0
  192. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/template_usecase.py +0 -0
  193. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/theft_detection.py +0 -0
  194. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/traffic_sign_monitoring.py +0 -0
  195. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/underwater_pollution_detection.py +0 -0
  196. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/vehicle_monitoring.py +0 -0
  197. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/warehouse_object_segmentation.py +0 -0
  198. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/weapon_detection.py +0 -0
  199. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/weld_defect_detection.py +0 -0
  200. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/windmill_maintenance.py +0 -0
  201. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/usecases/wound_segmentation.py +0 -0
  202. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/__init__.py +0 -0
  203. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/advanced_counting_utils.py +0 -0
  204. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/advanced_helper_utils.py +0 -0
  205. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/advanced_tracking_utils.py +0 -0
  206. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/alerting_utils.py +0 -0
  207. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/category_mapping_utils.py +0 -0
  208. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/color_utils.py +0 -0
  209. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/counting_utils.py +0 -0
  210. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/filter_utils.py +0 -0
  211. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/format_utils.py +0 -0
  212. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/geometry_utils.py +0 -0
  213. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/smoothing_utils.py +0 -0
  214. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deploy/utils/post_processing/utils/tracking_utils.py +0 -0
  215. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deployment/__init__.py +0 -0
  216. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deployment/camera_manager.py +0 -0
  217. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deployment/deployment.py +0 -0
  218. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deployment/inference_pipeline.py +0 -0
  219. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/deployment/streaming_gateway_manager.py +0 -0
  220. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/docker_utils.py +0 -0
  221. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/drift_monitor.py +0 -0
  222. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/exported_model.py +0 -0
  223. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/local_test.py +0 -0
  224. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/metrics_calculator.py +0 -0
  225. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/metrics_calculator_oop.py +0 -0
  226. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/model_store.py +0 -0
  227. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/models.py +0 -0
  228. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/pipeline.py +0 -0
  229. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/projects.py +0 -0
  230. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/rpc.py +0 -0
  231. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/scaling.py +0 -0
  232. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/session.py +0 -0
  233. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/testing.py +0 -0
  234. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/token_auth.py +0 -0
  235. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice/utils.py +0 -0
  236. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice.egg-info/SOURCES.txt +0 -0
  237. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice.egg-info/dependency_links.txt +0 -0
  238. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice.egg-info/requires.txt +0 -0
  239. {matrice-1.0.99141 → matrice-1.0.99143}/src/matrice.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice
3
- Version: 1.0.99141
3
+ Version: 1.0.99143
4
4
  Summary: SDK for connecting to matrice.ai services
5
5
  Home-page: https://github.com/matrice-ai/python-sdk
6
6
  Author: Matrice.ai
@@ -14,7 +14,7 @@ long_description = (here / "README.md").read_text(encoding="utf-8")
14
14
  setup(
15
15
  name="matrice",
16
16
 
17
- version = "1.0.99141",
17
+ version = "1.0.99143",
18
18
 
19
19
  description="SDK for connecting to matrice.ai services",
20
20
  long_description=long_description,
@@ -26,6 +26,8 @@ APP_NAME_TO_USECASE = {
26
26
  "weld_defect_detection" : "weld_defect_detection",
27
27
  "fruit_monitoring" : "fruit_monitoring",
28
28
  "concrete_crack_detection": "concrete_crack_detection",
29
+ "lane_detection" : "lane_detection",
30
+ "shelf_inventory" :"shelf_inventory",
29
31
  }
30
32
 
31
33
  APP_NAME_TO_CATEGORY = {
@@ -56,6 +58,8 @@ APP_NAME_TO_CATEGORY = {
56
58
  "weld_defect_detection" : "weld",
57
59
  "fruit_monitoring" : "agriculture",
58
60
  "concrete_crack_detection": "general",
61
+ "lane_detection" : "traffic",
62
+ "shelf_inventory" : "retail",
59
63
  }
60
64
 
61
65
  def get_usecase_from_app_name(app_name: str) -> str:
@@ -0,0 +1,610 @@
1
+ from typing import Any, Dict, List, Optional
2
+ from dataclasses import asdict, dataclass, field
3
+ import time
4
+ from datetime import datetime, timezone
5
+
6
+ from ..core.base import BaseProcessor, ProcessingContext, ProcessingResult, ConfigProtocol
7
+ from ..utils import (
8
+ filter_by_confidence,
9
+ filter_by_categories,
10
+ apply_category_mapping,
11
+ count_objects_by_category,
12
+ count_objects_in_zones,
13
+ calculate_counting_summary,
14
+ match_results_structure,
15
+ bbox_smoothing,
16
+ BBoxSmoothingConfig,
17
+ BBoxSmoothingTracker
18
+ )
19
+ from ..core.config import BaseConfig, AlertConfig, ZoneConfig
20
+
21
+
22
+ @dataclass
23
+ class LaneDetectionConfig(BaseConfig):
24
+ """Configuration for lane detection use case in road monitoring."""
25
+ enable_smoothing: bool = True
26
+ smoothing_algorithm: str = "observability"
27
+ smoothing_window_size: int = 20
28
+ smoothing_cooldown_frames: int = 5
29
+ smoothing_confidence_range_factor: float = 0.5
30
+ confidence_threshold: float = 0.6
31
+ usecase_categories: List[str] = field(
32
+ default_factory=lambda: ['Divider-Line', 'Dotted-Line', 'Double-Line', 'Random-Line', 'Road-Sign-Line', 'Solid-Line']
33
+ )
34
+ target_categories: List[str] = field(
35
+ default_factory=lambda: ['Divider-Line', 'Dotted-Line', 'Double-Line', 'Random-Line', 'Road-Sign-Line', 'Solid-Line']
36
+ )
37
+ alert_config: Optional[AlertConfig] = None
38
+ index_to_category: Optional[Dict[int, str]] = field(
39
+ default_factory=lambda: {
40
+ 0: "Divider-Line",
41
+ 1: "Dotted-Line",
42
+ 2: "Double-Line",
43
+ 3: "Random-Line",
44
+ 4: "Road-Sign-Line",
45
+ 5: "Solid-Line"
46
+ }
47
+ )
48
+
49
+
50
+ class LaneDetectionUseCase(BaseProcessor):
51
+ CATEGORY_DISPLAY = {
52
+ "Divider-Line": "Divider Line",
53
+ "Dotted-Line": "Dotted Line",
54
+ "Double-Line": "Double Line",
55
+ "Random-Line": "Random Line",
56
+ "Road-Sign-Line": "Road Sign Line",
57
+ "Solid-Line": "Solid Line"
58
+ }
59
+
60
+ def __init__(self):
61
+ super().__init__("lane_detection")
62
+ self.category = "traffic"
63
+ self.CASE_TYPE: Optional[str] = 'lane_detection'
64
+ self.CASE_VERSION: Optional[str] = '1.0'
65
+ self.target_categories = ['Divider-Line', 'Dotted-Line', 'Double-Line', 'Random-Line', 'Road-Sign-Line', 'Solid-Line']
66
+ self.smoothing_tracker = None
67
+ self.tracker = None
68
+ self._total_frame_counter = 0
69
+ self._global_frame_offset = 0
70
+ self._tracking_start_time = None
71
+ self._track_aliases: Dict[Any, Any] = {}
72
+ self._canonical_tracks: Dict[Any, Dict[str, Any]] = {}
73
+ self._track_merge_iou_threshold: float = 0.05
74
+ self._track_merge_time_window: float = 7.0
75
+ self._ascending_alert_list: List[int] = []
76
+ self.current_incident_end_timestamp: str = "N/A"
77
+
78
+ def process(self, data: Any, config: ConfigProtocol, context: Optional[ProcessingContext] = None,
79
+ stream_info: Optional[Dict[str, Any]] = None) -> ProcessingResult:
80
+ start_time = time.time()
81
+ if not isinstance(config, LaneDetectionConfig):
82
+ return self.create_error_result("Invalid config type", usecase=self.name, category=self.category, context=context)
83
+ if context is None:
84
+ context = ProcessingContext()
85
+
86
+ input_format = match_results_structure(data)
87
+ context.input_format = input_format
88
+ context.confidence_threshold = config.confidence_threshold
89
+
90
+ if config.confidence_threshold is not None:
91
+ processed_data = filter_by_confidence(data, config.confidence_threshold)
92
+ self.logger.debug(f"Applied confidence filtering with threshold {config.confidence_threshold}")
93
+ else:
94
+ processed_data = data
95
+ self.logger.debug("Did not apply confidence filtering since no threshold provided")
96
+
97
+ if config.index_to_category:
98
+ processed_data = apply_category_mapping(processed_data, config.index_to_category)
99
+ self.logger.debug("Applied category mapping")
100
+
101
+ if config.target_categories:
102
+ processed_data = [d for d in processed_data if d.get('category') in self.target_categories]
103
+ self.logger.debug("Applied category filtering")
104
+
105
+ if config.enable_smoothing:
106
+ if self.smoothing_tracker is None:
107
+ smoothing_config = BBoxSmoothingConfig(
108
+ smoothing_algorithm=config.smoothing_algorithm,
109
+ window_size=config.smoothing_window_size,
110
+ cooldown_frames=config.smoothing_cooldown_frames,
111
+ confidence_threshold=config.confidence_threshold,
112
+ confidence_range_factor=config.smoothing_confidence_range_factor,
113
+ enable_smoothing=True
114
+ )
115
+ self.smoothing_tracker = BBoxSmoothingTracker(smoothing_config)
116
+ processed_data = bbox_smoothing(processed_data, self.smoothing_tracker.config, self.smoothing_tracker)
117
+
118
+ try:
119
+ from ..advanced_tracker import AdvancedTracker
120
+ from ..advanced_tracker.config import TrackerConfig
121
+ if self.tracker is None:
122
+ tracker_config = TrackerConfig()
123
+ self.tracker = AdvancedTracker(tracker_config)
124
+ self.logger.info("Initialized AdvancedTracker for Lane Detection")
125
+ processed_data = self.tracker.update(processed_data)
126
+ except Exception as e:
127
+ self.logger.warning(f"AdvancedTracker failed: {e}")
128
+
129
+ self._update_tracking_state(processed_data)
130
+ self._total_frame_counter += 1
131
+
132
+ frame_number = None
133
+ if stream_info:
134
+ input_settings = stream_info.get("input_settings", {})
135
+ start_frame = input_settings.get("start_frame")
136
+ end_frame = input_settings.get("end_frame")
137
+ if start_frame is not None and end_frame is not None and start_frame == end_frame:
138
+ frame_number = start_frame
139
+
140
+ general_counting_summary = calculate_counting_summary(data)
141
+ counting_summary = self._count_categories(processed_data, config)
142
+ total_counts = self.get_total_counts()
143
+ counting_summary['total_counts'] = total_counts
144
+ alerts = self._check_alerts(counting_summary, frame_number, config)
145
+ predictions = self._extract_predictions(processed_data)
146
+
147
+ incidents_list = self._generate_incidents(counting_summary, alerts, config, frame_number, stream_info)
148
+ tracking_stats_list = self._generate_tracking_stats(counting_summary, alerts, config, frame_number, stream_info)
149
+ business_analytics_list = self._generate_business_analytics(counting_summary, alerts, config, stream_info, is_empty=True)
150
+ summary_list = self._generate_summary(counting_summary, incidents_list, tracking_stats_list, business_analytics_list, alerts)
151
+
152
+ incidents = incidents_list[0] if incidents_list else {}
153
+ tracking_stats = tracking_stats_list[0] if tracking_stats_list else {}
154
+ business_analytics = business_analytics_list[0] if business_analytics_list else {}
155
+ summary = summary_list[0] if summary_list else {}
156
+ agg_summary = {str(frame_number): {
157
+ "incidents": incidents,
158
+ "tracking_stats": tracking_stats,
159
+ "business_analytics": business_analytics,
160
+ "alerts": alerts,
161
+ "human_text": summary}
162
+ }
163
+
164
+ context.mark_completed()
165
+ result = self.create_result(
166
+ data={"agg_summary": agg_summary},
167
+ usecase=self.name,
168
+ category=self.category,
169
+ context=context
170
+ )
171
+ return result
172
+
173
+ def _check_alerts(self, summary: dict, frame_number: Any, config: LaneDetectionConfig) -> List[Dict]:
174
+ def get_trend(data, lookback=900, threshold=0.6):
175
+ window = data[-lookback:] if len(data) >= lookback else data
176
+ if len(window) < 2:
177
+ return True
178
+ increasing = 0
179
+ total = 0
180
+ for i in range(1, len(window)):
181
+ if window[i] >= window[i - 1]:
182
+ increasing += 1
183
+ total += 1
184
+ ratio = increasing / total
185
+ return ratio >= threshold
186
+
187
+ frame_key = str(frame_number) if frame_number is not None else "current_frame"
188
+ alerts = []
189
+ total_detections = summary.get("total_count", 0)
190
+ total_counts_dict = summary.get("total_counts", {})
191
+ per_category_count = summary.get("per_category_count", {})
192
+
193
+ if not config.alert_config:
194
+ return alerts
195
+
196
+ if hasattr(config.alert_config, 'count_thresholds') and config.alert_config.count_thresholds:
197
+ for category, threshold in config.alert_config.count_thresholds.items():
198
+ if category == "all" and total_detections > threshold:
199
+ alerts.append({
200
+ "alert_type": getattr(config.alert_config, 'alert_type', ['Default']),
201
+ "alert_id": f"alert_{category}_{frame_key}",
202
+ "incident_category": self.CASE_TYPE,
203
+ "threshold_level": threshold,
204
+ "ascending": get_trend(self._ascending_alert_list, lookback=900, threshold=0.8),
205
+ "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']),
206
+ getattr(config.alert_config, 'alert_value', ['JSON']))}
207
+ })
208
+ elif category in per_category_count and per_category_count[category] > threshold:
209
+ alerts.append({
210
+ "alert_type": getattr(config.alert_config, 'alert_type', ['Default']),
211
+ "alert_id": f"alert_{category}_{frame_key}",
212
+ "incident_category": self.CASE_TYPE,
213
+ "threshold_level": threshold,
214
+ "ascending": get_trend(self._ascending_alert_list, lookback=900, threshold=0.8),
215
+ "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']),
216
+ getattr(config.alert_config, 'alert_value', ['JSON']))}
217
+ })
218
+ return alerts
219
+
220
+ def _generate_incidents(self, counting_summary: Dict, alerts: List, config: LaneDetectionConfig,
221
+ frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[Dict]:
222
+ incidents = []
223
+ total_detections = counting_summary.get("total_count", 0)
224
+ current_timestamp = self._get_current_timestamp_str(stream_info)
225
+ camera_info = self.get_camera_info_from_stream(stream_info)
226
+
227
+ self._ascending_alert_list = self._ascending_alert_list[-900:] if len(self._ascending_alert_list) > 900 else self._ascending_alert_list
228
+
229
+ if total_detections > 0:
230
+ level = "low"
231
+ intensity = 5.0
232
+ start_timestamp = self._get_start_timestamp_str(stream_info)
233
+ if start_timestamp and self.current_incident_end_timestamp == 'N/A':
234
+ self.current_incident_end_timestamp = 'Incident still active'
235
+ elif start_timestamp and self.current_incident_end_timestamp == 'Incident still active':
236
+ if len(self._ascending_alert_list) >= 15 and sum(self._ascending_alert_list[-15:]) / 15 < 1.5:
237
+ self.current_incident_end_timestamp = current_timestamp
238
+ elif self.current_incident_end_timestamp != 'Incident still active' and self.current_incident_end_timestamp != 'N/A':
239
+ self.current_incident_end_timestamp = 'N/A'
240
+
241
+ if config.alert_config and config.alert_config.count_thresholds:
242
+ threshold = config.alert_config.count_thresholds.get("all", 15)
243
+ intensity = min(10.0, (total_detections / threshold) * 10)
244
+ if intensity >= 9:
245
+ level = "critical"
246
+ self._ascending_alert_list.append(3)
247
+ elif intensity >= 7:
248
+ level = "significant"
249
+ self._ascending_alert_list.append(2)
250
+ elif intensity >= 5:
251
+ level = "medium"
252
+ self._ascending_alert_list.append(1)
253
+ else:
254
+ self._ascending_alert_list.append(0)
255
+ else:
256
+ if total_detections > 30:
257
+ level = "critical"
258
+ intensity = 10.0
259
+ self._ascending_alert_list.append(3)
260
+ elif total_detections > 25:
261
+ level = "significant"
262
+ intensity = 9.0
263
+ self._ascending_alert_list.append(2)
264
+ elif total_detections > 15:
265
+ level = "medium"
266
+ intensity = 7.0
267
+ self._ascending_alert_list.append(1)
268
+ else:
269
+ level = "low"
270
+ intensity = min(10.0, total_detections / 3.0)
271
+ self._ascending_alert_list.append(0)
272
+
273
+ human_text_lines = [f"INCIDENTS DETECTED @ {current_timestamp}:"]
274
+ human_text_lines.append(f"\tSeverity Level: {(self.CASE_TYPE, level)}")
275
+ human_text = "\n".join(human_text_lines)
276
+
277
+ alert_settings = []
278
+ if config.alert_config and hasattr(config.alert_config, 'alert_type'):
279
+ alert_settings.append({
280
+ "alert_type": getattr(config.alert_config, 'alert_type', ['Default']),
281
+ "incident_category": self.CASE_TYPE,
282
+ "threshold_level": config.alert_config.count_thresholds if hasattr(config.alert_config, 'count_thresholds') else {},
283
+ "ascending": True,
284
+ "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']),
285
+ getattr(config.alert_config, 'alert_value', ['JSON']))}
286
+ })
287
+
288
+ event = self.create_incident(
289
+ incident_id=f"{self.CASE_TYPE}_{frame_number}",
290
+ incident_type=self.CASE_TYPE,
291
+ severity_level=level,
292
+ human_text=human_text,
293
+ camera_info=camera_info,
294
+ alerts=alerts,
295
+ alert_settings=alert_settings,
296
+ start_time=start_timestamp,
297
+ end_time=self.current_incident_end_timestamp,
298
+ level_settings={"low": 1, "medium": 3, "significant": 4, "critical": 7}
299
+ )
300
+ incidents.append(event)
301
+ else:
302
+ self._ascending_alert_list.append(0)
303
+ incidents.append({})
304
+ return incidents
305
+
306
+ def _generate_tracking_stats(self, counting_summary: Dict, alerts: List, config: LaneDetectionConfig,
307
+ frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[Dict]:
308
+ camera_info = self.get_camera_info_from_stream(stream_info)
309
+ tracking_stats = []
310
+ total_detections = counting_summary.get("total_count", 0)
311
+ total_counts_dict = counting_summary.get("total_counts", {})
312
+ per_category_count = counting_summary.get("per_category_count", {})
313
+ current_timestamp = self._get_current_timestamp_str(stream_info, precision=False)
314
+ start_timestamp = self._get_start_timestamp_str(stream_info, precision=False)
315
+ high_precision_start_timestamp = self._get_current_timestamp_str(stream_info, precision=True)
316
+ high_precision_reset_timestamp = self._get_start_timestamp_str(stream_info, precision=True)
317
+
318
+ total_counts = [{"category": cat, "count": count} for cat, count in total_counts_dict.items() if count > 0]
319
+ current_counts = [{"category": cat, "count": count} for cat, count in per_category_count.items() if count > 0 or total_detections > 0]
320
+
321
+ detections = []
322
+ for detection in counting_summary.get("detections", []):
323
+ bbox = detection.get("bounding_box", {})
324
+ category = detection.get("category", "lane")
325
+ if detection.get("masks"):
326
+ segmentation = detection.get("masks", [])
327
+ detection_obj = self.create_detection_object(category, bbox, segmentation=segmentation)
328
+ elif detection.get("segmentation"):
329
+ segmentation = detection.get("segmentation")
330
+ detection_obj = self.create_detection_object(category, bbox, segmentation=segmentation)
331
+ elif detection.get("mask"):
332
+ segmentation = detection.get("mask")
333
+ detection_obj = self.create_detection_object(category, bbox, segmentation=segmentation)
334
+ else:
335
+ detection_obj = self.create_detection_object(category, bbox)
336
+ detections.append(detection_obj)
337
+
338
+ alert_settings = []
339
+ if config.alert_config and hasattr(config.alert_config, 'alert_type'):
340
+ alert_settings.append({
341
+ "alert_type": getattr(config.alert_config, 'alert_type', ['Default']),
342
+ "incident_category": self.CASE_TYPE,
343
+ "threshold_level": config.alert_config.count_thresholds if hasattr(config.alert_config, 'count_thresholds') else {},
344
+ "ascending": True,
345
+ "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']),
346
+ getattr(config.alert_config, 'alert_value', ['JSON']))}
347
+ })
348
+
349
+ human_text_lines = [f"Tracking Statistics:"]
350
+ human_text_lines.append(f"CURRENT FRAME @ {current_timestamp}")
351
+ for cat, count in per_category_count.items():
352
+ human_text_lines.append(f"\t{cat}: {count}")
353
+ human_text_lines.append(f"TOTAL SINCE {start_timestamp}")
354
+ for cat, count in total_counts_dict.items():
355
+ if count > 0:
356
+ human_text_lines.append(f"\t{cat}: {count}")
357
+ if alerts:
358
+ for alert in alerts:
359
+ human_text_lines.append(f"Alerts: {alert.get('settings', {})} sent @ {current_timestamp}")
360
+ else:
361
+ human_text_lines.append("Alerts: None")
362
+ human_text = "\n".join(human_text_lines)
363
+
364
+ reset_settings = [{"interval_type": "daily", "reset_time": {"value": 9, "time_unit": "hour"}}]
365
+ tracking_stat = self.create_tracking_stats(
366
+ total_counts=total_counts,
367
+ current_counts=current_counts,
368
+ detections=detections,
369
+ human_text=human_text,
370
+ camera_info=camera_info,
371
+ alerts=alerts,
372
+ alert_settings=alert_settings,
373
+ reset_settings=reset_settings,
374
+ start_time=high_precision_start_timestamp,
375
+ reset_time=high_precision_reset_timestamp
376
+ )
377
+ tracking_stats.append(tracking_stat)
378
+ return tracking_stats
379
+
380
+ def _generate_business_analytics(self, counting_summary: Dict, alerts: Any, config: LaneDetectionConfig,
381
+ stream_info: Optional[Dict[str, Any]] = None, is_empty=False) -> List[Dict]:
382
+ if is_empty:
383
+ return []
384
+
385
+ def _generate_summary(self, summary: dict, incidents: List, tracking_stats: List, business_analytics: List, alerts: List) -> List[str]:
386
+ lines = {}
387
+ lines["Application Name"] = self.CASE_TYPE
388
+ lines["Application Version"] = self.CASE_VERSION
389
+ if len(incidents) > 0:
390
+ lines["Incidents:"] = f"\n\t{incidents[0].get('human_text', 'No incidents detected')}\n"
391
+ if len(tracking_stats) > 0:
392
+ lines["Tracking Statistics:"] = f"\t{tracking_stats[0].get('human_text', 'No tracking statistics detected')}\n"
393
+ if len(business_analytics) > 0:
394
+ lines["Business Analytics:"] = f"\t{business_analytics[0].get('human_text', 'No business analytics detected')}\n"
395
+ if len(incidents) == 0 and len(tracking_stats) == 0 and len(business_analytics) == 0:
396
+ lines["Summary"] = "No Summary Data"
397
+ return [lines]
398
+
399
+ def _get_track_ids_info(self, detections: list) -> Dict[str, Any]:
400
+ frame_track_ids = set()
401
+ for det in detections:
402
+ tid = det.get('track_id')
403
+ if tid is not None:
404
+ frame_track_ids.add(tid)
405
+ total_track_ids = set()
406
+ for s in getattr(self, '_per_category_total_track_ids', {}).values():
407
+ total_track_ids.update(s)
408
+ return {
409
+ "total_count": len(total_track_ids),
410
+ "current_frame_count": len(frame_track_ids),
411
+ "total_unique_track_ids": len(total_track_ids),
412
+ "current_frame_track_ids": list(frame_track_ids),
413
+ "last_update_time": time.time(),
414
+ "total_frames_processed": getattr(self, '_total_frame_counter', 0)
415
+ }
416
+
417
+ def _update_tracking_state(self, detections: list):
418
+ if not hasattr(self, "_per_category_total_track_ids"):
419
+ self._per_category_total_track_ids = {cat: set() for cat in self.target_categories}
420
+ self._current_frame_track_ids = {cat: set() for cat in self.target_categories}
421
+
422
+ for det in detections:
423
+ cat = det.get("category")
424
+ raw_track_id = det.get("track_id")
425
+ if cat not in self.target_categories or raw_track_id is None:
426
+ continue
427
+ bbox = det.get("bounding_box", det.get("bbox"))
428
+ canonical_id = self._merge_or_register_track(raw_track_id, bbox)
429
+ det["track_id"] = canonical_id
430
+ self._per_category_total_track_ids.setdefault(cat, set()).add(canonical_id)
431
+ self._current_frame_track_ids[cat].add(canonical_id)
432
+
433
+ def get_total_counts(self):
434
+ return {cat: len(ids) for cat, ids in getattr(self, '_per_category_total_track_ids', {}).items()}
435
+
436
+ def _format_timestamp_for_stream(self, timestamp: float) -> str:
437
+ dt = datetime.fromtimestamp(timestamp, tz=timezone.utc)
438
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
439
+
440
+ def _format_timestamp_for_video(self, timestamp: float) -> str:
441
+ hours = int(timestamp // 3600)
442
+ minutes = int((timestamp % 3600) // 60)
443
+ seconds = round(float(timestamp % 60), 2)
444
+ return f"{hours:02d}:{minutes:02d}:{seconds:.1f}"
445
+
446
+ def _get_current_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False, frame_id: Optional[str] = None) -> str:
447
+ if not stream_info:
448
+ return "00:00:00.00"
449
+ if precision:
450
+ if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
451
+ if frame_id:
452
+ start_time = int(frame_id) / stream_info.get("input_settings", {}).get("original_fps", 30)
453
+ else:
454
+ start_time = stream_info.get("input_settings", {}).get("start_frame", 30) / stream_info.get("input_settings", {}).get("original_fps", 30)
455
+ return self._format_timestamp_for_video(start_time)
456
+ else:
457
+ return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
458
+ if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
459
+ if frame_id:
460
+ start_time = int(frame_id) / stream_info.get("input_settings", {}).get("original_fps", 30)
461
+ else:
462
+ start_time = stream_info.get("input_settings", {}).get("start_frame", 30) / stream_info.get("input_settings", {}).get("original_fps", 30)
463
+ return self._format_timestamp_for_video(start_time)
464
+ else:
465
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
466
+ if stream_time_str:
467
+ try:
468
+ timestamp_str = stream_time_str.replace(" UTC", "")
469
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
470
+ timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
471
+ return self._format_timestamp_for_stream(timestamp)
472
+ except:
473
+ return self._format_timestamp_for_stream(time.time())
474
+ else:
475
+ return self._format_timestamp_for_stream(time.time())
476
+
477
+ def _get_start_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False) -> str:
478
+ if not stream_info:
479
+ return "00:00:00"
480
+ if precision:
481
+ if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
482
+ return "00:00:00"
483
+ else:
484
+ return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
485
+ if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
486
+ return "00:00:00"
487
+ else:
488
+ if self._tracking_start_time is None:
489
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
490
+ if stream_time_str:
491
+ try:
492
+ timestamp_str = stream_time_str.replace(" UTC", "")
493
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
494
+ self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
495
+ except:
496
+ self._tracking_start_time = time.time()
497
+ else:
498
+ self._tracking_start_time = time.time()
499
+ dt = datetime.fromtimestamp(self._tracking_start_time, tz=timezone.utc)
500
+ dt = dt.replace(minute=0, second=0, microsecond=0)
501
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
502
+
503
+ def _count_categories(self, detections: list, config: LaneDetectionConfig) -> dict:
504
+ counts = {}
505
+ for det in detections:
506
+ cat = det.get('category', 'unknown')
507
+ counts[cat] = counts.get(cat, 0) + 1
508
+ return {
509
+ "total_count": sum(counts.values()),
510
+ "per_category_count": counts,
511
+ "detections": [
512
+ {
513
+ "bounding_box": det.get("bounding_box"),
514
+ "category": det.get("category"),
515
+ "confidence": det.get("confidence"),
516
+ "track_id": det.get("track_id"),
517
+ "frame_id": det.get("frame_id")
518
+ }
519
+ for det in detections
520
+ ]
521
+ }
522
+
523
+ def _extract_predictions(self, detections: list) -> List[Dict[str, Any]]:
524
+ return [
525
+ {
526
+ "category": det.get("category", "unknown"),
527
+ "confidence": det.get("confidence", 0.0),
528
+ "bounding_box": det.get("bounding_box", {})
529
+ }
530
+ for det in detections
531
+ ]
532
+
533
+ def _compute_iou(self, box1: Any, box2: Any) -> float:
534
+ def _bbox_to_list(bbox):
535
+ if bbox is None:
536
+ return []
537
+ if isinstance(bbox, list):
538
+ return bbox[:4] if len(bbox) >= 4 else []
539
+ if isinstance(bbox, dict):
540
+ if "xmin" in bbox:
541
+ return [bbox["xmin"], bbox["ymin"], bbox["xmax"], bbox["ymax"]]
542
+ if "x1" in bbox:
543
+ return [bbox["x1"], bbox["y1"], bbox["x2"], bbox["y2"]]
544
+ values = [v for v in bbox.values() if isinstance(v, (int, float))]
545
+ return values[:4] if len(values) >= 4 else []
546
+ return []
547
+
548
+ l1 = _bbox_to_list(box1)
549
+ l2 = _bbox_to_list(box2)
550
+ if len(l1) < 4 or len(l2) < 4:
551
+ return 0.0
552
+ x1_min, y1_min, x1_max, y1_max = l1
553
+ x2_min, y2_min, x2_max, y2_max = l2
554
+ x1_min, x1_max = min(x1_min, x1_max), max(x1_min, x1_max)
555
+ y1_min, y1_max = min(y1_min, y1_max), max(y1_min, y1_max)
556
+ x2_min, x2_max = min(x2_min, x2_max), max(x2_min, x2_max)
557
+ y2_min, y2_max = min(y2_min, y2_max), max(y2_min, y2_max)
558
+ inter_x_min = max(x1_min, x2_min)
559
+ inter_y_min = max(y1_min, y2_min)
560
+ inter_x_max = min(x1_max, x2_max)
561
+ inter_y_max = min(y1_max, y2_max)
562
+ inter_w = max(0.0, inter_x_max - inter_x_min)
563
+ inter_h = max(0.0, inter_y_max - inter_y_min)
564
+ inter_area = inter_w * inter_h
565
+ area1 = (x1_max - x1_min) * (y1_max - y1_min)
566
+ area2 = (x2_max - x2_min) * (y2_max - y2_min)
567
+ union_area = area1 + area2 - inter_area
568
+ return (inter_area / union_area) if union_area > 0 else 0.0
569
+
570
+ def _merge_or_register_track(self, raw_id: Any, bbox: Any) -> Any:
571
+ if raw_id is None or bbox is None:
572
+ return raw_id
573
+ now = time.time()
574
+ if raw_id in self._track_aliases:
575
+ canonical_id = self._track_aliases[raw_id]
576
+ track_info = self._canonical_tracks.get(canonical_id)
577
+ if track_info is not None:
578
+ track_info["last_bbox"] = bbox
579
+ track_info["last_update"] = now
580
+ track_info["raw_ids"].add(raw_id)
581
+ return canonical_id
582
+ for canonical_id, info in self._canonical_tracks.items():
583
+ if now - info["last_update"] > self._track_merge_time_window:
584
+ continue
585
+ iou = self._compute_iou(bbox, info["last_bbox"])
586
+ if iou >= self._track_merge_iou_threshold:
587
+ self._track_aliases[raw_id] = canonical_id
588
+ info["last_bbox"] = bbox
589
+ info["last_update"] = now
590
+ info["raw_ids"].add(raw_id)
591
+ return canonical_id
592
+ canonical_id = raw_id
593
+ self._track_aliases[raw_id] = canonical_id
594
+ self._canonical_tracks[canonical_id] = {
595
+ "last_bbox": bbox,
596
+ "last_update": now,
597
+ "raw_ids": {raw_id},
598
+ }
599
+ return canonical_id
600
+
601
+ def _format_timestamp(self, timestamp: float) -> str:
602
+ return datetime.fromtimestamp(timestamp, timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')
603
+
604
+ def _get_tracking_start_time(self) -> str:
605
+ if self._tracking_start_time is None:
606
+ return "N/A"
607
+ return self._format_timestamp(self._tracking_start_time)
608
+
609
+ def _set_tracking_start_time(self) -> None:
610
+ self._tracking_start_time = time.time()