matrice 1.0.99396__py3-none-any.whl → 1.0.99398__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.
- matrice/deploy/__init__.py +3 -2
- matrice/deploy/utils/post_processing/usecases/license_plate_monitoring.py +163 -108
- {matrice-1.0.99396.dist-info → matrice-1.0.99398.dist-info}/METADATA +1 -1
- {matrice-1.0.99396.dist-info → matrice-1.0.99398.dist-info}/RECORD +7 -7
- {matrice-1.0.99396.dist-info → matrice-1.0.99398.dist-info}/WHEEL +0 -0
- {matrice-1.0.99396.dist-info → matrice-1.0.99398.dist-info}/licenses/LICENSE.txt +0 -0
- {matrice-1.0.99396.dist-info → matrice-1.0.99398.dist-info}/top_level.txt +0 -0
matrice/deploy/__init__.py
CHANGED
@@ -18,18 +18,24 @@ from ..utils import (
|
|
18
18
|
BBoxSmoothingConfig,
|
19
19
|
BBoxSmoothingTracker
|
20
20
|
)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
from ..ocr.postprocessing import TextPostprocessor
|
27
|
-
from ..ocr.preprocessing import ImagePreprocessor
|
28
|
-
from ..core.config import BaseConfig, AlertConfig, ZoneConfig
|
29
|
-
|
30
|
-
except:
|
31
|
-
print("test-------------------------------------------------")
|
21
|
+
# External dependencies
|
22
|
+
import cv2
|
23
|
+
import numpy as np
|
24
|
+
#import torch
|
25
|
+
import re
|
32
26
|
|
27
|
+
# Fast license-plate OCR (replaces EasyOCR)
|
28
|
+
from fast_plate_ocr import LicensePlateRecognizer
|
29
|
+
|
30
|
+
# Internal utilities that are still required
|
31
|
+
from ..ocr.preprocessing import ImagePreprocessor
|
32
|
+
from ..core.config import BaseConfig, AlertConfig, ZoneConfig
|
33
|
+
|
34
|
+
# (Catch import errors early in the logs)
|
35
|
+
try:
|
36
|
+
_ = LicensePlateRecognizer # noqa: B018 – reference to quiet linters
|
37
|
+
except Exception as _e:
|
38
|
+
print(f"Warning: fast_plate_ocr could not be imported ⇒ {_e}")
|
33
39
|
|
34
40
|
|
35
41
|
@dataclass
|
@@ -71,6 +77,17 @@ class LicensePlateMonitorConfig(BaseConfig):
|
|
71
77
|
class LicensePlateMonitorUseCase(BaseProcessor):
|
72
78
|
CATEGORY_DISPLAY = {"License_Plate": "License Plate"}
|
73
79
|
|
80
|
+
# --------------------------------------------------------------
|
81
|
+
# Shared resources (initialised once per process)
|
82
|
+
# --------------------------------------------------------------
|
83
|
+
_ocr_model: Optional[LicensePlateRecognizer] = None # Fast plate OCR
|
84
|
+
_non_alnum_regex = re.compile(r"[^A-Za-z0-9]+")
|
85
|
+
|
86
|
+
# Minimum length for a valid plate (after cleaning)
|
87
|
+
_min_plate_len = 5
|
88
|
+
# number of consecutive frames a plate must appear to be considered "stable"
|
89
|
+
_stable_frames_required = 3
|
90
|
+
|
74
91
|
def __init__(self):
|
75
92
|
super().__init__("license_plate_monitor")
|
76
93
|
self.category = "license_plate_monitor"
|
@@ -91,10 +108,19 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
91
108
|
self._seen_plate_texts = set()
|
92
109
|
# CHANGE: Added _tracked_plate_texts to store the longest plate_text per track_id
|
93
110
|
self._tracked_plate_texts: Dict[Any, str] = {}
|
94
|
-
|
111
|
+
# Containers for text stability & uniqueness
|
112
|
+
self._unique_plate_texts: Dict[str, str] = {} # cleaned_text -> original (longest)
|
95
113
|
self.image_preprocessor = ImagePreprocessor()
|
96
|
-
|
97
|
-
|
114
|
+
# Fast OCR model (shared across instances)
|
115
|
+
if LicensePlateMonitorUseCase._ocr_model is None:
|
116
|
+
try:
|
117
|
+
LicensePlateMonitorUseCase._ocr_model = LicensePlateRecognizer('cct-s-v1-global-model')
|
118
|
+
self.logger.info("LicensePlateRecognizer loaded successfully")
|
119
|
+
except Exception as e:
|
120
|
+
self.logger.error(f"Failed to initialise LicensePlateRecognizer: {e}")
|
121
|
+
self.ocr_model = LicensePlateMonitorUseCase._ocr_model
|
122
|
+
# OCR text history for stability checks (text → consecutive frame count)
|
123
|
+
self._text_history: Dict[str, int] = {}
|
98
124
|
|
99
125
|
self.start_timer = None
|
100
126
|
#self.reset_timer = "2025-08-19-04:22:47.187574 UTC"
|
@@ -112,24 +138,10 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
112
138
|
self._tracked_plate_texts = {}
|
113
139
|
self._total_frame_counter = 0
|
114
140
|
self._global_frame_offset = 0
|
141
|
+
self._text_history = {}
|
142
|
+
self._unique_plate_texts = {}
|
115
143
|
self.logger.info("Plate tracking state reset")
|
116
144
|
|
117
|
-
# def _normalize_plate_text(self, text: str) -> str:
|
118
|
-
# """Normalize plate text for comparison (e.g., remove spaces, convert to uppercase)."""
|
119
|
-
# if not text or not text.strip():
|
120
|
-
# return ""
|
121
|
-
# text = text.replace(" ", "").upper()
|
122
|
-
# # Map Arabic numerals to Latin to handle cases like ٠٠٤٦١٠
|
123
|
-
# arabic_to_latin = str.maketrans("٠١٢٣٤٥٦٧٨٩", "0123456789")
|
124
|
-
# text = text.translate(arabic_to_latin)
|
125
|
-
# # Optional: Add OCR error corrections (e.g., 'O' to '0', 'I' to '1')
|
126
|
-
# ocr_corrections = str.maketrans({'O': '0', 'I': '1', 'S': '5'})
|
127
|
-
# text = text.translate(ocr_corrections)
|
128
|
-
# # Validate: Ensure text is alphanumeric and at least 3 characters
|
129
|
-
# if len(text) < 3 or not text.isalnum():
|
130
|
-
# return ""
|
131
|
-
# return text
|
132
|
-
|
133
145
|
def reset_all_tracking(self) -> None:
|
134
146
|
"""Reset both advanced tracker and plate tracking state."""
|
135
147
|
self.reset_tracker()
|
@@ -152,19 +164,19 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
152
164
|
return self.create_error_result("input_bytes (video/image) is required for license plate monitoring",
|
153
165
|
usecase=self.name, category=self.category, context=context)
|
154
166
|
|
155
|
-
# if not data:
|
156
|
-
# return self.create_result(
|
157
|
-
# data={"agg_summary": {}},
|
158
|
-
# usecase=self.name,
|
159
|
-
# category=self.category,
|
160
|
-
# context=context
|
161
|
-
# )
|
162
|
-
# return self.create_error_result("Detection data is required for license plate monitoring",
|
163
|
-
# usecase=self.name, category=self.category, context=context)
|
164
|
-
|
165
167
|
# Initialize OCR extractor if not already done
|
166
|
-
if self.
|
167
|
-
self.
|
168
|
+
if self.ocr_model is None:
|
169
|
+
self.logger.info("Lazy initialisation fallback (should rarely happen)")
|
170
|
+
try:
|
171
|
+
LicensePlateMonitorUseCase._ocr_model = LicensePlateRecognizer('cct-s-v1-global-model')
|
172
|
+
self.ocr_model = LicensePlateMonitorUseCase._ocr_model
|
173
|
+
except Exception as e:
|
174
|
+
return self.create_error_result(
|
175
|
+
f"Failed to initialise OCR model: {e}",
|
176
|
+
usecase=self.name,
|
177
|
+
category=self.category,
|
178
|
+
context=context,
|
179
|
+
)
|
168
180
|
|
169
181
|
input_format = match_results_structure(data)
|
170
182
|
context.input_format = input_format
|
@@ -226,6 +238,8 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
226
238
|
|
227
239
|
# Step 8: Perform OCR on media
|
228
240
|
ocr_analysis = self._analyze_ocr_in_media(processed_data, input_bytes, config)
|
241
|
+
|
242
|
+
print("ocr_analysis", ocr_analysis)
|
229
243
|
|
230
244
|
# Step 9: Update plate texts
|
231
245
|
processed_data = self._update_detections_with_ocr(processed_data, ocr_analysis)
|
@@ -299,6 +313,7 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
299
313
|
def _analyze_ocr_in_media(self, data: Any, media_bytes: bytes, config: LicensePlateMonitorConfig) -> List[Dict[str, Any]]:
|
300
314
|
"""Analyze OCR of license plates in video frames or images."""
|
301
315
|
is_video = self._is_video_bytes(media_bytes)
|
316
|
+
print('is_video',is_video)
|
302
317
|
if is_video:
|
303
318
|
return self._analyze_ocr_in_video(data, media_bytes, config)
|
304
319
|
else:
|
@@ -348,13 +363,8 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
348
363
|
if crop.size == 0:
|
349
364
|
continue
|
350
365
|
|
351
|
-
|
352
|
-
|
353
|
-
texts = [r['text'] for r in ocr_results]
|
354
|
-
confs = [r['confidence'] for r in ocr_results]
|
355
|
-
processed = self.text_postprocessor.postprocess(texts, confs, task="license_plate", region=config.country, confidence_threshold=0.3)
|
356
|
-
valid_processed = [p for p in processed if p[2]]
|
357
|
-
plate_text = valid_processed[0][0] if valid_processed else None
|
366
|
+
plate_text_raw = self._run_ocr(crop)
|
367
|
+
plate_text = plate_text_raw if plate_text_raw else None
|
358
368
|
|
359
369
|
ocr_record = {
|
360
370
|
"frame_id": frame_key,
|
@@ -388,26 +398,27 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
388
398
|
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
389
399
|
ocr_analysis = []
|
390
400
|
detections = self._get_frame_detections(data, "0")
|
401
|
+
|
402
|
+
print("OCR-detections", detections)
|
391
403
|
|
392
404
|
for detection in detections:
|
405
|
+
print("---------OCR DETECTION",detection)
|
393
406
|
if detection.get("confidence", 1.0) < config.confidence_threshold:
|
394
407
|
continue
|
395
408
|
|
396
409
|
bbox = detection.get("bounding_box", detection.get("bbox"))
|
410
|
+
print("---------OCR BBOX",bbox)
|
397
411
|
if not bbox:
|
398
412
|
continue
|
399
413
|
|
400
414
|
crop = self._crop_bbox(rgb_image, bbox, config.bbox_format)
|
415
|
+
print("---------OCR CROP SIZEE",crop.size)
|
401
416
|
if crop.size == 0:
|
402
417
|
continue
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
confs = [r['confidence'] for r in ocr_results]
|
408
|
-
processed = self.text_postprocessor.postprocess(texts, confs, task="license_plate", region=config.country, confidence_threshold=0.3)
|
409
|
-
valid_processed = [p for p in processed if p[2]]
|
410
|
-
plate_text = valid_processed[0][0] if valid_processed else None
|
418
|
+
|
419
|
+
plate_text_raw = self._run_ocr(crop)
|
420
|
+
print("---------OCR PLATE TEXT",plate_text_raw)
|
421
|
+
plate_text = plate_text_raw if plate_text_raw else None
|
411
422
|
|
412
423
|
ocr_record = {
|
413
424
|
"frame_id": "0",
|
@@ -450,6 +461,34 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
450
461
|
|
451
462
|
return image[ymin:ymax, xmin:xmax]
|
452
463
|
|
464
|
+
# ------------------------------------------------------------------
|
465
|
+
# Fast OCR helpers
|
466
|
+
# ------------------------------------------------------------------
|
467
|
+
def _clean_text(self, text: str) -> str:
|
468
|
+
"""Sanitise OCR output to keep only alphanumerics and uppercase."""
|
469
|
+
if not text:
|
470
|
+
return ""
|
471
|
+
return LicensePlateMonitorUseCase._non_alnum_regex.sub('', text).upper()
|
472
|
+
|
473
|
+
def _run_ocr(self, crop: np.ndarray) -> str:
|
474
|
+
"""Run OCR on a cropped plate image and return cleaned text or empty string."""
|
475
|
+
print("---------OCR CROP22",crop)
|
476
|
+
print("---------OCR CROP SIZE22",crop.size)
|
477
|
+
|
478
|
+
if crop is None or crop.size == 0 or self.ocr_model is None:
|
479
|
+
return ""
|
480
|
+
try:
|
481
|
+
# fast_plate_ocr expects RGB
|
482
|
+
rgb_crop = cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)
|
483
|
+
res = self.ocr_model.run(rgb_crop)
|
484
|
+
if isinstance(res, list):
|
485
|
+
res = res[0] if res else ""
|
486
|
+
cleaned = self._clean_text(str(res))
|
487
|
+
return cleaned if len(cleaned) >= self._min_plate_len else ""
|
488
|
+
except Exception as exc:
|
489
|
+
self.logger.warning(f"OCR failed: {exc}")
|
490
|
+
return ""
|
491
|
+
|
453
492
|
def _get_frame_detections(self, data: Any, frame_key: str) -> List[Dict[str, Any]]:
|
454
493
|
"""Extract detections for a specific frame from data."""
|
455
494
|
if isinstance(data, dict):
|
@@ -488,45 +527,42 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
488
527
|
return detections
|
489
528
|
|
490
529
|
def _count_categories(self, detections: List[Dict], config: LicensePlateMonitorConfig) -> Dict[str, Any]:
|
491
|
-
"""Count
|
492
|
-
|
493
|
-
|
494
|
-
valid_detections = []
|
530
|
+
"""Count unique licence-plate texts per frame and attach detections."""
|
531
|
+
unique_texts: set = set()
|
532
|
+
valid_detections: List[Dict[str, Any]] = []
|
495
533
|
|
534
|
+
print("---------SUMMARY COUNT CATEGORIES",detections)
|
496
535
|
for det in detections:
|
497
536
|
if not all(k in det for k in ['category', 'confidence', 'bounding_box']):
|
498
|
-
self.logger.warning(f"Skipping invalid detection: {det}")
|
499
537
|
continue
|
500
538
|
|
501
|
-
cat = det.get('category', '
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
if unique_key is None:
|
508
|
-
continue # Cannot determine uniqueness
|
539
|
+
cat = det.get('category', 'license_plate')
|
540
|
+
plate_text_raw = det.get('plate_text', '')
|
541
|
+
print("---------SUMMARY COUNT CATEGORIES PLATE TEXT RAW",plate_text_raw)
|
542
|
+
print("---------SUMMARY COUNT CATEGORIES PLATE TEXT RAW",det)
|
543
|
+
cleaned_text = self._clean_text(plate_text_raw)
|
509
544
|
|
510
|
-
#
|
511
|
-
|
512
|
-
|
513
|
-
# Only count once per unique key within the current frame
|
514
|
-
if unique_key not in unique_keys_per_cat[cat]:
|
515
|
-
unique_keys_per_cat[cat].add(unique_key)
|
516
|
-
counts[cat] = counts.get(cat, 0) + 1
|
545
|
+
# Consider as unique only if meets criteria
|
546
|
+
if cleaned_text and len(cleaned_text) >= self._min_plate_len:
|
547
|
+
unique_texts.add(cleaned_text)
|
517
548
|
|
518
549
|
valid_detections.append({
|
519
550
|
"bounding_box": det.get("bounding_box"),
|
520
551
|
"category": cat,
|
521
552
|
"confidence": det.get("confidence"),
|
522
|
-
"track_id": track_id,
|
553
|
+
"track_id": det.get('track_id'),
|
523
554
|
"frame_id": det.get("frame_id"),
|
524
555
|
"masks": det.get("masks", []),
|
525
|
-
"plate_text":
|
556
|
+
"plate_text": plate_text_raw
|
526
557
|
})
|
527
|
-
|
558
|
+
|
559
|
+
counts = {"License_Plate": len(unique_texts)} if unique_texts else {}
|
560
|
+
|
561
|
+
print("---------SUMMARY COUNT CATEGORIES VALID DETECTIONS",valid_detections)
|
562
|
+
print(len(unique_texts),'per_cat_count',counts)
|
563
|
+
|
528
564
|
return {
|
529
|
-
"total_count":
|
565
|
+
"total_count": len(unique_texts),
|
530
566
|
"per_category_count": counts,
|
531
567
|
"detections": valid_detections
|
532
568
|
}
|
@@ -547,21 +583,28 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
547
583
|
camera_info = self.get_camera_info_from_stream(stream_info)
|
548
584
|
|
549
585
|
human_text_lines = []
|
586
|
+
print("counting_summary", counting_summary)
|
550
587
|
human_text_lines.append(f"CURRENT FRAME @ {current_timestamp}:")
|
551
588
|
if total_detections > 0:
|
552
589
|
category_counts = [f"{count} {cat}" for cat, count in per_category_count.items()]
|
553
590
|
detection_text = category_counts[0] + " detected" if len(category_counts) == 1 else f"{', '.join(category_counts[:-1])}, and {category_counts[-1]} detected"
|
554
591
|
human_text_lines.append(f"\t- {detection_text}")
|
555
592
|
# Deduplicate plate texts for the current frame while preserving order
|
556
|
-
|
557
|
-
|
593
|
+
seen_cleaned = set()
|
594
|
+
display_texts = []
|
558
595
|
for det in counting_summary.get("detections", []):
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
596
|
+
raw = det.get("plate_text", "")
|
597
|
+
cleaned = self._clean_text(raw)
|
598
|
+
if cleaned and cleaned not in seen_cleaned:
|
599
|
+
seen_cleaned.add(cleaned)
|
600
|
+
# Display the longest raw variant seen in this frame for that cleaned text
|
601
|
+
longest_variant = max(
|
602
|
+
[d.get("plate_text", "") for d in counting_summary.get("detections", []) if self._clean_text(d.get("plate_text", "")) == cleaned],
|
603
|
+
key=len,
|
604
|
+
)
|
605
|
+
display_texts.append(longest_variant)
|
606
|
+
if display_texts:
|
607
|
+
human_text_lines.append(f"\t- License Plates: {', '.join(display_texts)}")
|
565
608
|
else:
|
566
609
|
human_text_lines.append(f"\t- No detections")
|
567
610
|
|
@@ -569,10 +612,9 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
569
612
|
human_text_lines.append(f"TOTAL SINCE {start_timestamp}:")
|
570
613
|
human_text_lines.append(f"\t- Total Detected: {cumulative_total}")
|
571
614
|
|
572
|
-
if self.
|
615
|
+
if self._unique_plate_texts:
|
573
616
|
human_text_lines.append("\t- Unique License Plates:")
|
574
|
-
|
575
|
-
for text in sorted(set(self._tracked_plate_texts.values())):
|
617
|
+
for text in sorted(self._unique_plate_texts.values()):
|
576
618
|
human_text_lines.append(f"\t\t- {text}")
|
577
619
|
|
578
620
|
current_counts = [{"category": cat, "count": count} for cat, count in per_category_count.items() if count > 0 or total_detections > 0]
|
@@ -585,7 +627,7 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
585
627
|
category = detection.get("category", "License_Plate")
|
586
628
|
plate_text = detection.get("plate_text", "")
|
587
629
|
segmentation = detection.get("masks", detection.get("segmentation", detection.get("mask", [])))
|
588
|
-
detection_obj = self.create_detection_object(category, bbox, segmentation=
|
630
|
+
detection_obj = self.create_detection_object(category, bbox, segmentation=None, plate_text=plate_text)
|
589
631
|
detections.append(detection_obj)
|
590
632
|
|
591
633
|
alert_settings = []
|
@@ -798,24 +840,37 @@ class LicensePlateMonitorUseCase(BaseProcessor):
|
|
798
840
|
text = det.get('plate_text')
|
799
841
|
track_id = det.get('track_id')
|
800
842
|
if text and track_id is not None:
|
801
|
-
#
|
802
|
-
|
803
|
-
|
804
|
-
continue
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
#
|
812
|
-
self.
|
813
|
-
|
843
|
+
# Clean text again to guarantee consistency
|
844
|
+
text = self._clean_text(text)
|
845
|
+
if len(text) < self._min_plate_len:
|
846
|
+
continue # Too short to be a valid plate
|
847
|
+
|
848
|
+
# ----------------------------------------------------------
|
849
|
+
# Update consecutive frame appearance counter
|
850
|
+
# ----------------------------------------------------------
|
851
|
+
self._text_history[text] = self._text_history.get(text, 0) + 1
|
852
|
+
|
853
|
+
# Accept plate as stable only after N consecutive frames
|
854
|
+
if self._text_history[text] >= self._stable_frames_required:
|
855
|
+
# Track longest string variant per track_id
|
856
|
+
current_text = self._tracked_plate_texts.get(track_id, '')
|
857
|
+
if len(text) > len(current_text):
|
858
|
+
self._tracked_plate_texts[track_id] = text
|
859
|
+
# Maintain global unique mapping (cleaned -> original longest)
|
860
|
+
longest_variant = self._unique_plate_texts.get(text, '')
|
861
|
+
if len(text) > len(longest_variant):
|
862
|
+
self._unique_plate_texts[text] = text
|
863
|
+
self.logger.debug(f"Stable plate confirmed: {text} (track_id={track_id})")
|
864
|
+
|
865
|
+
# Reset counters for texts not seen in this frame
|
866
|
+
current_frame_texts = {self._clean_text(det.get('plate_text', '')) for det in detections if det.get('plate_text')}
|
867
|
+
for t in list(self._text_history.keys()):
|
868
|
+
if t not in current_frame_texts:
|
869
|
+
self._text_history[t] = 0
|
814
870
|
|
815
871
|
def get_total_counts(self):
|
816
872
|
"""Return total unique license plate texts encountered so far."""
|
817
|
-
|
818
|
-
return {'License_Plate': len(set(self._tracked_plate_texts.values()))}
|
873
|
+
return {'License_Plate': len(self._unique_plate_texts)}
|
819
874
|
|
820
875
|
def _get_track_ids_info(self, detections: List[Dict]) -> Dict[str, Any]:
|
821
876
|
"""Get detailed information about track IDs."""
|
@@ -91,7 +91,7 @@ matrice/data_processing/data_formats/video_mot_tracking.py,sha256=WlTikrOyVU6O_n
|
|
91
91
|
matrice/data_processing/data_formats/video_mscoco_detection.py,sha256=Z4e0GXcNrj-awwM-rIOlNFJqrb0cZD3KeFrnkYJjT1A,17066
|
92
92
|
matrice/data_processing/data_formats/video_youtube_bb_tracking.py,sha256=6RbuBOW1kfw0E626jGEZ0i5P3upgx8D5EQ0hsNVc9vs,10353
|
93
93
|
matrice/data_processing/data_formats/yolo_detection.py,sha256=qUeZA7_8Of_QWGZlHh-mhRnBFtb5A_u89Oihx-Meg3c,10018
|
94
|
-
matrice/deploy/__init__.py,sha256=
|
94
|
+
matrice/deploy/__init__.py,sha256=eKCxxed5ve_qDSDNmcBcaao7msj9rub0iS3EFstgE1I,1238
|
95
95
|
matrice/deploy/aggregator/__init__.py,sha256=HFz-ufUMeSpSyRINcrx6NdmrcuVZtPfyIXxYu5UNLTc,508
|
96
96
|
matrice/deploy/aggregator/aggregator.py,sha256=J1pE_RCWvxfwTwP2S2qrSX02bdT40Arhgww7OrmSbHo,11721
|
97
97
|
matrice/deploy/aggregator/analytics.py,sha256=F0vAT7aUkK0Bb7w_P_2mT0k4R8ARWNnwCJqJ97KMAts,18312
|
@@ -210,7 +210,7 @@ matrice/deploy/utils/post_processing/usecases/leaf.py,sha256=cwgB1ZNxkQFtkk-thSJ
|
|
210
210
|
matrice/deploy/utils/post_processing/usecases/leaf_disease.py,sha256=bkiLccTdf4KUq3he4eCpBlKXb5exr-WBhQ_oWQ7os68,36225
|
211
211
|
matrice/deploy/utils/post_processing/usecases/leak_detection.py,sha256=oOCLLVMuXVeXPHyN8FUrD3U9JYJJwIz-5fcEMgvLdls,40531
|
212
212
|
matrice/deploy/utils/post_processing/usecases/license_plate_detection.py,sha256=WmVmtp-GLUSNtBxjZHUtUk_M9lPp_8gA0rdzFXVL1SY,44961
|
213
|
-
matrice/deploy/utils/post_processing/usecases/license_plate_monitoring.py,sha256=
|
213
|
+
matrice/deploy/utils/post_processing/usecases/license_plate_monitoring.py,sha256=Ir0nEFAPxf8SMztfYxAMFekLTrjZ3WhF9tVQsl2X1UA,55556
|
214
214
|
matrice/deploy/utils/post_processing/usecases/litter_monitoring.py,sha256=XaHAUGRBDJg_iVbu8hRMjTR-5TqrLj6ZNCRkInbzZTY,33255
|
215
215
|
matrice/deploy/utils/post_processing/usecases/mask_detection.py,sha256=MNpCcuefOdW7C8g_x_mNuWYA4mbyg8UNwomwBPoKtr0,39684
|
216
216
|
matrice/deploy/utils/post_processing/usecases/parking.py,sha256=lqTGqcjUZZPFw3tu11Ha8BSsZ311K5--wEZnlVsXakU,34534
|
@@ -261,8 +261,8 @@ matrice/deployment/camera_manager.py,sha256=e1Lc81RJP5wUWRdTgHO6tMWF9BkBdHOSVyx3
|
|
261
261
|
matrice/deployment/deployment.py,sha256=HFt151eWq6iqIAMsQvurpV2WNxW6Cx_gIUVfnVy5SWE,48093
|
262
262
|
matrice/deployment/inference_pipeline.py,sha256=6b4Mm3-qt-Zy0BeiJfFQdImOn3FzdNCY-7ET7Rp8PMk,37911
|
263
263
|
matrice/deployment/streaming_gateway_manager.py,sha256=ifYGl3g25wyU39HwhPQyI2OgF3M6oIqKMWt8RXtMxY8,21401
|
264
|
-
matrice-1.0.
|
265
|
-
matrice-1.0.
|
266
|
-
matrice-1.0.
|
267
|
-
matrice-1.0.
|
268
|
-
matrice-1.0.
|
264
|
+
matrice-1.0.99398.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
|
265
|
+
matrice-1.0.99398.dist-info/METADATA,sha256=b3J2CplYOqjkR3waKBvff83-SO2QiPHMlRyn45PqZNI,14624
|
266
|
+
matrice-1.0.99398.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
267
|
+
matrice-1.0.99398.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
|
268
|
+
matrice-1.0.99398.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|