matrice-analytics 0.1.35__tar.gz → 0.1.37__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.35 → matrice_analytics-0.1.37}/PKG-INFO +1 -1
  2. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/matrice_analytics.egg-info/PKG-INFO +1 -1
  3. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/post_processor.py +2 -1
  4. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/license_plate_monitoring.py +173 -84
  5. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/LICENSE.txt +0 -0
  6. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/README.md +0 -0
  7. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/matrice_analytics.egg-info/SOURCES.txt +0 -0
  8. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/matrice_analytics.egg-info/dependency_links.txt +0 -0
  9. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/matrice_analytics.egg-info/not-zip-safe +0 -0
  10. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/matrice_analytics.egg-info/top_level.txt +0 -0
  11. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/pyproject.toml +0 -0
  12. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/setup.cfg +0 -0
  13. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/setup.py +0 -0
  14. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/__init__.py +0 -0
  15. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/README.md +0 -0
  16. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/__init__.py +0 -0
  17. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_internal.py +0 -0
  18. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/boundary_drawing_tool.py +0 -0
  19. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/boundary_tool_template.html +0 -0
  20. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/example_usage.py +0 -0
  21. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/usage/README.md +0 -0
  22. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/usage/boundary_drawer_launcher.py +0 -0
  23. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py +0 -0
  24. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/README.md +0 -0
  25. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/__init__.py +0 -0
  26. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/README.md +0 -0
  27. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/__init__.py +0 -0
  28. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/base.py +0 -0
  29. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/config.py +0 -0
  30. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/kalman_filter.py +0 -0
  31. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/matching.py +0 -0
  32. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/strack.py +0 -0
  33. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/advanced_tracker/tracker.py +0 -0
  34. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/config.py +0 -0
  35. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/core/__init__.py +0 -0
  36. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/core/base.py +0 -0
  37. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/core/config.py +0 -0
  38. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/core/config_utils.py +0 -0
  39. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/face_reg/__init__.py +0 -0
  40. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/face_reg/compare_similarity.py +0 -0
  41. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/face_reg/embedding_manager.py +0 -0
  42. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/face_reg/face_recognition.py +0 -0
  43. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/face_reg/face_recognition_client.py +0 -0
  44. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/face_reg/people_activity_logging.py +0 -0
  45. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/__init__.py +0 -0
  46. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/easyocr_extractor.py +0 -0
  47. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/__init__.py +0 -0
  48. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/__init__.py +0 -0
  49. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/cli.py +0 -0
  50. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/dataset_stats.py +0 -0
  51. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/export.py +0 -0
  52. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/train.py +0 -0
  53. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/utils.py +0 -0
  54. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/valid.py +0 -0
  55. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/validate_dataset.py +0 -0
  56. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_augmentation.py +0 -0
  57. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_predictions.py +0 -0
  58. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/__init__.py +0 -0
  59. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/process.py +0 -0
  60. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/types.py +0 -0
  61. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/utils.py +0 -0
  62. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/__init__.py +0 -0
  63. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/config.py +0 -0
  64. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/hub.py +0 -0
  65. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/plate_recognizer.py +0 -0
  66. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/py.typed +0 -0
  67. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/__init__.py +0 -0
  68. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/__init__.py +0 -0
  69. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/augmentation.py +0 -0
  70. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/dataset.py +0 -0
  71. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/__init__.py +0 -0
  72. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/config.py +0 -0
  73. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/layers.py +0 -0
  74. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/loss.py +0 -0
  75. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/metric.py +0 -0
  76. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_builders.py +0 -0
  77. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_schema.py +0 -0
  78. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/__init__.py +0 -0
  79. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/backend_utils.py +0 -0
  80. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/utils.py +0 -0
  81. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/postprocessing.py +0 -0
  82. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/ocr/preprocessing.py +0 -0
  83. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/__init__.py +0 -0
  84. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/run_tests.py +0 -0
  85. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_advanced_customer_service.py +0 -0
  86. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_basic_counting_tracking.py +0 -0
  87. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_comprehensive.py +0 -0
  88. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_config.py +0 -0
  89. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_customer_service.py +0 -0
  90. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_data_generators.py +0 -0
  91. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_people_counting.py +0 -0
  92. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_processor.py +0 -0
  93. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_utilities.py +0 -0
  94. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/test_cases/test_utils.py +0 -0
  95. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py +0 -0
  96. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/__init__.py +0 -0
  97. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/abandoned_object_detection.py +0 -0
  98. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/advanced_customer_service.py +0 -0
  99. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/age_detection.py +0 -0
  100. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/age_gender_detection.py +0 -0
  101. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/anti_spoofing_detection.py +0 -0
  102. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/assembly_line_detection.py +0 -0
  103. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/banana_defect_detection.py +0 -0
  104. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/basic_counting_tracking.py +0 -0
  105. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/blood_cancer_detection_img.py +0 -0
  106. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/car_damage_detection.py +0 -0
  107. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/car_part_segmentation.py +0 -0
  108. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/car_service.py +0 -0
  109. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/cardiomegaly_classification.py +0 -0
  110. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/cell_microscopy_segmentation.py +0 -0
  111. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/chicken_pose_detection.py +0 -0
  112. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/child_monitoring.py +0 -0
  113. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip.py +0 -0
  114. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip_processor/merges.txt +0 -0
  115. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip_processor/preprocessor_config.json +0 -0
  116. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip_processor/special_tokens_map.json +0 -0
  117. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer.json +0 -0
  118. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer_config.json +0 -0
  119. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/clip_processor/vocab.json +0 -0
  120. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/color_map_utils.py +0 -0
  121. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color/color_mapper.py +0 -0
  122. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color_detection.py +0 -0
  123. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/color_map_utils.py +0 -0
  124. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/concrete_crack_detection.py +0 -0
  125. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/crop_weed_detection.py +0 -0
  126. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/customer_service.py +0 -0
  127. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/defect_detection_products.py +0 -0
  128. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/distracted_driver_detection.py +0 -0
  129. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/drone_traffic_monitoring.py +0 -0
  130. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/drowsy_driver_detection.py +0 -0
  131. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/dwell_detection.py +0 -0
  132. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/emergency_vehicle_detection.py +0 -0
  133. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/face_emotion.py +0 -0
  134. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/face_recognition.py +0 -0
  135. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/fashion_detection.py +0 -0
  136. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/field_mapping.py +0 -0
  137. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/fire_detection.py +0 -0
  138. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/flare_analysis.py +0 -0
  139. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/flower_segmentation.py +0 -0
  140. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/gas_leak_detection.py +0 -0
  141. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/gender_detection.py +0 -0
  142. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/human_activity_recognition.py +0 -0
  143. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/intrusion_detection.py +0 -0
  144. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/leaf.py +0 -0
  145. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/leaf_disease.py +0 -0
  146. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/leak_detection.py +0 -0
  147. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/license_plate_detection.py +0 -0
  148. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/litter_monitoring.py +0 -0
  149. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/mask_detection.py +0 -0
  150. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/natural_disaster.py +0 -0
  151. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/parking.py +0 -0
  152. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/parking_space_detection.py +0 -0
  153. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/pcb_defect_detection.py +0 -0
  154. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/pedestrian_detection.py +0 -0
  155. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/people_counting.py +0 -0
  156. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/people_counting_bckp.py +0 -0
  157. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/people_tracking.py +0 -0
  158. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/pipeline_detection.py +0 -0
  159. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/plaque_segmentation_img.py +0 -0
  160. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/pothole_segmentation.py +0 -0
  161. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/ppe_compliance.py +0 -0
  162. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/price_tag_detection.py +0 -0
  163. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/proximity_detection.py +0 -0
  164. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/road_lane_detection.py +0 -0
  165. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/road_traffic_density.py +0 -0
  166. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/road_view_segmentation.py +0 -0
  167. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/shelf_inventory_detection.py +0 -0
  168. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/shoplifting_detection.py +0 -0
  169. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/shopping_cart_analysis.py +0 -0
  170. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/skin_cancer_classification_img.py +0 -0
  171. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/smoker_detection.py +0 -0
  172. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/solar_panel.py +0 -0
  173. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/suspicious_activity_detection.py +0 -0
  174. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/template_usecase.py +0 -0
  175. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/theft_detection.py +0 -0
  176. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/traffic_sign_monitoring.py +0 -0
  177. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/underground_pipeline_defect_detection.py +0 -0
  178. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/underwater_pollution_detection.py +0 -0
  179. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/vehicle_monitoring.py +0 -0
  180. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/warehouse_object_segmentation.py +0 -0
  181. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/waterbody_segmentation.py +0 -0
  182. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/weapon_detection.py +0 -0
  183. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/weld_defect_detection.py +0 -0
  184. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/wildlife_monitoring.py +0 -0
  185. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/windmill_maintenance.py +0 -0
  186. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/usecases/wound_segmentation.py +0 -0
  187. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/__init__.py +0 -0
  188. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/advanced_counting_utils.py +0 -0
  189. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/advanced_helper_utils.py +0 -0
  190. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/advanced_tracking_utils.py +0 -0
  191. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/alerting_utils.py +0 -0
  192. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/category_mapping_utils.py +0 -0
  193. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/color_utils.py +0 -0
  194. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/counting_utils.py +0 -0
  195. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/filter_utils.py +0 -0
  196. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/format_utils.py +0 -0
  197. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/geometry_utils.py +0 -0
  198. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/smoothing_utils.py +0 -0
  199. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/src/matrice_analytics/post_processing/utils/tracking_utils.py +0 -0
  200. {matrice_analytics-0.1.35 → matrice_analytics-0.1.37}/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.35
