matrice 1.0.99140__py3-none-any.whl → 1.0.99141__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.
@@ -22,7 +22,7 @@ from ..core.config import BaseConfig, AlertConfig, ZoneConfig
22
22
 
23
23
  @dataclass
24
24
  class ConcreteCrackConfig(BaseConfig):
25
- """Configuration for concrete crack detection use case in concrete crack monitoring."""
25
+ """Configuration for Concrete Crack detection use case."""
26
26
  # Smoothing configuration
27
27
  enable_smoothing: bool = True
28
28
  smoothing_algorithm: str = "observability" # "window" or "observability"
@@ -31,14 +31,14 @@ class ConcreteCrackConfig(BaseConfig):
31
31
  smoothing_confidence_range_factor: float = 0.5
32
32
 
33
33
  #confidence thresholds
34
- confidence_threshold: float = 0.2
34
+ confidence_threshold: float = 0.6
35
35
 
36
36
  usecase_categories: List[str] = field(
37
- default_factory=lambda: ['Cracks']
37
+ default_factory=lambda: ["Cracks"]
38
38
  )
39
39
 
40
40
  target_categories: List[str] = field(
41
- default_factory=lambda: ['Cracks']
41
+ default_factory=lambda: ["Cracks"]
42
42
  )
43
43
 
44
44
  alert_config: Optional[AlertConfig] = None
@@ -55,23 +55,23 @@ class ConcreteCrackUseCase(BaseProcessor):
55
55
  CATEGORY_DISPLAY = {
56
56
  "Cracks": "Cracks",
57
57
  }
58
-
58
+
59
+
59
60
  def __init__(self):
60
61
  super().__init__("concrete_crack_detection")
61
62
  self.category = "general"
62
63
 
63
64
  self.CASE_TYPE: Optional[str] = 'concrete_crack_detection'
64
- self.CASE_VERSION: Optional[str] = '1.3'
65
-
65
+ self.CASE_VERSION: Optional[str] = '1.2'
66
66
  # List of categories to track
67
- self.target_categories = ['Cracks']
67
+ self.target_categories = ["Cracks"]
68
+
68
69
 
69
70
  # Initialize smoothing tracker
70
71
  self.smoothing_tracker = None
71
72
 
72
73
  # Initialize advanced tracker (will be created on first use)
73
74
  self.tracker = None
74
-
75
75
  # Initialize tracking state variables
76
76
  self._total_frame_counter = 0
77
77
  self._global_frame_offset = 0
@@ -88,6 +88,7 @@ class ConcreteCrackUseCase(BaseProcessor):
88
88
  self._ascending_alert_list: List[int] = []
89
89
  self.current_incident_end_timestamp: str = "N/A"
90
90
 
91
+
91
92
  def process(self, data: Any, config: ConfigProtocol, context: Optional[ProcessingContext] = None,
92
93
  stream_info: Optional[Dict[str, Any]] = None) -> ProcessingResult:
93
94
  """
@@ -107,8 +108,6 @@ class ConcreteCrackUseCase(BaseProcessor):
107
108
  input_format = match_results_structure(data)
108
109
  context.input_format = input_format
109
110
  context.confidence_threshold = config.confidence_threshold
110
-
111
-
112
111
 
113
112
  if config.confidence_threshold is not None:
114
113
  processed_data = filter_by_confidence(data, config.confidence_threshold)
@@ -117,19 +116,15 @@ class ConcreteCrackUseCase(BaseProcessor):
117
116
  processed_data = data
118
117
 
119
118
  self.logger.debug(f"Did not apply confidence filtering with threshold since nothing was provided")
120
- print("---------------------processed_1-----------------------------------")
121
- print(processed_data)
119
+
122
120
  # Step 2: Apply category mapping if provided
123
121
  if config.index_to_category:
124
122
  processed_data = apply_category_mapping(processed_data, config.index_to_category)
125
123
  self.logger.debug("Applied category mapping")
126
- print("---------------------processed_2-----------------------------------")
127
- print(processed_data)
124
+
128
125
  if config.target_categories:
129
126
  processed_data = [d for d in processed_data if d.get('category') in self.target_categories]
130
127
  self.logger.debug(f"Applied category filtering")
131
- print("---------------------processed_3-----------------------------------")
132
- print(processed_data)
133
128
 
134
129
  # Apply bbox smoothing if enabled
135
130
  if config.enable_smoothing:
@@ -143,11 +138,14 @@ class ConcreteCrackUseCase(BaseProcessor):
143
138
  enable_smoothing=True
144
139
  )
145
140
  self.smoothing_tracker = BBoxSmoothingTracker(smoothing_config)
146
- print("---------------------processed_4-----------------------------------")
147
141
  processed_data = bbox_smoothing(processed_data, self.smoothing_tracker.config, self.smoothing_tracker)
148
- print(processed_data)
142
+
149
143
  # Advanced tracking (BYTETracker-like)
150
144
  try:
145
+ from ..advanced_tracker import AdvancedTracker
146
+ from ..advanced_tracker.config import TrackerConfig
147
+
148
+ # Create tracker instance if it doesn't exist (preserves state across frames)
151
149
  if self.tracker is None:
152
150
  # Configure tracker thresholds based on the use-case confidence threshold so that
153
151
  # low-confidence detections (e.g. < 0.7) can still be initialised as tracks when
@@ -168,9 +166,10 @@ class ConcreteCrackUseCase(BaseProcessor):
168
166
  f"low={tracker_config.track_low_thresh}, "
169
167
  f"new={tracker_config.new_track_thresh}"
170
168
  )
169
+
170
+ # The tracker expects the data in the same format as input
171
+ # It will add track_id and frame_id to each detection
171
172
  processed_data = self.tracker.update(processed_data)
172
- print("---------------------processed_5-----------------------------------")
173
- print(processed_data)
174
173
 
175
174
  except Exception as e:
176
175
  # If advanced tracker fails, fallback to unsmoothed detections
@@ -198,16 +197,14 @@ class ConcreteCrackUseCase(BaseProcessor):
198
197
  # Add total unique counts after tracking using only local state
199
198
  total_counts = self.get_total_counts()
200
199
  counting_summary['total_counts'] = total_counts
201
- print("---------------------counting_summ-----------------------------------")
202
- print(counting_summary)
200
+
203
201
  alerts = self._check_alerts(counting_summary, frame_number, config)
204
202
  predictions = self._extract_predictions(processed_data)
205
203
 
206
204
  # Step: Generate structured incidents, tracking stats and business analytics with frame-based keys
207
205
  incidents_list = self._generate_incidents(counting_summary, alerts, config, frame_number, stream_info)
208
206
  tracking_stats_list = self._generate_tracking_stats(counting_summary, alerts, config, frame_number, stream_info)
209
- # business_analytics_list = self._generate_business_analytics(counting_summary, alerts, config, frame_number, stream_info, is_empty=True)
210
- business_analytics_list = []
207
+ business_analytics_list = self._generate_business_analytics(counting_summary, alerts, config, stream_info, is_empty=True)
211
208
  summary_list = self._generate_summary(counting_summary, incidents_list, tracking_stats_list, business_analytics_list, alerts)
212
209
 
213
210
  # Extract frame-based dictionaries from the lists
@@ -222,8 +219,8 @@ class ConcreteCrackUseCase(BaseProcessor):
222
219
  "alerts": alerts,
223
220
  "human_text": summary}
224
221
  }
225
-
226
-
222
+
223
+
227
224
  context.mark_completed()
228
225
 
229
226
  # Build result object following the new pattern
@@ -285,8 +282,8 @@ class ConcreteCrackUseCase(BaseProcessor):
285
282
  "threshold_level": threshold,
286
283
  "ascending": get_trend(self._ascending_alert_list, lookback=900, threshold=0.8),
287
284
  "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']) if hasattr(config.alert_config, 'alert_type') else ['Default'],
288
- getattr(config.alert_config, 'alert_value', ['JSON']) if hasattr(config.alert_config, 'alert_value') else ['JSON'])
289
- }
285
+ getattr(config.alert_config, 'alert_value', ['JSON']) if hasattr(config.alert_config, 'alert_value') else ['JSON'])
286
+ }
290
287
  })
291
288
  elif category in summary.get("per_category_count", {}):
292
289
  count = summary.get("per_category_count", {})[category]
@@ -298,15 +295,15 @@ class ConcreteCrackUseCase(BaseProcessor):
298
295
  "threshold_level": threshold,
299
296
  "ascending": get_trend(self._ascending_alert_list, lookback=900, threshold=0.8),
300
297
  "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']) if hasattr(config.alert_config, 'alert_type') else ['Default'],
301
- getattr(config.alert_config, 'alert_value', ['JSON']) if hasattr(config.alert_config, 'alert_value') else ['JSON'])
302
- }
298
+ getattr(config.alert_config, 'alert_value', ['JSON']) if hasattr(config.alert_config, 'alert_value') else ['JSON'])
299
+ }
303
300
  })
304
301
  else:
305
302
  pass
306
303
  return alerts
307
304
 
308
305
  def _generate_incidents(self, counting_summary: Dict, alerts: List, config: ConcreteCrackConfig,
309
- frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[
306
+ frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[
310
307
  Dict]:
311
308
  """Generate structured incidents for the output format with frame-based keys."""
312
309
 
@@ -364,12 +361,12 @@ class ConcreteCrackUseCase(BaseProcessor):
364
361
  intensity = min(10.0, total_detections / 3.0)
365
362
  self._ascending_alert_list.append(0)
366
363
 
367
- # Generate human text in new format
364
+ # Generate human text in new format
368
365
  human_text_lines = [f"INCIDENTS DETECTED @ {current_timestamp}:"]
369
366
  human_text_lines.append(f"\tSeverity Level: {(self.CASE_TYPE,level)}")
370
367
  human_text = "\n".join(human_text_lines)
371
368
 
372
- alert_settings = []
369
+ alert_settings=[]
373
370
  if config.alert_config and hasattr(config.alert_config, 'alert_type'):
374
371
  alert_settings.append({
375
372
  "alert_type": getattr(config.alert_config, 'alert_type', ['Default']) if hasattr(config.alert_config, 'alert_type') else ['Default'],
@@ -382,17 +379,16 @@ class ConcreteCrackUseCase(BaseProcessor):
382
379
  })
383
380
 
384
381
  event= self.create_incident(incident_id=self.CASE_TYPE+'_'+str(frame_number), incident_type=self.CASE_TYPE,
385
- severity_level=level, human_text=human_text, camera_info=camera_info, alerts=alerts, alert_settings=alert_settings,
386
- start_time=start_timestamp, end_time=self.current_incident_end_timestamp,
387
- level_settings= {"low": 1, "medium": 3, "significant":4, "critical": 7})
382
+ severity_level=level, human_text=human_text, camera_info=camera_info, alerts=alerts, alert_settings=alert_settings,
383
+ start_time=start_timestamp, end_time=self.current_incident_end_timestamp,
384
+ level_settings= {"low": 1, "medium": 3, "significant":4, "critical": 7})
388
385
  incidents.append(event)
389
386
 
390
387
  else:
391
388
  self._ascending_alert_list.append(0)
392
389
  incidents.append({})
393
-
390
+
394
391
  return incidents
395
-
396
392
  def _generate_tracking_stats(
397
393
  self,
398
394
  counting_summary: Dict,
@@ -430,8 +426,7 @@ class ConcreteCrackUseCase(BaseProcessor):
430
426
  "category": cat,
431
427
  "count": count
432
428
  })
433
- print("-----------------------------total_counts---------------------------------------")
434
- print(total_counts)
429
+
435
430
  # Build current_counts array in expected format
436
431
  current_counts = []
437
432
  for cat, count in per_category_count.items():
@@ -440,8 +435,7 @@ class ConcreteCrackUseCase(BaseProcessor):
440
435
  "category": cat,
441
436
  "count": count
442
437
  })
443
- print("----------------------------------current_counts---------------------------------------")
444
- print(current_counts)
438
+
445
439
  # Prepare detections without confidence scores (as per eg.json)
446
440
  detections = []
447
441
  for detection in counting_summary.get("detections", []):
@@ -493,9 +487,7 @@ class ConcreteCrackUseCase(BaseProcessor):
493
487
  human_text_lines.append("Alerts: None")
494
488
 
495
489
  human_text = "\n".join(human_text_lines)
496
- print("-------------------------------human_text-----------------------------------------------------")
497
- print(human_text)
498
- reset_settings = [
490
+ reset_settings=[
499
491
  {
500
492
  "interval_type": "daily",
501
493
  "reset_time": {
@@ -506,14 +498,14 @@ class ConcreteCrackUseCase(BaseProcessor):
506
498
  ]
507
499
 
508
500
  tracking_stat=self.create_tracking_stats(total_counts=total_counts, current_counts=current_counts,
509
- detections=detections, human_text=human_text, camera_info=camera_info, alerts=alerts, alert_settings=alert_settings,
510
- reset_settings=reset_settings, start_time=high_precision_start_timestamp ,
511
- reset_time=high_precision_reset_timestamp)
501
+ detections=detections, human_text=human_text, camera_info=camera_info, alerts=alerts, alert_settings=alert_settings,
502
+ reset_settings=reset_settings, start_time=high_precision_start_timestamp ,
503
+ reset_time=high_precision_reset_timestamp)
512
504
 
513
505
  tracking_stats.append(tracking_stat)
514
506
  return tracking_stats
515
507
 
516
- def _generate_business_analytics(self, counting_summary: Dict, zone_analysis: Dict, config: ConcreteCrackConfig, stream_info: Optional[Dict[str, Any]] = None, is_empty=False) -> List[Dict]:
508
+ def _generate_business_analytics(self, counting_summary: Dict, alerts:Any, config: ConcreteCrackConfig, stream_info: Optional[Dict[str, Any]] = None, is_empty=False) -> List[Dict]:
517
509
  """Generate standardized business analytics for the agg_summary structure."""
518
510
  if is_empty:
519
511
  return []
@@ -596,6 +588,12 @@ class ConcreteCrackUseCase(BaseProcessor):
596
588
  Return total unique track_id count for each category.
597
589
  """
