matrice 1.0.99393__py3-none-any.whl → 1.0.99394__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,22 +1,24 @@
1
1
  from typing import Any, Dict, List, Optional, Tuple
2
+ from dataclasses import asdict
2
3
  import time
3
4
  from datetime import datetime, timezone
4
5
 
5
- from ..core.base import BaseProcessor, ProcessingContext, ProcessingResult, ConfigProtocol
6
+ from ..core.base import BaseProcessor, ProcessingContext, ProcessingResult, ConfigProtocol, ResultFormat
6
7
  from ..utils import (
7
8
  filter_by_confidence,
8
9
  filter_by_categories,
9
10
  apply_category_mapping,
10
11
  count_objects_by_category,
11
12
  count_objects_in_zones,
13
+ calculate_counting_summary,
12
14
  match_results_structure,
13
15
  bbox_smoothing,
14
16
  BBoxSmoothingConfig,
15
17
  BBoxSmoothingTracker
16
18
  )
17
- from ..utils.geometry_utils import point_in_polygon, get_bbox_bottom25_center
18
19
  from dataclasses import dataclass, field
19
20
  from ..core.config import BaseConfig, AlertConfig, ZoneConfig
21
+ from ..utils.geometry_utils import get_bbox_center, point_in_polygon, get_bbox_bottom25_center
20
22
 
21
23
  @dataclass
22
24
  class VehicleMonitoringConfig(BaseConfig):
@@ -30,24 +32,26 @@ class VehicleMonitoringConfig(BaseConfig):
30
32
  zone_config: Optional[ZoneConfig] = None
31
33
  usecase_categories: List[str] = field(
32
34
  default_factory=lambda: [
33
- "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat"
34
- ,"traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat"
35
- ,"dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella"
36
- ,"handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat"
37
- ,"baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup"
38
- ,"fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli"
39
- ,"carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed"
40
- ,"dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone"
41
- ,"microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors"
42
- ,"teddy bear", "hair drier", "toothbrush"
35
+ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat",
36
+ "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog",
37
+ "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
38
+ "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite",
39
+ "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle",
40
+ "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich",
41
+ "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
42
+ "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote",
43
+ "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book",
44
+ "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"
43
45
  ]
44
46
  )
45
47
  target_categories: List[str] = field(
46
- default_factory=lambda: ['car', 'bicycle', 'bus', 'motorcycle']
48
+ default_factory=lambda: [
49
+ 'car', 'bicycle', 'bus', 'truck', 'motorcycle']
47
50
  )
48
51
  alert_config: Optional[AlertConfig] = None
49
52
  index_to_category: Optional[Dict[int, str]] = field(
50
- default_factory=lambda:{0: "person", 1: "bicycle", 2: "car", 3: "motorcycle", 4: "airplane", 5: "bus",
53
+ default_factory=lambda: {
54
+ 0: "person", 1: "bicycle", 2: "car", 3: "motorcycle", 4: "airplane", 5: "bus",
51
55
  6: "train", 7: "truck", 8: "boat", 9: "traffic light", 10: "fire hydrant",
52
56
  11: "stop sign", 12: "parking meter", 13: "bench", 14: "bird", 15: "cat",
53
57
  16: "dog", 17: "horse", 18: "sheep", 19: "cow", 20: "elephant", 21: "bear",
@@ -62,7 +66,8 @@ class VehicleMonitoringConfig(BaseConfig):
62
66
  62: "tv", 63: "laptop", 64: "mouse", 65: "remote", 66: "keyboard",
63
67
  67: "cell phone", 68: "microwave", 69: "oven", 70: "toaster", 71: "sink",
64
68
  72: "refrigerator", 73: "book", 74: "clock", 75: "vase", 76: "scissors",
65
- 77: "teddy bear", 78: "hair drier", 79: "toothbrush"}
69
+ 77: "teddy bear", 78: "hair drier", 79: "toothbrush"
70
+ }
66
71
  )