3
+ Version: 0.1.37
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.35
3
+ Version: 0.1.37
4
4
  Summary: Common server utilities for Matrice.ai services
5
5
  Author-email: "Matrice.ai" <dipendra@matrice.ai>
6
6
  License-Expression: MIT
@@ -711,7 +711,8 @@ class PostProcessor:
711
711
 
712
712
  # Async use cases
713
713
  async_use_cases = {
714
- FaceRecognitionEmbeddingUseCase
714
+ FaceRecognitionEmbeddingUseCase,
715
+ LicensePlateMonitorUseCase
715
716
  }
716
717
 
717
718
  # Determine the appropriate method signature and call
@@ -25,6 +25,7 @@ import numpy as np
25
25
  import re
26
26
  from collections import Counter, defaultdict
27
27
  import sys
28
+ import subprocess
28
29
  import logging
29
30
  import asyncio
30
31
  import urllib
@@ -37,33 +38,96 @@ print(f"Python version: {major_version}.{minor_version}")
37
38
  os.environ["ORT_LOG_SEVERITY_LEVEL"] = "3"
38
39
 
39
40
 
40
- # Try to import LicensePlateRecognizer from local repo first, then installed package
41
+ # Lazy import mechanism for LicensePlateRecognizer
41
42
  _OCR_IMPORT_SOURCE = None
