matrice 1.0.99142__py3-none-any.whl → 1.0.99143__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.
@@ -1,10 +1,3 @@
1
- """
2
- Road Lane Detection Use Case for Post-Processing
3
-
4
- This module provides road lane detection functionality with lane type classification,
5
- zone analysis, and alert generation.
6
- """
7
-
8
1
  from typing import Any, Dict, List, Optional
9
2
  from dataclasses import asdict, dataclass, field
10
3
  import time
@@ -25,9 +18,10 @@ from ..utils import (
25
18
  )
26
19
  from ..core.config import BaseConfig, AlertConfig, ZoneConfig
27
20
 
21
+
28
22
  @dataclass
29
23
  class LaneDetectionConfig(BaseConfig):
30
- """Configuration for road lane detection use case."""
24
+ """Configuration for lane detection use case in road monitoring."""
31
25
  enable_smoothing: bool = True
32
26
  smoothing_algorithm: str = "observability"
33
27
  smoothing_window_size: int = 20
@@ -52,6 +46,7 @@ class LaneDetectionConfig(BaseConfig):
52
46
  }
53
47
  )
54
48
 
49
+
55
50
  class LaneDetectionUseCase(BaseProcessor):
56
51
  CATEGORY_DISPLAY = {
57
52
  "Divider-Line": "Divider Line",
@@ -97,7 +92,7 @@ class LaneDetectionUseCase(BaseProcessor):
97
92
  self.logger.debug(f"Applied confidence filtering with threshold {config.confidence_threshold}")
98
93
  else:
99
94
  processed_data = data
100
- self.logger.debug("No confidence filtering applied")
95
+ self.logger.debug("Did not apply confidence filtering since no threshold provided")
101
96
 
102
97
  if config.index_to_category:
103
98
  processed_data = apply_category_mapping(processed_data, config.index_to_category)
@@ -256,7 +251,6 @@ class LaneDetectionUseCase(BaseProcessor):
256
251
  level = "medium"
257
252
  self._ascending_alert_list.append(1)
258
253
  else:
259
- level = "low"
260
254
  self._ascending_alert_list.append(0)
261
255
  else:
262
256
  if total_detections > 30:
@@ -276,7 +270,7 @@ class LaneDetectionUseCase(BaseProcessor):
276
270
  intensity = min(10.0, total_detections / 3.0)
277
271
  self._ascending_alert_list.append(0)
278
272
 
279
- human_text_lines = [f"LANE INCIDENTS DETECTED @ {current_timestamp}:"]
273
+ human_text_lines = [f"INCIDENTS DETECTED @ {current_timestamp}:"]
280
274
  human_text_lines.append(f"\tSeverity Level: {(self.CASE_TYPE, level)}")
281
275
  human_text = "\n".join(human_text_lines)
282
276
 
@@ -307,7 +301,6 @@ class LaneDetectionUseCase(BaseProcessor):
307
301
  else:
308
302
  self._ascending_alert_list.append(0)
309
303
  incidents.append({})
310
-
311
304
  return incidents
312
305
 
313
306
  def _generate_tracking_stats(self, counting_summary: Dict, alerts: List, config: LaneDetectionConfig,
@@ -361,7 +354,11 @@ class LaneDetectionUseCase(BaseProcessor):
361
354
  for cat, count in total_counts_dict.items():
362
355
  if count > 0:
363
356
  human_text_lines.append(f"\t{cat}: {count}")
364
- human_text_lines.append(f"Alerts: {alerts[0].get('settings', {})} sent @ {current_timestamp}" if alerts else "Alerts: None")
357
+ if alerts:
358
+ for alert in alerts:
359
+ human_text_lines.append(f"Alerts: {alert.get('settings', {})} sent @ {current_timestamp}")
360
+ else:
361
+ human_text_lines.append("Alerts: None")
365
362
  human_text = "\n".join(human_text_lines)
366
363
 
367
364
  reset_settings = [{"interval_type": "daily", "reset_time": {"value": 9, "time_unit": "hour"}}]
@@ -389,18 +386,22 @@ class LaneDetectionUseCase(BaseProcessor):
389
386
  lines = {}
390
387
  lines["Application Name"] = self.CASE_TYPE
391
388
  lines["Application Version"] = self.CASE_VERSION
392
- if incidents:
389
+ if len(incidents) > 0:
393
390
  lines["Incidents:"] = f"\n\t{incidents[0].get('human_text', 'No incidents detected')}\n"
394
- if tracking_stats:
391
+ if len(tracking_stats) > 0:
395
392
  lines["Tracking Statistics:"] = f"\t{tracking_stats[0].get('human_text', 'No tracking statistics detected')}\n"
396
- if business_analytics:
393
+ if len(business_analytics) > 0:
397
394
  lines["Business Analytics:"] = f"\t{business_analytics[0].get('human_text', 'No business analytics detected')}\n"
398
- if not incidents and not tracking_stats and not business_analytics:
395
+ if len(incidents) == 0 and len(tracking_stats) == 0 and len(business_analytics) == 0:
399
396
  lines["Summary"] = "No Summary Data"
400
397
  return [lines]
401
398
 
402
399
  def _get_track_ids_info(self, detections: list) -> Dict[str, Any]:
403
- frame_track_ids = {det.get('track_id') for det in detections if det.get('track_id') is not None}
400
+ frame_track_ids = set()
401
+ for det in detections:
402
+ tid = det.get('track_id')
403
+ if tid is not None:
404
+ frame_track_ids.add(tid)
404
405
  total_track_ids = set()
405
406
  for s in getattr(self, '_per_category_total_track_ids', {}).values():
406
407
  total_track_ids.update(s)
@@ -444,49 +445,60 @@ class LaneDetectionUseCase(BaseProcessor):
444
445
 
445
446
  def _get_current_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False, frame_id: Optional[str] = None) -> str:
446
447
  if not stream_info:
447
- return "00:00:00.00" if precision else "00:00:00"
448
+ return "00:00:00.00"
448
449
  if precision:
449
450
  if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
450
- start_time = (int(frame_id) if frame_id else stream_info.get("input_settings", {}).get("start_frame", 30)) / stream_info.get("input_settings", {}).get("original_fps", 30)
451
+ if frame_id:
452
+ start_time = int(frame_id) / stream_info.get("input_settings", {}).get("original_fps", 30)
453
+ else:
454
+ start_time = stream_info.get("input_settings", {}).get("start_frame", 30) / stream_info.get("input_settings", {}).get("original_fps", 30)
451
455
  return self._format_timestamp_for_video(start_time)
452
- return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
456
+ else:
457
+ return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
453
458
  if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
454
- start_time = (int(frame_id) if frame_id else stream_info.get("input_settings", {}).get("start_frame", 30)) / stream_info.get("input_settings", {}).get("original_fps", 30)
459
+ if frame_id:
460
+ start_time = int(frame_id) / stream_info.get("input_settings", {}).get("original_fps", 30)
461
+ else:
462
+ start_time = stream_info.get("input_settings", {}).get("start_frame", 30) / stream_info.get("input_settings", {}).get("original_fps", 30)
455
463
  return self._format_timestamp_for_video(start_time)
456
- stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
457
- if stream_time_str:
458
- try:
459
- timestamp_str = stream_time_str.replace(" UTC", "")
460
- dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
461
- timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
462
- return self._format_timestamp_for_stream(timestamp)
463
- except:
464
+ else:
465
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
466
+ if stream_time_str:
467
+ try:
468
+ timestamp_str = stream_time_str.replace(" UTC", "")
469
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
470
+ timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
471
+ return self._format_timestamp_for_stream(timestamp)
472
+ except:
473
+ return self._format_timestamp_for_stream(time.time())
474
+ else:
464
475
  return self._format_timestamp_for_stream(time.time())
465
- return self._format_timestamp_for_stream(time.time())
466
476
 
467
477
  def _get_start_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False) -> str:
468
478
  if not stream_info:
469
- return "00:00:00" if not precision else "00:00:00.00"
479
+ return "00:00:00"
470
480
  if precision:
471
481
  if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
472
- return "00:00:00.00"
473
- return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
482
+ return "00:00:00"
483
+ else:
484
+ return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
474
485
  if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
475
486
  return "00:00:00"
476
- if self._tracking_start_time is None:
477
- stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
478
- if stream_time_str:
479
- try:
480
- timestamp_str = stream_time_str.replace(" UTC", "")
481
- dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
482
- self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
483
- except:
487
+ else:
488
+ if self._tracking_start_time is None:
489
+ stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
490
+ if stream_time_str:
491
+ try:
492
+ timestamp_str = stream_time_str.replace(" UTC", "")
493
+ dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
494
+ self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
495
+ except:
496
+ self._tracking_start_time = time.time()
497
+ else:
484
498
  self._tracking_start_time = time.time()
485
- else:
486
- self._tracking_start_time = time.time()
487
- dt = datetime.fromtimestamp(self._tracking_start_time, tz=timezone.utc)
488
- dt = dt.replace(minute=0, second=0, microsecond=0)
489
- return dt.strftime('%Y:%m:%d %H:%M:%S')
499
+ dt = datetime.fromtimestamp(self._tracking_start_time, tz=timezone.utc)
500
+ dt = dt.replace(minute=0, second=0, microsecond=0)
501
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
490
502
 