67
72
 
68
73
  class VehicleMonitoringUseCase(BaseProcessor):
@@ -82,7 +87,7 @@ class VehicleMonitoringUseCase(BaseProcessor):
82
87
  self.category = "traffic"
83
88
  self.CASE_TYPE: Optional[str] = 'vehicle_monitoring'
84
89
  self.CASE_VERSION: Optional[str] = '1.0'
85
- self.target_categories = ['car', 'bicycle', 'bus', 'truck', 'motorbike']
90
+ self.target_categories = ['car', 'bicycle', 'bus', 'truck', 'motorcycle']
86
91
  self.smoothing_tracker = None
87
92
  self.tracker = None
88
93
  self._total_frame_counter = 0
@@ -95,11 +100,22 @@ class VehicleMonitoringUseCase(BaseProcessor):
95
100
  self._ascending_alert_list: List[int] = []
96
101
  self.current_incident_end_timestamp: str = "N/A"
97
102
  self.start_timer = None
98
- self._per_zone_total_track_ids = {}
103
+
104
+ # Track ID storage for total count calculation
105
+ self._total_track_ids = set() # Store all unique track IDs seen across calls
106
+ self._current_frame_track_ids = set() # Store track IDs from current frame
107
+ self._total_count = 0 # Cached total count
108
+ self._last_update_time = time.time() # Track when last updated
109
+
110
+ # Zone-based tracking storage
111
+ self._zone_current_track_ids = {} # zone_name -> set of current track IDs in zone
112
+ self._zone_total_track_ids = {} # zone_name -> set of all track IDs that have been in zone
113
+ self._zone_current_counts = {} # zone_name -> current count in zone
114
+ self._zone_total_counts = {} # zone_name -> total count that have been in zone
99
115
 
100
116
  def process(self, data: Any, config: ConfigProtocol, context: Optional[ProcessingContext] = None,
101
117
  stream_info: Optional[Dict[str, Any]] = None) -> ProcessingResult:
102
- # Note: start_time not used; keeping processing focused on zone-based counts
118
+ start_time = time.time()
103
119
  if not isinstance(config, VehicleMonitoringConfig):
104
120
  return self.create_error_result("Invalid config type", usecase=self.name, category=self.category, context=context)
105
121
  if context is None:
@@ -151,36 +167,7 @@ class VehicleMonitoringUseCase(BaseProcessor):
151
167
  except Exception as e:
152
168
  self.logger.warning(f"AdvancedTracker failed: {e}")
153
169
 
154
- # If zones are configured, keep only detections that fall inside any zone
155
- detections_for_counting = processed_data
156
- if getattr(config, 'zone_config', None) and getattr(config.zone_config, 'zones', None):
157
- zones = config.zone_config.zones
158
- in_zone_detections = []
159
- for det in processed_data:
160
- matched_zones = []
161
- for zone_name, zone_polygon in zones.items():
162
- if self._is_detection_in_zone(det, zone_polygon):
163
- matched_zones.append(zone_name)
164
- if matched_zones:
165
- det_copy = dict(det)
166
- det_copy['zones'] = matched_zones
167
- in_zone_detections.append(det_copy)
168
- detections_for_counting = in_zone_detections
169
-
170
- self._update_tracking_state(detections_for_counting)
171
- # Maintain cumulative per-zone unique track counts using canonicalized track_ids
172
- if getattr(config, 'zone_config', None) and getattr(config.zone_config, 'zones', None):
173
- if not hasattr(self, '_per_zone_total_track_ids'):
174
- self._per_zone_total_track_ids = {}
175
- for det in detections_for_counting:
176
- track_id = det.get('track_id')
177
- if track_id is None:
178
- continue
179
- category = det.get('category', 'unknown')
180
- for zone_name in det.get('zones', []):
181
- zone_map = self._per_zone_total_track_ids.setdefault(zone_name, {})
182
- cat_set = zone_map.setdefault(category, set())
183
- cat_set.add(track_id)
170
+ self._update_tracking_state(processed_data)
184
171
  self._total_frame_counter += 1