42
- try:
43
- from ..ocr.fast_plate_ocr_py38 import LicensePlateRecognizer
44
- _OCR_IMPORT_SOURCE = "local_repo"
45
- except ImportError:
43
+ _LicensePlateRecognizerClass = None
44
+
45
+ def _get_license_plate_recognizer_class():
46
+ """Lazy load LicensePlateRecognizer with automatic installation fallback."""
47
+ global _OCR_IMPORT_SOURCE, _LicensePlateRecognizerClass
48
+
49
+ if _LicensePlateRecognizerClass is not None:
50
+ return _LicensePlateRecognizerClass
51
+
52
+ # Try to import from local repo first
53
+ try:
54
+ from ..ocr.fast_plate_ocr_py38 import LicensePlateRecognizer
55
+ _OCR_IMPORT_SOURCE = "local_repo"
56
+ _LicensePlateRecognizerClass = LicensePlateRecognizer
57
+ logging.info("Successfully imported LicensePlateRecognizer from local repo")
58
+ return _LicensePlateRecognizerClass
59
+ except ImportError as e:
60
+ logging.debug(f"Could not import from local repo: {e}")
61
+
62
+ # Try to import from installed package
46
63
  try:
47
64
  from fast_plate_ocr import LicensePlateRecognizer # type: ignore
48
65
  _OCR_IMPORT_SOURCE = "installed_package"