491
503
  def _count_categories(self, detections: list, config: LaneDetectionConfig) -> dict:
492
504
  counts = {}
@@ -582,7 +594,7 @@ class LaneDetectionUseCase(BaseProcessor):
582
594
  self._canonical_tracks[canonical_id] = {
583
595
  "last_bbox": bbox,
584
596
  "last_update": now,
585
- "raw_ids": {raw_id}
597
+ "raw_ids": {raw_id},
586
598
  }
587
599
  return canonical_id
588
600
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice
3
- Version: 1.0.99142
3
+ Version: 1.0.99143
4
4
  Summary: SDK for connecting to matrice.ai services
5
5
  Home-page: https://github.com/matrice-ai/python-sdk
6
6
  Author: Matrice.ai
@@ -191,7 +191,7 @@ matrice/deploy/utils/post_processing/usecases/plaque_segmentation_img.py,sha256=
191
191
  matrice/deploy/utils/post_processing/usecases/pothole_segmentation.py,sha256=6Mv8SoEE5CGItY7S0g-SY5Lb3DV-WWVMlpEp04a86a8,43197
192
192
  matrice/deploy/utils/post_processing/usecases/ppe_compliance.py,sha256=G9P9j9E9nfNJInHJxmK1Lb4daFBlG5hq0aqotTLvFFE,30146
193
193
  matrice/deploy/utils/post_processing/usecases/price_tag_detection.py,sha256=Sn_Dvwf5f_dcfaiPIl-pqckgP8z96CeNIJ4hfeab3FM,39880
194
- matrice/deploy/utils/post_processing/usecases/road_lane_detection.py,sha256=NILx7xkx8qARJt0L63ualPm7a95qSZWfQCfvEVaMkps,29778
194
+ matrice/deploy/utils/post_processing/usecases/road_lane_detection.py,sha256=VTPGU1Z2dnOo5x_bwsLY5VczJc_tLApptahxBcEASyo,30186
195
195
  matrice/deploy/utils/post_processing/usecases/shelf_inventory_detection.py,sha256=1juloltHnCj3U499Aps0ggE0nEI37x3iKe4DgfP4RCw,29140
196
196
  matrice/deploy/utils/post_processing/usecases/shoplifting_detection.py,sha256=zqeV_ARV5gJqMY2sJGBjlU6UOb0SthGGbC8UNj_mycs,34701
197
197
  matrice/deploy/utils/post_processing/usecases/shopping_cart_analysis.py,sha256=9Ej2xiZM7yq5sOBcSXIllou_z0rSZDJ_QHyYz6HxZSY,43957
@@ -225,8 +225,8 @@ matrice/deployment/camera_manager.py,sha256=ReBZqm1CNXRImKcbcZ4uWAT3TUWkof1D28oB
225
225
  matrice/deployment/deployment.py,sha256=PLIUD-PxTaC2Zxb3Y12wUddsryV-OJetjCjLoSUh7S4,48103
226
226
  matrice/deployment/inference_pipeline.py,sha256=bXLgd29ViA7o0c7YWLFJl1otBUQfTPb61jS6VawQB0Y,37918
227
227
  matrice/deployment/streaming_gateway_manager.py,sha256=w5swGsuFVfZIdOm2ZuBHRHlRdYYJMLopLsf2gb91lQ8,20946
228
- matrice-1.0.99142.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
229
- matrice-1.0.99142.dist-info/METADATA,sha256=mwmWB2ZlF49tBndisppxH6Kg4lTStAjy9Ie8CCXIk2Y,14624
230
- matrice-1.0.99142.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
231
- matrice-1.0.99142.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
232
- matrice-1.0.99142.dist-info/RECORD,,
228
+ matrice-1.0.99143.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
229
+ matrice-1.0.99143.dist-info/METADATA,sha256=PIYKGvaWzfWG2FSrUkwNmHpR4gNBQtlUg13zcFGtgN0,14624
230
+ matrice-1.0.99143.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
231
+ matrice-1.0.99143.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
232
+ matrice-1.0.99143.dist-info/RECORD,,