185
172
 
186
173
  frame_number = None
@@ -191,40 +178,41 @@ class VehicleMonitoringUseCase(BaseProcessor):
191
178
  if start_frame is not None and end_frame is not None and start_frame == end_frame:
192
179
  frame_number = start_frame
193
180
 
194
- # Compute zone-wise counts (and filter totals) if zones are provided
195
- zone_counts = {}
196
- if getattr(config, 'zone_config', None) and getattr(config.zone_config, 'zones', None):
197
- try:
198
- zone_counts = count_objects_in_zones(detections_for_counting, config.zone_config.zones)
199
- except Exception as e:
200
- self.logger.warning("Zone counting failed: %s", e)
201
- counting_summary = self._count_categories(detections_for_counting, config)
181
+ general_counting_summary = calculate_counting_summary(data)
182
+ counting_summary = self._count_categories(processed_data, config)
202
183
  total_counts = self.get_total_counts()
203
184
  counting_summary['total_counts'] = total_counts
204
- # Attach zone analysis to counting summary so it can be included in human text
205
- counting_summary['zone_analysis'] = zone_counts
206
- # Attach total zone analysis (unique canonical tracks per zone/category) if available
207
- if hasattr(self, '_per_zone_total_track_ids'):
208
- counting_summary['zone_analysis_total'] = {
209
- zone_name: {cat: len(ids) for cat, ids in cat_map.items()}
210
- for zone_name, cat_map in self._per_zone_total_track_ids.items()
211
- }
212
- print("----------------------------CS-------------------------------")
213
- print(counting_summary)
214
- print("----------------------------CS-------------------------------")
215
-
216
- alerts = self._check_alerts(counting_summary, frame_number, config)
217
- # predictions are not required in the current agg_summary; skip computing to avoid unused variable
218
-
219
- incidents_list = self._generate_incidents(counting_summary, alerts, config, frame_number, stream_info)
220
- tracking_stats_list = self._generate_tracking_stats(counting_summary, alerts, config, frame_number, stream_info)
221
- business_analytics_list = self._generate_business_analytics(counting_summary, alerts, config, stream_info, is_empty=True)
222
- summary_list = self._generate_summary(counting_summary, incidents_list, tracking_stats_list, business_analytics_list, alerts)
223
-
224
- print("-----------------------------TS----------------------------------")
185
+ for detection in processed_data:
186
+ category = detection.get("category", "unknown")
187
+ counting_summary["categories"][category] = counting_summary["categories"].get(category, 0) + 1
188
+
189
+ zone_analysis = {}
190
+ if config.zone_config and config.zone_config.zones:
191
+ # Convert single frame to format expected by count_objects_in_zones
192
+ frame_data = processed_data #[frame_detections]
193
+ zone_analysis = count_objects_in_zones(frame_data, config.zone_config.zones)
194
+
195
+ # Update zone tracking with current frame data
196
+ if zone_analysis and config.enable_tracking:
197
+ enhanced_zone_analysis = self._update_zone_tracking(zone_analysis, processed_data, config)
198
+ # Merge enhanced zone analysis with original zone analysis
199
+ for zone_name, enhanced_data in enhanced_zone_analysis.items():
200
+ zone_analysis[zone_name] = enhanced_data
201
+
202
+ print("-----------------------------ZONEEEE-----------------------------------")
203
+ print(zone_analysis)
204
+ print("-----------------------------ZONEEEE-----------------------------------")
205
+
206
+ alerts = self._check_alerts(counting_summary,zone_analysis, frame_number, config)
207
+ predictions = self._extract_predictions(processed_data)
208
+
209
+ incidents_list = self._generate_incidents(counting_summary,zone_analysis, alerts, config, frame_number, stream_info)
210
+ tracking_stats_list = self._generate_tracking_stats(counting_summary,zone_analysis, alerts, config, frame_number, stream_info)
211
+ print("---------------------------TS--------------------------------------")
225
212
  print(tracking_stats_list)