49
- except ImportError:
50
- # Use stub class if neither import works
51
- _OCR_IMPORT_SOURCE = "stub"
52
- class LicensePlateRecognizer: # type: ignore
53
- """Stub fallback when fast_plate_ocr is not available."""
54
- def __init__(self, *args, **kwargs):
55
- pass # Silent stub - error will be logged once during initialization
66
+ _LicensePlateRecognizerClass = LicensePlateRecognizer
67
+ logging.info("Successfully imported LicensePlateRecognizer from installed package")
68
+ return _LicensePlateRecognizerClass
69
+ except ImportError as e:
70
+ logging.warning(f"Could not import from installed package: {e}")
71
+
72
+ # Try to install with GPU support first
73
+ logging.info("Attempting to install fast-plate-ocr with GPU support...")
74
+ try:
75
+ import subprocess
76
+ result = subprocess.run(
77
+ [sys.executable, "-m", "pip", "install", "fast-plate-ocr[onnx-gpu]", "--no-cache-dir"],
78
+ capture_output=True,
79
+ text=True,
80
+ timeout=300
81
+ )
82
+ if result.returncode == 0:
83
+ logging.info("Successfully installed fast-plate-ocr[onnx-gpu]")
84
+ try:
85
+ from fast_plate_ocr import LicensePlateRecognizer # type: ignore
86
+ _OCR_IMPORT_SOURCE = "installed_package_gpu"
87
+ _LicensePlateRecognizerClass = LicensePlateRecognizer
88
+ logging.info("Successfully imported LicensePlateRecognizer after GPU installation")
89
+ return _LicensePlateRecognizerClass
90
+ except ImportError as e:
91
+ logging.warning(f"Installation succeeded but import failed: {e}")
92
+ else:
93
+ logging.warning(f"GPU installation failed: {result.stderr}")
94
+ except Exception as e:
95
+ logging.warning(f"Error during GPU installation: {e}")
96
+
97
+ # Try to install with CPU support as fallback
98
+ logging.info("Attempting to install fast-plate-ocr with CPU support...")
99
+ try:
100
+ import subprocess
101
+ result = subprocess.run(
102
+ [sys.executable, "-m", "pip", "install", "fast-plate-ocr[onnx]", "--no-cache-dir"],
103
+ capture_output=True,
104
+ text=True,
105
+ timeout=300
106
+ )
107
+ if result.returncode == 0:
108
+ logging.info("Successfully installed fast-plate-ocr[onnx]")
109
+ try:
110
+ from fast_plate_ocr import LicensePlateRecognizer # type: ignore
111
+ _OCR_IMPORT_SOURCE = "installed_package_cpu"
112
+ _LicensePlateRecognizerClass = LicensePlateRecognizer
113
+ logging.info("Successfully imported LicensePlateRecognizer after CPU installation")
114
+ return _LicensePlateRecognizerClass
115
+ except ImportError as e:
116
+ logging.error(f"Installation succeeded but import failed: {e}")
117
+ else:
118
+ logging.error(f"CPU installation failed: {result.stderr}")
119
+ except Exception as e:
120
+ logging.error(f"Error during CPU installation: {e}")
121
+
122
+ # Return None if all attempts failed
123
+ logging.error("All attempts to load or install LicensePlateRecognizer failed")
124
+ _OCR_IMPORT_SOURCE = "unavailable"
125
+ return None
56
126
 
57
127
  # Internal utilities that are still required
58
128
  from ..ocr.preprocessing import ImagePreprocessor
59
129
  from ..core.config import BaseConfig, AlertConfig, ZoneConfig
60
130
 
61
- # (Catch import errors early in the logs)
62
- try:
63
- _ = LicensePlateRecognizer # noqa: B018 reference to quiet linters
64
- except Exception as _e:
65
- print(f"Warning: fast_plate_ocr could not be imported {_e}")
66
-
67
131
  try:
68
132
  from matrice_common.session import Session
69
133
  HAS_MATRICE_SESSION = True
@@ -123,6 +187,8 @@ class LicensePlateMonitorLogger:
123
187
 
124
188
  def initialize_session(self, config: LicensePlateMonitorConfig) -> None:
125
189
  """Initialize session and fetch server connection info if lpr_server_id is provided."""
190
+ print("[LP_LOGGING] ===== INITIALIZING LP LOGGER SESSION =====")
191
+ print(f"[LP_LOGGING] Config lpr_server_id: {config.lpr_server_id}")
126
192
  self.logger.info("[LP_LOGGING] ===== INITIALIZING LP LOGGER SESSION =====")
127
193
  self.logger.info(f"[LP_LOGGING] Config lpr_server_id: {config.lpr_server_id}")
128
194
 
@@ -204,6 +270,7 @@ class LicensePlateMonitorLogger:
204
270
  else:
205
271
  self.logger.warning("[LP_LOGGING] No lpr_server_id provided in config, skipping server connection info fetch")
206
272
 
273
+ print("[LP_LOGGING] ===== LP LOGGER SESSION INITIALIZATION COMPLETE =====")
207
274
  self.logger.info("[LP_LOGGING] ===== LP LOGGER SESSION INITIALIZATION COMPLETE =====")
208
275
 
209
276
  def _get_public_ip(self) -> str:
@@ -261,9 +328,11 @@ class LicensePlateMonitorLogger:
261
328
  time_since_last_log = current_time - last_log_time
262
329
 
263
330
  if time_since_last_log >= cooldown:
331
+ print(f"[LP_LOGGING] ✓ Plate '{plate_text}' ready to log ({time_since_last_log:.1f}s since last)")
264
332
  self.logger.info(f"[LP_LOGGING] OK - Plate '{plate_text}' ready to log (last logged {time_since_last_log:.1f}s ago, cooldown={cooldown}s)")
265
333
  return True
266
334
  else:
335
+ print(f"[LP_LOGGING] ⊗ Plate '{plate_text}' in cooldown ({cooldown - time_since_last_log:.1f}s remaining)")
267
336
  self.logger.info(f"[LP_LOGGING] SKIP - Plate '{plate_text}' in cooldown period ({time_since_last_log:.1f}s elapsed, {cooldown - time_since_last_log:.1f}s remaining)")
268
337
  return False
269
338
 
@@ -325,11 +394,14 @@ class LicensePlateMonitorLogger:
325
394
  image_data: Base64-encoded JPEG image of the license plate crop
326
395
  cooldown: Cooldown period in seconds
327
396
  """
397
+ print(f"[LP_LOGGING] ===== PLATE LOG REQUEST START =====")
398
+ print(f"[LP_LOGGING] Plate: '{plate_text}', Timestamp: {timestamp}")
328
399
  self.logger.info(f"[LP_LOGGING] ===== PLATE LOG REQUEST START =====")
329
400
  self.logger.info(f"[LP_LOGGING] Plate: '{plate_text}', Timestamp: {timestamp}")
330
401
 
331
402
  # Check cooldown
332
403
  if not self.should_log_plate(plate_text, cooldown):
404
+ print(f"[LP_LOGGING] Plate '{plate_text}' NOT SENT - cooldown")
333
405
  self.logger.info(f"[LP_LOGGING] Plate '{plate_text}' NOT SENT - skipped due to cooldown period")
334
406
  self.logger.info(f"[LP_LOGGING] ===== PLATE LOG REQUEST END (SKIPPED) =====")
335
407
  return False
@@ -340,6 +412,7 @@ class LicensePlateMonitorLogger:
340
412
  location = camera_info.get("location", "")
341
413
  frame_id = stream_info.get("frame_id", "")
342
414
 
415
+ print(f"[LP_LOGGING] Camera: '{camera_name}', Location: '{location}'")
343
416
  self.logger.info(f"[LP_LOGGING] Stream Info - Camera: '{camera_name}', Location: '{location}', Frame ID: '{frame_id}'")
344
417
 
345
418
  # Get project ID from server_info
@@ -363,20 +436,24 @@ class LicensePlateMonitorLogger:
363
436
  # Add projectId as query parameter
364
437
  endpoint = f'/v1/lpr-server/detections?projectId={project_id}'
365
438
  full_url = f"{self.server_base_url}{endpoint}"
439
+ print(f"[LP_LOGGING] Sending POST to: {full_url}")
366
440
  self.logger.info(f"[LP_LOGGING] Sending POST request to: {full_url}")
367
441
  self.logger.info(f"[LP_LOGGING] Payload: licensePlate='{plate_text}', frameId='{frame_id}', location='{location}', camera='{camera_name}', imageData length={len(image_data) if image_data else 0}")
368
442
 
369
443
  response = await self.session.rpc.post_async(endpoint, payload=payload, base_url=self.server_base_url)
370
444
 
445
+ print(f"[LP_LOGGING] Response: {response}")
371
446
  self.logger.info(f"[LP_LOGGING] API Response received: {response}")
372
447
 
373
448
  # Update timestamp after successful log
374
449
  self.update_log_timestamp(plate_text)
450
+ print(f"[LP_LOGGING] ✓ Plate '{plate_text}' SUCCESSFULLY SENT")
375
451
  self.logger.info(f"[LP_LOGGING] Plate '{plate_text}' SUCCESSFULLY SENT at {rfc3339_timestamp}")
376
452
  self.logger.info(f"[LP_LOGGING] ===== PLATE LOG REQUEST END (SUCCESS) =====")
377
453
  return True
378
454
 
379
455
  except Exception as e:
456
+ print(f"[LP_LOGGING] ✗ Plate '{plate_text}' FAILED - {e}")
380
457
  self.logger.error(f"[LP_LOGGING] Plate '{plate_text}' NOT SENT - Exception occurred: {e}", exc_info=True)
381
458
  self.logger.info(f"[LP_LOGGING] ===== PLATE LOG REQUEST END (FAILED) =====")
382
459
  return False
@@ -384,13 +461,6 @@ class LicensePlateMonitorLogger:
384
461
  class LicensePlateMonitorUseCase(BaseProcessor):
385
462
  CATEGORY_DISPLAY = {"license_plate": "license_plate"}
386
463
 
387
- # --------------------------------------------------------------
388
- # Shared resources (initialised once per process)
389
- # --------------------------------------------------------------
390
- _ocr_model: Optional[LicensePlateRecognizer] = None # Fast plate OCR
391
-
392
-
393
-
394
464
  def __init__(self):
395
465
  super().__init__("license_plate_monitor")
396
466
  self.category = "license_plate_monitor"
@@ -420,22 +490,9 @@ class LicensePlateMonitorUseCase(BaseProcessor):
420
490
  # Map of track_id -> current dominant plate text
421
491
  self.unique_plate_track: Dict[Any, str] = {}
422
492
  self.image_preprocessor = ImagePreprocessor()
423
- # Fast OCR model (shared across instances)
424
- if LicensePlateMonitorUseCase._ocr_model is None:
425
- if _OCR_IMPORT_SOURCE == "stub":
426
- # Using stub - log warning once
427
- self.logger.error("OCR module not available. LicensePlateRecognizer will not function. Install: pip install fast-plate-ocr[onnx]")
428
- LicensePlateMonitorUseCase._ocr_model = LicensePlateRecognizer('cct-s-v1-global-model')
429
- else:
430
- # Try to load real OCR model
431
- try:
432
- LicensePlateMonitorUseCase._ocr_model = LicensePlateRecognizer('cct-s-v1-global-model')
433
- source_msg = "from local repo" if _OCR_IMPORT_SOURCE == "local_repo" else "from installed package"
434
- self.logger.info(f"LicensePlateRecognizer loaded successfully {source_msg}")
435
- except Exception as e:
436
- self.logger.error(f"Failed to initialize LicensePlateRecognizer: {e}", exc_info=True)
437
- LicensePlateMonitorUseCase._ocr_model = None
438
- self.ocr_model = LicensePlateMonitorUseCase._ocr_model
493
+ # OCR model will be lazily initialized when first used
494
+ self.ocr_model = None
495
+ self._ocr_initialization_attempted = False
439
496
  # OCR text history for stability checks (text consecutive frame count)
440
497
  self._text_history: Dict[str, int] = {}
441
498
 
@@ -511,25 +568,30 @@ class LicensePlateMonitorUseCase(BaseProcessor):
511
568
  self.logger.error(f"[LP_LOGGING] Plate logging has been DISABLED due to initialization failure")
512
569
  return False
513
570
 
514
- def _log_detected_plates(self, detections: List[Dict[str, Any]], config: LicensePlateMonitorConfig,
571
+ async def _log_detected_plates(self, detections: List[Dict[str, Any]], config: LicensePlateMonitorConfig,
515
572
  stream_info: Optional[Dict[str, Any]], image_bytes: Optional[bytes] = None) -> None:
516
573
  """Log all detected plates to RPC server with cooldown."""
517
574
  # Enhanced logging for diagnostics
575
+ print(f"[LP_LOGGING] Starting plate logging check - detections count: {len(detections)}")
518
576
  self.logger.info(f"[LP_LOGGING] Starting plate logging check - detections count: {len(detections)}")
519
577
  self.logger.info(f"[LP_LOGGING] Logging enabled: {self._logging_enabled}, Plate logger exists: {self.plate_logger is not None}, Stream info exists: {stream_info is not None}")
520
578
 
521
579
  if not self._logging_enabled:
580
+ print("[LP_LOGGING] Plate logging is DISABLED")
522
581
  self.logger.warning("[LP_LOGGING] Plate logging is DISABLED - logging_enabled flag is False")
523
582
  return
524
583
 
525
584
  if not self.plate_logger:
585
+ print("[LP_LOGGING] Plate logging SKIPPED - plate_logger not initialized")
526
586
  self.logger.warning("[LP_LOGGING] Plate logging SKIPPED - plate_logger is not initialized (lpr_server_id may not be configured)")
527
587
  return
528
588
 
529
589
  if not stream_info:
590
+ print("[LP_LOGGING] Plate logging SKIPPED - stream_info is None")
530
591
  self.logger.warning("[LP_LOGGING] Plate logging SKIPPED - stream_info is None")
531
592
  return
532
593
 
594
+ print("[LP_LOGGING] All pre-conditions met, proceeding with plate logging")
533
595
  self.logger.info(f"[LP_LOGGING] All pre-conditions met, proceeding with plate logging")
534
596
 
535
597
  # Get current timestamp
@@ -569,49 +631,45 @@ class LicensePlateMonitorUseCase(BaseProcessor):
569
631
  continue
570
632
  plates_to_log.add(plate_text)
571
633
 
634
+ print(f"[LP_LOGGING] Collected {len(plates_to_log)} unique plates to log: {plates_to_log}")
572
635
  self.logger.info(f"[LP_LOGGING] Collected {len(plates_to_log)} unique plates to log: {plates_to_log}")
573
636
  if detections_without_text > 0:
574
637
  self.logger.warning(f"[LP_LOGGING] {detections_without_text} detections have NO plate_text (OCR may have failed or not run yet)")
575
638
 
576
- # Log each unique plate (respecting cooldown)
639
+ # Log each unique plate directly with await (respecting cooldown)
577
640
  if plates_to_log:
578
- self.logger.info(f"[LP_LOGGING] Starting async logging for {len(plates_to_log)} plates with cooldown={config.plate_log_cooldown}s")
641
+ print(f"[LP_LOGGING] Logging {len(plates_to_log)} plates with cooldown={config.plate_log_cooldown}s")
642
+ self.logger.info(f"[LP_LOGGING] Logging {len(plates_to_log)} plates with cooldown={config.plate_log_cooldown}s")
579
643
  try:
580
- # Run async logging tasks
581
- loop = asyncio.new_event_loop()
582
- asyncio.set_event_loop(loop)
583
- try:
584
- tasks = []
585
- for plate_text in plates_to_log:
586
- self.logger.info(f"[LP_LOGGING] Creating task for plate: {plate_text}")
587
- task = self.plate_logger.log_plate(
644
+ # Call log_plate directly with await for each plate
645
+ for plate_text in plates_to_log:
646
+ print(f"[LP_LOGGING] Processing plate: {plate_text}")
647
+ self.logger.info(f"[LP_LOGGING] Processing plate: {plate_text}")
648
+ try:
649
+ result = await self.plate_logger.log_plate(
588
650
  plate_text=plate_text,
589
651
  timestamp=current_timestamp,
590
652
  stream_info=stream_info,
591
653
  image_data=image_data,
592
654
  cooldown=config.plate_log_cooldown
593
655
  )
594
- tasks.append(task)
595
-
596
- # Run all logging tasks concurrently
597
- self.logger.info(f"[LP_LOGGING] Executing {len(tasks)} async logging tasks")
598
- results = loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True))
599
-
600
- # Log results
601
- for i, (plate, result) in enumerate(zip(plates_to_log, results)):
602
- if isinstance(result, Exception):
603
- self.logger.error(f"[LP_LOGGING] Task {i} for plate {plate} raised exception: {result}")
604
- else:
605
- self.logger.info(f"[LP_LOGGING] Task {i} for plate {plate} completed with result: {result}")
606
- finally:
607
- loop.close()
608
- self.logger.info(f"[LP_LOGGING] Event loop closed")
656
+ status = "SENT" if result else "SKIPPED (cooldown)"
657
+ print(f"[LP_LOGGING] Plate {plate_text}: {status}")
658
+ self.logger.info(f"[LP_LOGGING] Plate {plate_text}: {status}")
659
+ except Exception as e:
660
+ print(f"[LP_LOGGING] ERROR - Plate {plate_text} failed: {e}")
661
+ self.logger.error(f"[LP_LOGGING] Plate {plate_text} raised exception: {e}", exc_info=True)
662
+
663
+ print("[LP_LOGGING] Plate logging complete")
664
+ self.logger.info(f"[LP_LOGGING] Plate logging complete")
609
665
  except Exception as e:
666
+ print(f"[LP_LOGGING] CRITICAL ERROR during plate logging: {e}")
610
667
  self.logger.error(f"[LP_LOGGING] CRITICAL ERROR during plate logging: {e}", exc_info=True)
611
668
  else:
669
+ print("[LP_LOGGING] No plates to log")
612
670
  self.logger.info(f"[LP_LOGGING] No plates to log (plates_to_log is empty)")
613
671
 
614
- def process(self, data: Any, config: ConfigProtocol, input_bytes: Optional[bytes] = None,
672
+ async def process(self, data: Any, config: ConfigProtocol, input_bytes: Optional[bytes] = None,
615
673
  context: Optional[ProcessingContext] = None, stream_info: Optional[Dict[str, Any]] = None) -> ProcessingResult:
616
674
  processing_start = time.time()
617
675
  try:
@@ -647,19 +705,8 @@ class LicensePlateMonitorUseCase(BaseProcessor):
647
705
  except Exception:
648
706
  pass
649
707
 
650
- # Initialize OCR extractor if not already done
651
- if self.ocr_model is None:
652
- self.logger.info("Lazy initialisation fallback (should rarely happen)")
653
- try:
654
- LicensePlateMonitorUseCase._ocr_model = LicensePlateRecognizer('cct-s-v1-global-model')
655
- self.ocr_model = LicensePlateMonitorUseCase._ocr_model
656
- except Exception as e:
657
- return self.create_error_result(
658
- f"Failed to initialise OCR model: {e}",
659
- usecase=self.name,
660
- category=self.category,
661
- context=context,
662
- )
708
+ # OCR model will be lazily initialized when _run_ocr is first called
709
+ # No need to initialize here
663
710
 
664
711
  input_format = match_results_structure(data)
665
712
  context.input_format = input_format
@@ -744,7 +791,8 @@ class LicensePlateMonitorUseCase(BaseProcessor):
744
791
  self.logger.info(f"[LP_LOGGING] After OCR update, {len(final_plates)} detections have plate_text: {final_plates}")
745
792
 
746
793
  # Step 9.5: Log detected plates to RPC (optional, only if lpr_server_id is provided)
747
- self._log_detected_plates(processed_data, config, stream_info, input_bytes)
794
+ # Direct await since process is now async
795
+ await self._log_detected_plates(processed_data, config, stream_info, input_bytes)
748
796
 
749
797
  # Step 10: Update frame counter
750
798
  self._total_frame_counter += 1
@@ -914,6 +962,39 @@ class LicensePlateMonitorUseCase(BaseProcessor):
914
962
  # ------------------------------------------------------------------
915
963
  # Fast OCR helpers
916
964
  # ------------------------------------------------------------------
965
+ def _ensure_ocr_model_loaded(self) -> bool:
966
+ """Lazy initialization of OCR model. Returns True if model is available."""
967
+ if self.ocr_model is not None:
968
+ return True
969
+
970
+ if self._ocr_initialization_attempted:
971
+ return False
972
+
973
+ self._ocr_initialization_attempted = True
974
+
975
+ # Try to get the LicensePlateRecognizer class
976
+ LicensePlateRecognizerClass = _get_license_plate_recognizer_class()
977
+
978
+ if LicensePlateRecognizerClass is None:
979
+ self.logger.error("OCR module not available. LicensePlateRecognizer will not function.")
980
+ return False
981
+
982
+ # Try to initialize the OCR model
983
+ try:
984
+ self.ocr_model = LicensePlateRecognizerClass('cct-s-v1-global-model')
985
+ source_msg = {
986
+ "local_repo": "from local repo",
987
+ "installed_package": "from installed package",
988
+ "installed_package_gpu": "from installed package (GPU)",
989
+ "installed_package_cpu": "from installed package (CPU)"
990
+ }.get(_OCR_IMPORT_SOURCE, "from unknown source")
991
+ self.logger.info(f"LicensePlateRecognizer loaded successfully {source_msg}")
992
+ return True
993
+ except Exception as e:
994
+ self.logger.error(f"Failed to initialize LicensePlateRecognizer: {e}", exc_info=True)
995
+ self.ocr_model = None
996
+ return False
997
+
917
998
  def _clean_text(self, text: str) -> str:
918
999
  """Sanitise OCR output to keep only alphanumerics and uppercase."""
919
1000
  if not text:
@@ -922,10 +1003,18 @@ class LicensePlateMonitorUseCase(BaseProcessor):
922
1003
 
923
1004
  def _run_ocr(self, crop: np.ndarray) -> str:
924
1005
  """Run OCR on a cropped plate image and return cleaned text or empty string."""
925
- if crop is None or crop.size == 0 or self.ocr_model is None:
1006
+ if crop is None or crop.size == 0:
1007
+ return ""
1008
+
1009
+ # Lazy load OCR model on first use
1010
+ if not self._ensure_ocr_model_loaded():
1011
+ return ""
1012
+
1013
+ # Double-check model is available
1014
+ if self.ocr_model is None:
926
1015
  return ""
927
1016
 
928
- # Check if we have a valid OCR model (not the stub) - silently return empty if stub
1017
+ # Check if we have a valid OCR model with run method
929
1018
  if not hasattr(self.ocr_model, 'run'):
930
1019
  return ""
931
1020