matrice-analytics 0.1.35__py3-none-any.whl → 0.1.36__py3-none-any.whl

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.

@@ -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
@@ -420,22 +497,9 @@ class LicensePlateMonitorUseCase(BaseProcessor):
420
497
  # Map of track_id -> current dominant plate text
421
498
  self.unique_plate_track: Dict[Any, str] = {}
422
499
  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
500
+ # OCR model will be lazily initialized when first used
501
+ self.ocr_model = None
502
+ self._ocr_initialization_attempted = False
439
503
  # OCR text history for stability checks (text consecutive frame count)
440
504
  self._text_history: Dict[str, int] = {}
441
505
 
@@ -511,25 +575,30 @@ class LicensePlateMonitorUseCase(BaseProcessor):
511
575
  self.logger.error(f"[LP_LOGGING] Plate logging has been DISABLED due to initialization failure")
512
576
  return False
513
577
 
514
- def _log_detected_plates(self, detections: List[Dict[str, Any]], config: LicensePlateMonitorConfig,
578
+ async def _log_detected_plates(self, detections: List[Dict[str, Any]], config: LicensePlateMonitorConfig,
515
579
  stream_info: Optional[Dict[str, Any]], image_bytes: Optional[bytes] = None) -> None:
516
580
  """Log all detected plates to RPC server with cooldown."""
517
581
  # Enhanced logging for diagnostics
582
+ print(f"[LP_LOGGING] Starting plate logging check - detections count: {len(detections)}")
518
583
  self.logger.info(f"[LP_LOGGING] Starting plate logging check - detections count: {len(detections)}")
519
584
  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
585
 
521
586
  if not self._logging_enabled:
587
+ print("[LP_LOGGING] Plate logging is DISABLED")
522
588
  self.logger.warning("[LP_LOGGING] Plate logging is DISABLED - logging_enabled flag is False")
523
589
  return
524
590
 
525
591
  if not self.plate_logger:
592
+ print("[LP_LOGGING] Plate logging SKIPPED - plate_logger not initialized")
526
593
  self.logger.warning("[LP_LOGGING] Plate logging SKIPPED - plate_logger is not initialized (lpr_server_id may not be configured)")
527
594
  return
528
595
 
529
596
  if not stream_info:
597
+ print("[LP_LOGGING] Plate logging SKIPPED - stream_info is None")
530
598
  self.logger.warning("[LP_LOGGING] Plate logging SKIPPED - stream_info is None")
531
599
  return
532
600
 
601
+ print("[LP_LOGGING] All pre-conditions met, proceeding with plate logging")
533
602
  self.logger.info(f"[LP_LOGGING] All pre-conditions met, proceeding with plate logging")
534
603
 
535
604
  # Get current timestamp
@@ -569,49 +638,45 @@ class LicensePlateMonitorUseCase(BaseProcessor):
569
638
  continue
570
639
  plates_to_log.add(plate_text)
571
640
 
641
+ print(f"[LP_LOGGING] Collected {len(plates_to_log)} unique plates to log: {plates_to_log}")
572
642
  self.logger.info(f"[LP_LOGGING] Collected {len(plates_to_log)} unique plates to log: {plates_to_log}")
573
643
  if detections_without_text > 0:
574
644
  self.logger.warning(f"[LP_LOGGING] {detections_without_text} detections have NO plate_text (OCR may have failed or not run yet)")
575
645
 
576
- # Log each unique plate (respecting cooldown)
646
+ # Log each unique plate directly with await (respecting cooldown)
577
647
  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")
648
+ print(f"[LP_LOGGING] Logging {len(plates_to_log)} plates with cooldown={config.plate_log_cooldown}s")
649
+ self.logger.info(f"[LP_LOGGING] Logging {len(plates_to_log)} plates with cooldown={config.plate_log_cooldown}s")
579
650
  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(
651
+ # Call log_plate directly with await for each plate
652
+ for plate_text in plates_to_log:
653
+ print(f"[LP_LOGGING] Processing plate: {plate_text}")
654
+ self.logger.info(f"[LP_LOGGING] Processing plate: {plate_text}")
655
+ try:
656
+ result = await self.plate_logger.log_plate(
588
657
  plate_text=plate_text,
589
658
  timestamp=current_timestamp,
590
659
  stream_info=stream_info,
591
660
  image_data=image_data,
592
661
  cooldown=config.plate_log_cooldown
593
662
  )
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")
663
+ status = "SENT" if result else "SKIPPED (cooldown)"
664
+ print(f"[LP_LOGGING] Plate {plate_text}: {status}")
665
+ self.logger.info(f"[LP_LOGGING] Plate {plate_text}: {status}")
666
+ except Exception as e:
667
+ print(f"[LP_LOGGING] ERROR - Plate {plate_text} failed: {e}")
668
+ self.logger.error(f"[LP_LOGGING] Plate {plate_text} raised exception: {e}", exc_info=True)
669
+
670
+ print("[LP_LOGGING] Plate logging complete")
671
+ self.logger.info(f"[LP_LOGGING] Plate logging complete")
609
672
  except Exception as e:
673
+ print(f"[LP_LOGGING] CRITICAL ERROR during plate logging: {e}")
610
674
  self.logger.error(f"[LP_LOGGING] CRITICAL ERROR during plate logging: {e}", exc_info=True)
611
675
  else:
676
+ print("[LP_LOGGING] No plates to log")
612
677
  self.logger.info(f"[LP_LOGGING] No plates to log (plates_to_log is empty)")
613
678
 
614
- def process(self, data: Any, config: ConfigProtocol, input_bytes: Optional[bytes] = None,
679
+ async def process(self, data: Any, config: ConfigProtocol, input_bytes: Optional[bytes] = None,
615
680
  context: Optional[ProcessingContext] = None, stream_info: Optional[Dict[str, Any]] = None) -> ProcessingResult:
616
681
  processing_start = time.time()
617
682
  try:
@@ -647,19 +712,8 @@ class LicensePlateMonitorUseCase(BaseProcessor):
647
712
  except Exception:
648
713
  pass
649
714
 
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
- )
715
+ # OCR model will be lazily initialized when _run_ocr is first called
716
+ # No need to initialize here
663
717
 
664
718
  input_format = match_results_structure(data)
665
719
  context.input_format = input_format
@@ -744,7 +798,8 @@ class LicensePlateMonitorUseCase(BaseProcessor):
744
798
  self.logger.info(f"[LP_LOGGING] After OCR update, {len(final_plates)} detections have plate_text: {final_plates}")
745
799
 
746
800
  # 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)
801
+ # Direct await since process is now async
802
+ await self._log_detected_plates(processed_data, config, stream_info, input_bytes)
748
803
 
749
804
  # Step 10: Update frame counter
750
805
  self._total_frame_counter += 1
@@ -914,6 +969,39 @@ class LicensePlateMonitorUseCase(BaseProcessor):
914
969
  # ------------------------------------------------------------------
915
970
  # Fast OCR helpers
916
971
  # ------------------------------------------------------------------
972
+ def _ensure_ocr_model_loaded(self) -> bool:
973
+ """Lazy initialization of OCR model. Returns True if model is available."""
974
+ if self.ocr_model is not None:
975
+ return True
976
+
977
+ if self._ocr_initialization_attempted:
978
+ return False
979
+
980
+ self._ocr_initialization_attempted = True
981
+
982
+ # Try to get the LicensePlateRecognizer class
983
+ LicensePlateRecognizerClass = _get_license_plate_recognizer_class()
984
+
985
+ if LicensePlateRecognizerClass is None:
986
+ self.logger.error("OCR module not available. LicensePlateRecognizer will not function.")
987
+ return False
988
+
989
+ # Try to initialize the OCR model
990
+ try:
991
+ self.ocr_model = LicensePlateRecognizerClass('cct-s-v1-global-model')
992
+ source_msg = {
993
+ "local_repo": "from local repo",
994
+ "installed_package": "from installed package",
995
+ "installed_package_gpu": "from installed package (GPU)",
996
+ "installed_package_cpu": "from installed package (CPU)"
997
+ }.get(_OCR_IMPORT_SOURCE, "from unknown source")
998
+ self.logger.info(f"LicensePlateRecognizer loaded successfully {source_msg}")
999
+ return True
1000
+ except Exception as e:
1001
+ self.logger.error(f"Failed to initialize LicensePlateRecognizer: {e}", exc_info=True)
1002
+ self.ocr_model = None
1003
+ return False
1004
+
917
1005
  def _clean_text(self, text: str) -> str:
918
1006
  """Sanitise OCR output to keep only alphanumerics and uppercase."""
919
1007
  if not text:
@@ -922,10 +1010,18 @@ class LicensePlateMonitorUseCase(BaseProcessor):
922
1010
 
923
1011
  def _run_ocr(self, crop: np.ndarray) -> str:
924
1012
  """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:
1013
+ if crop is None or crop.size == 0:
1014
+ return ""
1015
+
1016
+ # Lazy load OCR model on first use
1017
+ if not self._ensure_ocr_model_loaded():
1018
+ return ""
1019
+
1020
+ # Double-check model is available
1021
+ if self.ocr_model is None:
926
1022
  return ""
927
1023
 
928
- # Check if we have a valid OCR model (not the stub) - silently return empty if stub
1024
+ # Check if we have a valid OCR model with run method
929
1025
  if not hasattr(self.ocr_model, 'run'):
930
1026
  return ""
931
1027
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice_analytics
3
- Version: 0.1.35
3
+ Version: 0.1.36
4
4
  Summary: Common server utilities for Matrice.ai services
5
5
  Author-email: "Matrice.ai" <dipendra@matrice.ai>
6
6
  License-Expression: MIT
@@ -13,7 +13,7 @@ matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py,sh
13
13
  matrice_analytics/post_processing/README.md,sha256=bDszazvqV5xbGhMM6hDaMctIyk5gox9bADo2IZZ9Goo,13368
14
14
  matrice_analytics/post_processing/__init__.py,sha256=dxGBUQaRCGndQmXpYAWqUhDeUZAcxU-_6HFnm3GRDRA,29417
15
15
  matrice_analytics/post_processing/config.py,sha256=V0s86qNapyDE6Q81ZS_1uzNqAjz-vc5L-9Tb33XaLEo,6771
16
- matrice_analytics/post_processing/post_processor.py,sha256=ql4WuT1qVusXXYP36PNICQYPgvWOwBBErAb4UBMXlm8,44344
16
+ matrice_analytics/post_processing/post_processor.py,sha256=F838_vc7p9tjcp-vTMgTbpHqQcLX94xhL9HM06Wvpo8,44384
17
17
  matrice_analytics/post_processing/advanced_tracker/README.md,sha256=RM8dynVoUWKn_hTbw9c6jHAbnQj-8hEAXnmuRZr2w1M,22485
18
18
  matrice_analytics/post_processing/advanced_tracker/__init__.py,sha256=tAPFzI_Yep5TLX60FDwKqBqppc-EbxSr0wNsQ9DGI1o,423
19
19
  matrice_analytics/post_processing/advanced_tracker/base.py,sha256=VqWy4dd5th5LK-JfueTt2_GSEoOi5QQfQxjTNhmQoLc,3580
@@ -126,7 +126,7 @@ matrice_analytics/post_processing/usecases/leaf.py,sha256=cwgB1ZNxkQFtkk-thSJrkX
126
126
  matrice_analytics/post_processing/usecases/leaf_disease.py,sha256=bkiLccTdf4KUq3he4eCpBlKXb5exr-WBhQ_oWQ7os68,36225
127
127
  matrice_analytics/post_processing/usecases/leak_detection.py,sha256=oOCLLVMuXVeXPHyN8FUrD3U9JYJJwIz-5fcEMgvLdls,40531
128
128
  matrice_analytics/post_processing/usecases/license_plate_detection.py,sha256=dsavd92-wnyXCNrCzaRj24zH7BVvLSa09HkYsrOXYDM,50806
129
- matrice_analytics/post_processing/usecases/license_plate_monitoring.py,sha256=LL-oFNq2SBrg57jLMmQRReyNI6D7zJYky9IoCnw1me8,84804
129
+ matrice_analytics/post_processing/usecases/license_plate_monitoring.py,sha256=5YvqGwvvocyBZkFgSnCGuvCp4XT_YTrPuO-RHOEjRAk,89336
130
130
  matrice_analytics/post_processing/usecases/litter_monitoring.py,sha256=XaHAUGRBDJg_iVbu8hRMjTR-5TqrLj6ZNCRkInbzZTY,33255
131
131
  matrice_analytics/post_processing/usecases/mask_detection.py,sha256=L_s6ZiT5zeXG-BsFcskb3HEG98DhLgqeMSDmCuwOteU,41501
132
132
  matrice_analytics/post_processing/usecases/natural_disaster.py,sha256=ehxdPBoYcZWGVDOVn_mHFoz4lIE8LrveAkuXQj0n9XE,44253
@@ -188,8 +188,8 @@ matrice_analytics/post_processing/utils/format_utils.py,sha256=UTF7A5h9j0_S12xH9
188
188
  matrice_analytics/post_processing/utils/geometry_utils.py,sha256=BWfdM6RsdJTTLR1GqkWfdwpjMEjTCJyuBxA4zVGKdfk,9623
189
189
  matrice_analytics/post_processing/utils/smoothing_utils.py,sha256=78U-yucAcjUiZ0NIAc9NOUSIT0PWP1cqyIPA_Fdrjp0,14699
190
190
  matrice_analytics/post_processing/utils/tracking_utils.py,sha256=rWxuotnJ3VLMHIBOud2KLcu4yZfDp7hVPWUtNAq_2xw,8288
191
- matrice_analytics-0.1.35.dist-info/licenses/LICENSE.txt,sha256=_uQUZpgO0mRYL5-fPoEvLSbNnLPv6OmbeEDCHXhK6Qc,1066
192
- matrice_analytics-0.1.35.dist-info/METADATA,sha256=0h391iXJNFSJWWuYDxgd7U8eQZhR9FLAunYRSa25s2U,14378
193
- matrice_analytics-0.1.35.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
194
- matrice_analytics-0.1.35.dist-info/top_level.txt,sha256=STAPEU-e-rWTerXaspdi76T_eVRSrEfFpURSP7_Dt8E,18
195
- matrice_analytics-0.1.35.dist-info/RECORD,,
191
+ matrice_analytics-0.1.36.dist-info/licenses/LICENSE.txt,sha256=_uQUZpgO0mRYL5-fPoEvLSbNnLPv6OmbeEDCHXhK6Qc,1066
192
+ matrice_analytics-0.1.36.dist-info/METADATA,sha256=SOV2XH7crdPmqvOuZmjQvlkrVM0BoWI1fK2K2xmlR64,14378
193
+ matrice_analytics-0.1.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
194
+ matrice_analytics-0.1.36.dist-info/top_level.txt,sha256=STAPEU-e-rWTerXaspdi76T_eVRSrEfFpURSP7_Dt8E,18
195
+ matrice_analytics-0.1.36.dist-info/RECORD,,