226
- print("-----------------------------TS----------------------------------")
227
-
213
+ print("---------------------------TS--------------------------------------")
214
+ business_analytics_list = self._generate_business_analytics(counting_summary,zone_analysis, alerts, config, stream_info, is_empty=True)
215
+ summary_list = self._generate_summary(counting_summary,zone_analysis, incidents_list, tracking_stats_list, business_analytics_list, alerts)
228
216
 
229
217
  incidents = incidents_list[0] if incidents_list else {}
230
218
  tracking_stats = tracking_stats_list[0] if tracking_stats_list else {}
@@ -235,12 +223,9 @@ class VehicleMonitoringUseCase(BaseProcessor):
235
223
  "tracking_stats": tracking_stats,
236
224
  "business_analytics": business_analytics,
237
225
  "alerts": alerts,
238
- "zone_analysis": zone_counts,
226
+ "zone_analysis": zone_analysis,
239
227
  "human_text": summary}
240
228
  }
241
- print("--------------------------------agg_summary--------------------------------")
242
- print(agg_summary)
243
- print("--------------------------------agg_summary--------------------------------")
244
229
 
245
230
  context.mark_completed()
246
231
  result = self.create_result(
@@ -251,6 +236,84 @@ class VehicleMonitoringUseCase(BaseProcessor):
251
236
  )
252
237
  return result
253
238
 
239
+ def _update_zone_tracking(self, zone_analysis: Dict[str, Dict[str, int]], detections: List[Dict], config: VehicleMonitoringConfig) -> Dict[str, Dict[str, Any]]:
240
+ """
241
+ Update zone tracking with current frame data.
242
+
243
+ Args:
244
+ zone_analysis: Current zone analysis results
245
+ detections: List of detections with track IDs
246
+
247
+ Returns:
248
+ Enhanced zone analysis with tracking information
249
+ """
250
+ if not zone_analysis or not config.zone_config or not config.zone_config.zones:
251
+ return {}
252
+
253
+ enhanced_zone_analysis = {}
254
+ zones = config.zone_config.zones
255
+
256
+ # Get current frame track IDs in each zone
257
+ current_frame_zone_tracks = {}
258
+
259
+ # Initialize zone tracking for all zones
260
+ for zone_name in zones.keys():
261
+ current_frame_zone_tracks[zone_name] = set()
262
+ if zone_name not in self._zone_current_track_ids:
263
+ self._zone_current_track_ids[zone_name] = set()
264
+ if zone_name not in self._zone_total_track_ids:
265
+ self._zone_total_track_ids[zone_name] = set()
266
+
267
+ # Check each detection against each zone
268
+ for detection in detections:
269
+ track_id = detection.get("track_id")
270
+ if track_id is None:
271
+ continue
272
+
273
+ # Get detection bbox
274
+ bbox = detection.get("bounding_box", detection.get("bbox"))
275
+ if not bbox:
276
+ continue
277
+
278
+ # Get detection center point
279
+ center_point = get_bbox_bottom25_center(bbox) #get_bbox_center(bbox)
280
+
281
+ # Check which zone this detection is in using actual zone polygons
282
+ for zone_name, zone_polygon in zones.items():
283
+ # Convert polygon points to tuples for point_in_polygon function
284
+ # zone_polygon format: [[x1, y1], [x2, y2], [x3, y3], ...]
285
+ polygon_points = [(point[0], point[1]) for point in zone_polygon]
286
+
287
+ # Check if detection center is inside the zone polygon using ray casting algorithm
288
+ if point_in_polygon(center_point, polygon_points):
289
+ current_frame_zone_tracks[zone_name].add(track_id)
290
+
291
+ # Update zone tracking for each zone
292
+ for zone_name, zone_counts in zone_analysis.items():
293
+ # Get current frame tracks for this zone
294
+ current_tracks = current_frame_zone_tracks.get(zone_name, set())
295
+
296
+ # Update current zone tracks
297
+ self._zone_current_track_ids[zone_name] = current_tracks
298
+
299
+ # Update total zone tracks (accumulate all track IDs that have been in this zone)
300
+ self._zone_total_track_ids[zone_name].update(current_tracks)
301
+
302
+ # Update counts
303
+ self._zone_current_counts[zone_name] = len(current_tracks)
304
+ self._zone_total_counts[zone_name] = len(self._zone_total_track_ids[zone_name])
305
+
306
+ # Create enhanced zone analysis
307
+ enhanced_zone_analysis[zone_name] = {
308
+ "current_count": self._zone_current_counts[zone_name],
309
+ "total_count": self._zone_total_counts[zone_name],
310
+ "current_track_ids": list(current_tracks),
311
+ "total_track_ids": list(self._zone_total_track_ids[zone_name]),
312
+ "original_counts": zone_counts # Preserve original zone counts
313
+ }
314
+
315
+ return enhanced_zone_analysis
316
+
254
317
  def _normalize_yolo_results(self, data: Any, index_to_category: Optional[Dict[int, str]] = None) -> Any:
255
318
  """
256
319
  Normalize YOLO-style outputs to internal detection schema:
@@ -324,7 +387,7 @@ class VehicleMonitoringUseCase(BaseProcessor):
324
387
  return normalized_dict
325
388
  return data
326
389
 
327
- def _check_alerts(self, summary: dict, frame_number: Any, config: VehicleMonitoringConfig) -> List[Dict]:
390
+ def _check_alerts(self, summary: dict, zone_analysis: Dict, frame_number: Any, config: VehicleMonitoringConfig) -> List[Dict]:
328
391
  def get_trend(data, lookback=900, threshold=0.6):
329
392
  window = data[-lookback:] if len(data) >= lookback else data
330
393
  if len(window) < 2:
@@ -357,7 +420,7 @@ class VehicleMonitoringUseCase(BaseProcessor):
357
420
  "threshold_level": threshold,
358
421
  "ascending": get_trend(self._ascending_alert_list, lookback=900, threshold=0.8),
359
422
  "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']),
360
- getattr(config.alert_config, 'alert_value', ['JSON']))}
423
+ getattr(config.alert_config, 'alert_value', ['JSON']))}
361
424
  })
362
425
  elif category in per_category_count and per_category_count[category] > threshold:
363
426
  alerts.append({
@@ -367,12 +430,12 @@ class VehicleMonitoringUseCase(BaseProcessor):
367
430
  "threshold_level": threshold,
368
431
  "ascending": get_trend(self._ascending_alert_list, lookback=900, threshold=0.8),
369
432
  "settings": {t: v for t, v in zip(getattr(config.alert_config, 'alert_type', ['Default']),
370
- getattr(config.alert_config, 'alert_value', ['JSON']))}
433
+ getattr(config.alert_config, 'alert_value', ['JSON']))}
371
434
  })
372
435
  return alerts
373
436
 
374
- def _generate_incidents(self, counting_summary: Dict, alerts: List, config: VehicleMonitoringConfig,
375
- frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[Dict]:
437
+ def _generate_incidents(self, counting_summary: Dict, zone_analysis: Dict, alerts: List, config: VehicleMonitoringConfig,
438
+ frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[Dict]:
376
439
  incidents = []
377
440
  total_detections = counting_summary.get("total_count", 0)
378
441
  current_timestamp = self._get_current_timestamp_str(stream_info)
@@ -458,7 +521,7 @@ class VehicleMonitoringUseCase(BaseProcessor):
458
521
  incidents.append({})
459
522
  return incidents
460
523
 
461
- def _generate_tracking_stats(self, counting_summary: Dict, alerts: List, config: VehicleMonitoringConfig,
524
+ def _generate_tracking_stats(self, counting_summary: Dict, zone_analysis: Dict, alerts: List, config: VehicleMonitoringConfig,
462
525
  frame_number: Optional[int] = None, stream_info: Optional[Dict[str, Any]] = None) -> List[Dict]:
463
526
  camera_info = self.get_camera_info_from_stream(stream_info)
464
527
  tracking_stats = []
@@ -504,49 +567,11 @@ class VehicleMonitoringUseCase(BaseProcessor):
504
567
  human_text_lines = [f"Tracking Statistics:"]
505
568
  human_text_lines.append(f"CURRENT FRAME @ {current_timestamp}")
506
569
  for cat, count in per_category_count.items():
507
- if cat in ['car', 'bicycle', 'bus', 'motorcycle']:
508
- human_text_lines.append(f"\t{cat}: {count}")
509
- else:
510
- human_text_lines.append("No Detections in Frame")
511
- # Append zone analysis for the current frame if available
512
- zone_analysis = counting_summary.get("zone_analysis", {})
513
- if zone_analysis:
514
- human_text_lines.append("ZONE ANALYSIS (CURRENT FRAME):")
515
- for zone_name, cat_counts in zone_analysis.items():
516
- if isinstance(cat_counts, dict):
517
- total_in_zone = sum(cat_counts.values())
518
- car_count = (
519
- cat_counts.get('car', 0)
520
- + cat_counts.get('truck', 0)
521
- )
522
- if car_count > 0:
523
- human_text_lines.append(f"\t{zone_name}: total={total_in_zone} (car: {car_count})")
524
- else:
525
- human_text_lines.append(f"\t{zone_name}: total={total_in_zone}")
526
- else:
527
- human_text_lines.append(f"\t{zone_name}: total=0")
570
+ human_text_lines.append(f"\t{cat}: {count}")
528
571
  human_text_lines.append(f"TOTAL SINCE {start_timestamp}")
529
572
  for cat, count in total_counts_dict.items():
530
- if cat in ['car', 'bicycle', 'bus', 'motorcycle']:
531
- if count > 0:
532
- human_text_lines.append(f"\t{cat}: {count}")
533
- # Append zone analysis totals across time if available
534
- zone_analysis_total = counting_summary.get("zone_analysis_total", {})
535
- if zone_analysis_total:
536
- human_text_lines.append("ZONE ANALYSIS (TOTAL SINCE START):")
537
- for zone_name, cat_counts in zone_analysis_total.items():
538
- if isinstance(cat_counts, dict):
539
- total_in_zone = sum(cat_counts.values())
540
- car_count = (
541
- cat_counts.get('car', 0)
542
- + cat_counts.get('truck', 0)
543
- )
544
- if car_count > 0:
545
- human_text_lines.append(f"\t{zone_name}: total={total_in_zone} (car: {car_count})")
546
- else:
547
- human_text_lines.append(f"\t{zone_name}: total={total_in_zone}")
548
- else:
549
- human_text_lines.append(f"\t{zone_name}: total=0")
573
+ if count > 0:
574
+ human_text_lines.append(f"\t{cat}: {count}")
550
575
  if alerts:
551
576
  for alert in alerts:
552
577
  human_text_lines.append(f"Alerts: {alert.get('settings', {})} sent @ {current_timestamp}")
@@ -570,12 +595,12 @@ class VehicleMonitoringUseCase(BaseProcessor):
570
595
  tracking_stats.append(tracking_stat)
571
596
  return tracking_stats
572
597
 
573
- def _generate_business_analytics(self, counting_summary: Dict, alerts: Any, config: VehicleMonitoringConfig,
598
+ def _generate_business_analytics(self, counting_summary: Dict, zone_analysis: Dict, alerts: Any, config: VehicleMonitoringConfig,
574
599
  stream_info: Optional[Dict[str, Any]] = None, is_empty=False) -> List[Dict]:
575
600
  if is_empty:
576
601
  return []
577
602
 
578
- def _generate_summary(self, summary: dict, incidents: List, tracking_stats: List, business_analytics: List, alerts: List) -> List[str]:
603
+ def _generate_summary(self, summary: dict, zone_analysis: Dict, incidents: List, tracking_stats: List, business_analytics: List, alerts: List) -> List[str]:
579
604
  """