598
590
  return {cat: len(ids) for cat, ids in getattr(self, '_per_category_total_track_ids', {}).items()}
591
+
592
+
593
+ def _format_timestamp_for_stream(self, timestamp: float) -> str:
594
+ """Format timestamp for streams (YYYY:MM:DD HH:MM:SS format)."""
595
+ dt = datetime.fromtimestamp(timestamp, tz=timezone.utc)
596
+ return dt.strftime('%Y:%m:%d %H:%M:%S')
599
597
 
600
598
  def _format_timestamp_for_video(self, timestamp: float) -> str:
601
599
  """Format timestamp for video chunks (HH:MM:SS.ms format)."""
@@ -604,11 +602,6 @@ class ConcreteCrackUseCase(BaseProcessor):
604
602
  seconds = round(float(timestamp % 60),2)
605
603
  return f"{hours:02d}:{minutes:02d}:{seconds:.1f}"
606
604
 
607
- def _format_timestamp_for_stream(self, timestamp: float) -> str:
608
- """Format timestamp for streams (YYYY:MM:DD HH:MM:SS format)."""
609
- dt = datetime.fromtimestamp(timestamp, tz=timezone.utc)
610
- return dt.strftime('%Y:%m:%d %H:%M:%S')
611
-
612
605
  def _get_current_timestamp_str(self, stream_info: Optional[Dict[str, Any]], precision=False, frame_id: Optional[str]=None) -> str:
613
606
  """Get formatted current timestamp based on stream type."""
614
607
  if not stream_info:
@@ -684,6 +677,7 @@ class ConcreteCrackUseCase(BaseProcessor):
684
677
  dt = dt.replace(minute=0, second=0, microsecond=0)
685
678
  return dt.strftime('%Y:%m:%d %H:%M:%S')
686
679
 
680
+
687
681
  def _count_categories(self, detections: list, config: ConcreteCrackConfig) -> dict:
688
682
  """
689
683
  Count the number of detections per category and return a summary dict.
@@ -695,10 +689,6 @@ class ConcreteCrackUseCase(BaseProcessor):
695
689
  cat = det.get('category', 'unknown')
696
690
  counts[cat] = counts.get(cat, 0) + 1
697
691
  # Each detection dict will now include 'track_id' (and possibly 'frame_id')
698
- print("---------------------------------COUNTS-------------------------------------")
699
- print(counts)
700
- print("---------------------------------Detections-------------------------------------")
701
- print(detections)
702
692
  return {
703
693
  "total_count": sum(counts.values()),
704
694
  "per_category_count": counts,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice
3
- Version: 1.0.99140
3
+ Version: 1.0.99141
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
@@ -166,7 +166,7 @@ matrice/deploy/utils/post_processing/usecases/chicken_pose_detection.py,sha256=-
166
166
  matrice/deploy/utils/post_processing/usecases/child_monitoring.py,sha256=z3oymoqq4hDGwA8MkdEONZW_Vx5CAZmvzZaNLsqmCfw,39380
167
167
  matrice/deploy/utils/post_processing/usecases/color_detection.py,sha256=Z8-akjy8a7f8YyiOzXu_Zi1Km30v-TRrymDqQOPpJ_8,43277
168
168
  matrice/deploy/utils/post_processing/usecases/color_map_utils.py,sha256=SP-AEVcjLmL8rxblu-ixqUJC2fqlcr7ab4hWo4Fcr_k,2677
169
- matrice/deploy/utils/post_processing/usecases/concrete_crack_detection.py,sha256=6CnS8Aag-ZJoFrJxhOFMb3Xt2G4P5wfFl9_TeW0E0jA,41307
169
+ matrice/deploy/utils/post_processing/usecases/concrete_crack_detection.py,sha256=pxhOH_hG4hq9yytNepbGMdk2W_lTG8D1_2RAagaPBkg,40252
170
170
  matrice/deploy/utils/post_processing/usecases/crop_weed_detection.py,sha256=i7BWhC-D7liOg9fzFHFg_upd1fdvXlVHYzDRyHL-AdM,40322
171
171
  matrice/deploy/utils/post_processing/usecases/customer_service.py,sha256=UWS83qxguyAyhh8a0JF5QH9DtKxO8I-gI2BPOjLPxBw,44642
172
172
  matrice/deploy/utils/post_processing/usecases/defect_detection_products.py,sha256=flvTWv6vxa3q4zXD8_e8TW0pqNE5z3LIuvU9ceVKuXg,34481
@@ -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.99140.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
229
- matrice-1.0.99140.dist-info/METADATA,sha256=J55ccW-zzCwuiba6hXViCQw90Kmh7fRftaQ_j1S4QoM,14624
230
- matrice-1.0.99140.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
231
- matrice-1.0.99140.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
232
- matrice-1.0.99140.dist-info/RECORD,,
228
+ matrice-1.0.99141.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
229
+ matrice-1.0.99141.dist-info/METADATA,sha256=7aK3PJ9ODjlD7ASl79Bf8RxjOtZd474MsY2WvUoBAlA,14624
230
+ matrice-1.0.99141.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
231
+ matrice-1.0.99141.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
232
+ matrice-1.0.99141.dist-info/RECORD,,