580
605
  Generate a human_text string for the tracking_stat, incident, business analytics and alerts.
581
606
  """
@@ -835,13 +860,6 @@ class VehicleMonitoringUseCase(BaseProcessor):
835
860
  union_area = area1 + area2 - inter_area
836
861
  return (inter_area / union_area) if union_area > 0 else 0.0
837
862
 
838
- def _is_detection_in_zone(self, detection: Dict[str, Any], zone_polygon: List[List[float]]) -> bool:
839
- bbox = detection.get("bounding_box", detection.get("bbox"))
840
- if not bbox:
841
- return False
842
- bottom25_center = get_bbox_bottom25_center(bbox)
843
- return point_in_polygon(bottom25_center, [(p[0], p[1]) for p in zone_polygon])
844
-
845
863
  def _merge_or_register_track(self, raw_id: Any, bbox: Any) -> Any:
846
864
  if raw_id is None or bbox is None:
847
865
  return raw_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrice
3
- Version: 1.0.99393
3
+ Version: 1.0.99394
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
@@ -236,7 +236,7 @@ matrice/deploy/utils/post_processing/usecases/template_usecase.py,sha256=6NC-bTn
236
236
  matrice/deploy/utils/post_processing/usecases/theft_detection.py,sha256=Rs_zKn2z9YM10fGzTHR44Q3m8TIO1s5UMdiPWA03rbA,28671
237
237
  matrice/deploy/utils/post_processing/usecases/traffic_sign_monitoring.py,sha256=nDlEzHgMlUjy_VtJ7usnEzMcdSs-jouqaoJpJ8DYUMw,34351
238
238
  matrice/deploy/utils/post_processing/usecases/underwater_pollution_detection.py,sha256=jqP1ZKfDZe2-56Lyvgb2DxnbqRfvxm6pPL0Ck3esfBk,40356
239
- matrice/deploy/utils/post_processing/usecases/vehicle_monitoring.py,sha256=0puMZ3k_1vscgB7SJL2jIEjCZ4h3dwVleQUPNaMNGcw,45173
239
+ matrice/deploy/utils/post_processing/usecases/vehicle_monitoring.py,sha256=-TtvPEHShXlslhxpjSEGFEdeeP0zY-OYu635969K51I,45525
240
240
  matrice/deploy/utils/post_processing/usecases/warehouse_object_segmentation.py,sha256=5uZXTJL_A3tUEN08T-_ZQpUoJ9gqbuuMc4z2mT4sMnQ,43753
241
241
  matrice/deploy/utils/post_processing/usecases/waterbody_segmentation.py,sha256=JsCxDEMB8s4WDcezfJDr2zrjM-TCjB9hxOztzSvWmpY,45268
242
242
  matrice/deploy/utils/post_processing/usecases/weapon_detection.py,sha256=gea-rjEHmP0hUjpcrcQIHOnhMMHQNqDI90cbpXHnlpI,31071
@@ -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.99393.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
265
- matrice-1.0.99393.dist-info/METADATA,sha256=0XiAKaevRgUqDUghFhVjQYgozLtAbO115t78n49gf-E,14624
266
- matrice-1.0.99393.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
267
- matrice-1.0.99393.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
268
- matrice-1.0.99393.dist-info/RECORD,,
264
+ matrice-1.0.99394.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
265
+ matrice-1.0.99394.dist-info/METADATA,sha256=3bISm-l43QIoOwL2kjo_BTbUsV2TC-dCMaMPPNgRvdQ,14624
266
+ matrice-1.0.99394.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
267
+ matrice-1.0.99394.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
268
+ matrice-1.0.99394.dist-info/RECORD,,