matrice 1.0.99267__py3-none-any.whl → 1.0.99268__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/utils/post_processing/usecases/proximity_detection.py +166 -104
- {matrice-1.0.99267.dist-info → matrice-1.0.99268.dist-info}/METADATA +1 -1
- {matrice-1.0.99267.dist-info → matrice-1.0.99268.dist-info}/RECORD +6 -6
- {matrice-1.0.99267.dist-info → matrice-1.0.99268.dist-info}/WHEEL +0 -0
- {matrice-1.0.99267.dist-info → matrice-1.0.99268.dist-info}/licenses/LICENSE.txt +0 -0
- {matrice-1.0.99267.dist-info → matrice-1.0.99268.dist-info}/top_level.txt +0 -0
@@ -6,9 +6,9 @@ with zone-based analysis, tracking, and alerting capabilities.
|
|
6
6
|
"""
|
7
7
|
|
8
8
|
from typing import Any, Dict, List, Optional, Set
|
9
|
-
from dataclasses import asdict
|
10
9
|
import time
|
11
10
|
from datetime import datetime, timezone
|
11
|
+
import math
|
12
12
|
|
13
13
|
from ..core.base import BaseProcessor, ProcessingContext, ProcessingResult, ConfigProtocol, ResultFormat
|
14
14
|
from ..core.config import ProximityConfig, ZoneConfig, AlertConfig
|
@@ -65,6 +65,7 @@ class ProximityUseCase(BaseProcessor):
|
|
65
65
|
|
66
66
|
# Proximity counting
|
67
67
|
self._total_proximity_count = 0 # Total proximity events across all calls
|
68
|
+
self._observed_proximity_pairs: Set[frozenset] = set() # Unique canonical ID pairs seen across frames
|
68
69
|
|
69
70
|
|
70
71
|
# --------------------------------------------------------------------- #
|
@@ -108,7 +109,7 @@ class ProximityUseCase(BaseProcessor):
|
|
108
109
|
Returns:
|
109
110
|
ProcessingResult: Processing result with standardized agg_summary structure
|
110
111
|
"""
|
111
|
-
start_time = time.time()
|
112
|
+
# start_time = time.time()
|
112
113
|
|
113
114
|
try:
|
114
115
|
# Ensure we have the right config type
|
@@ -144,8 +145,8 @@ class ProximityUseCase(BaseProcessor):
|
|
144
145
|
else:
|
145
146
|
return self._process_single_frame(data, config, context, stream_info)
|
146
147
|
|
147
|
-
except Exception as e:
|
148
|
-
self.logger.error(
|
148
|
+
except Exception as e: # noqa: BLE001
|
149
|
+
self.logger.error("Proximity detection failed: %s", str(e), exc_info=True)
|
149
150
|
|
150
151
|
if context:
|
151
152
|
context.mark_completed()
|
@@ -283,9 +284,13 @@ class ProximityUseCase(BaseProcessor):
|
|
283
284
|
current_count = counting_summary["categories"].get(category, 0)
|
284
285
|
counting_summary["categories"][category] = current_count + 1
|
285
286
|
|
286
|
-
|
287
|
+
# Update tracking state BEFORE proximity calculation so we have canonical IDs
|
288
|
+
self._update_tracking_state(counting_summary)
|
289
|
+
|
290
|
+
# Calculate unique proximity events for this frame
|
291
|
+
proximity_count = self._count_proximity_events(counting_summary["detections"])
|
287
292
|
counting_summary["proximity_events"] = proximity_count
|
288
|
-
counting_summary["total_proximity_count"] = self._total_proximity_count
|
293
|
+
counting_summary["total_proximity_count"] = self._total_proximity_count
|
289
294
|
|
290
295
|
# Step 5: Zone analysis for this frame
|
291
296
|
zone_analysis = {}
|
@@ -301,9 +306,6 @@ class ProximityUseCase(BaseProcessor):
|
|
301
306
|
for zone_name, enhanced_data in enhanced_zone_analysis.items():
|
302
307
|
zone_analysis[zone_name] = enhanced_data
|
303
308
|
|
304
|
-
# Step 4.5: Always update tracking state (regardless of enable_unique_counting setting)
|
305
|
-
self._update_tracking_state(counting_summary)
|
306
|
-
|
307
309
|
# Step 5: Generate insights and alerts for this frame
|
308
310
|
alerts = self._check_alerts(counting_summary, zone_analysis, config, frame_id)
|
309
311
|
|
@@ -402,11 +404,10 @@ class ProximityUseCase(BaseProcessor):
|
|
402
404
|
|
403
405
|
# Add zone-specific events if applicable
|
404
406
|
if zone_analysis:
|
405
|
-
human_text_lines.append(
|
407
|
+
human_text_lines.append("\t- ZONE EVENTS:")
|
406
408
|
for zone_name, zone_count in zone_analysis.items():
|
407
409
|
zone_total = self._robust_zone_total(zone_count)
|
408
410
|
if zone_total > 0:
|
409
|
-
zone_intensity = min(10.0, zone_total / 5.0)
|
410
411
|
zone_level = "info"
|
411
412
|
if intensity >= 9:
|
412
413
|
level = "critical"
|
@@ -432,14 +433,14 @@ class ProximityUseCase(BaseProcessor):
|
|
432
433
|
incidents.append(event)
|
433
434
|
return incidents
|
434
435
|
|
435
|
-
def _generate_tracking_stats(self, counting_summary: Dict, zone_analysis: Dict, config: ProximityConfig, frame_id: str, alerts: Any=
|
436
|
+
def _generate_tracking_stats(self, counting_summary: Dict, zone_analysis: Dict, config: ProximityConfig, frame_id: str, alerts: Any=None, stream_info: Optional[Dict[str, Any]] = None) -> List[Dict]:
|
436
437
|
"""Generate tracking stats using standardized methods."""
|
437
438
|
|
438
439
|
total_people = counting_summary.get("total_objects", 0)
|
439
440
|
|
440
441
|
# Get total count from cached tracking state
|
441
442
|
total_unique_count = self.get_total_count()
|
442
|
-
current_frame_count = self.get_current_frame_count()
|
443
|
+
# current_frame_count = self.get_current_frame_count()
|
443
444
|
|
444
445
|
# Get camera info using standardized method
|
445
446
|
camera_info = self.get_camera_info_from_stream(stream_info)
|
@@ -520,7 +521,7 @@ class ProximityUseCase(BaseProcessor):
|
|
520
521
|
detection_obj = self.create_detection_object(category, bbox)
|
521
522
|
detections.append(detection_obj)
|
522
523
|
|
523
|
-
|
524
|
+
# detections prepared above are used only for output formatting
|
524
525
|
# Build alerts and alert_settings arrays
|
525
526
|
alert_settings = []
|
526
527
|
if config.alert_config and hasattr(config.alert_config, 'alert_type'):
|
@@ -534,42 +535,44 @@ class ProximityUseCase(BaseProcessor):
|
|
534
535
|
}
|
535
536
|
})
|
536
537
|
if zone_analysis:
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
return 0
|
556
|
-
human_text_lines.append(f"\t- People Detected: {total_people}")
|
557
|
-
human_text_lines.append("")
|
558
|
-
human_text_lines.append(f"TOTAL SINCE @ {start_timestamp}:")
|
559
|
-
|
560
|
-
for zone_name, zone_count in zone_analysis.items():
|
561
|
-
zone_total = robust_zone_total(zone_count)
|
562
|
-
human_text_lines.append(f"\t- Zone name: {zone_name}")
|
563
|
-
human_text_lines.append(f"\t\t- Total count in zone: {zone_total-1}")
|
564
|
-
|
565
|
-
if total_unique_count > 0:
|
566
|
-
human_text_lines.append(f"\t- Total unique people in the scene: {total_unique_count}")
|
567
|
-
if alerts:
|
568
|
-
for alert in alerts:
|
569
|
-
human_text_lines.append(f"Alerts: {alert.get('settings', {})} sent @ {current_timestamp}")
|
538
|
+
human_text_lines = []
|
539
|
+
current_timestamp = self._get_current_timestamp_str(stream_info, frame_id=frame_id)
|
540
|
+
start_timestamp = self._get_start_timestamp_str(stream_info)
|
541
|
+
human_text_lines.append(f"CURRENT FRAME @ {current_timestamp}:")
|
542
|
+
|
543
|
+
def robust_zone_total(zone_count):
|
544
|
+
if isinstance(zone_count, dict):
|
545
|
+
total = 0
|
546
|
+
for v in zone_count.values():
|
547
|
+
if isinstance(v, int):
|
548
|
+
total += v
|
549
|
+
elif isinstance(v, list) and total == 0:
|
550
|
+
total += len(v)
|
551
|
+
return total
|
552
|
+
elif isinstance(zone_count, list):
|
553
|
+
return len(zone_count)
|
554
|
+
elif isinstance(zone_count, int):
|
555
|
+
return zone_count
|
570
556
|
else:
|
571
|
-
|
572
|
-
|
557
|
+
return 0
|
558
|
+
|
559
|
+
human_text_lines.append(f"\t- People Detected: {total_people}")
|
560
|
+
human_text_lines.append("")
|
561
|
+
human_text_lines.append(f"TOTAL SINCE @ {start_timestamp}:")
|
562
|
+
|
563
|
+
for zone_name, zone_count in zone_analysis.items():
|
564
|
+
zone_total = robust_zone_total(zone_count)
|
565
|
+
human_text_lines.append(f"\t- Zone name: {zone_name}")
|
566
|
+
human_text_lines.append(f"\t\t- Total count in zone: {zone_total}")
|
567
|
+
|
568
|
+
if total_unique_count > 0:
|
569
|
+
human_text_lines.append(f"\t- Total unique people in the scene: {total_unique_count}")
|
570
|
+
if alerts:
|
571
|
+
for alert in alerts:
|
572
|
+
human_text_lines.append(f"Alerts: {alert.get('settings', {})} sent @ {current_timestamp}")
|
573
|
+
else:
|
574
|
+
human_text_lines.append("Alerts: None")
|
575
|
+
human_text = "\n".join(human_text_lines)
|
573
576
|
else:
|
574
577
|
human_text = self._generate_human_text_for_tracking(total_people, detections, total_unique_count, config, frame_id, alerts, stream_info)
|
575
578
|
|
@@ -580,43 +583,97 @@ class ProximityUseCase(BaseProcessor):
|
|
580
583
|
tracking_stat = self.create_tracking_stats(
|
581
584
|
total_counts, current_counts, detections, human_text, camera_info, alerts, alert_settings, start_time=high_precision_start_timestamp, reset_time=high_precision_reset_timestamp
|
582
585
|
)
|
583
|
-
print(tracking_stat)
|
584
586
|
return [tracking_stat]
|
585
587
|
|
586
|
-
def _count_proximity_events(self, detections):
|
587
|
-
"""Count proximity events between detections.
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
588
|
+
def _count_proximity_events(self, detections: List[Dict[str, Any]]) -> int:
|
589
|
+
"""Count UNIQUE proximity events between detections in a frame.
|
590
|
+
|
591
|
+
Rules:
|
592
|
+
- If canonical track IDs are present, deduplicate by track_id first.
|
593
|
+
- Otherwise, deduplicate overlapping boxes using IoU to avoid duplicate detections of the same person.
|
594
|
+
- Count each pair once (i < j) using Euclidean distance between bottom-center points.
|
595
|
+
- Maintain a running set of unique canonical-ID pairs across frames to compute total unique proximity events.
|
596
|
+
"""
|
597
|
+
if not detections:
|
598
|
+
return 0
|
599
|
+
|
600
|
+
proximity_threshold = 400.0 # pixels, screen space
|
601
|
+
iou_duplicate_threshold = getattr(self, "_proximity_iou_duplicate_threshold", 0.5)
|
602
|
+
|
603
|
+
# Step 1: Deduplicate detections
|
604
|
+
unique_detections: List[Dict[str, Any]] = []
|
605
|
+
seen_track_ids: Set[Any] = set()
|
606
|
+
|
607
|
+
for det in detections:
|
608
|
+
track_id = det.get("track_id")
|
609
|
+
bbox = det.get("bounding_box", det.get("bbox", {}))
|
610
|
+
if not bbox:
|
611
|
+
continue
|
612
|
+
|
613
|
+
# Prefer canonical track IDs if present (set earlier in _update_tracking_state)
|
614
|
+
if track_id is not None:
|
615
|
+
if track_id in seen_track_ids:
|
597
616
|
continue
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
617
|
+
seen_track_ids.add(track_id)
|
618
|
+
unique_detections.append(det)
|
619
|
+
continue
|
620
|
+
|
621
|
+
# Fallback: IoU-based dedup for pure detection outputs without track IDs
|
622
|
+
is_duplicate = False
|
623
|
+
for kept in unique_detections:
|
624
|
+
kept_bbox = kept.get("bounding_box", kept.get("bbox", {}))
|
625
|
+
if self._compute_iou(bbox, kept_bbox) >= iou_duplicate_threshold:
|
626
|
+
is_duplicate = True
|
627
|
+
break
|
628
|
+
if not is_duplicate:
|
629
|
+
unique_detections.append(det)
|
630
|
+
|
631
|
+
# Step 2: Compute proximity pairs uniquely (i < j)
|
632
|
+
frame_unique_count = 0
|
633
|
+
|
634
|
+
for i in range(len(unique_detections)):
|
635
|
+
det_i = unique_detections[i]
|
636
|
+
bbox_i = det_i.get("bounding_box", det_i.get("bbox", {}))
|
637
|
+
p_i = get_bbox_bottom25_center(bbox_i) or get_bbox_center(bbox_i)
|
638
|
+
if not p_i:
|
639
|
+
continue
|
640
|
+
|
641
|
+
for j in range(i + 1, len(unique_detections)):
|
642
|
+
det_j = unique_detections[j]
|
643
|
+
bbox_j = det_j.get("bounding_box", det_j.get("bbox", {}))
|
644
|
+
p_j = get_bbox_bottom25_center(bbox_j) or get_bbox_center(bbox_j)
|
645
|
+
if not p_j:
|
646
|
+
continue
|
647
|
+
|
648
|
+
dx = float(p_i[0]) - float(p_j[0])
|
649
|
+
dy = float(p_i[1]) - float(p_j[1])
|
650
|
+
distance = math.hypot(dx, dy)
|
651
|
+
if distance >= proximity_threshold:
|
652
|
+
continue
|
653
|
+
|
654
|
+
frame_unique_count += 1
|
655
|
+
|
656
|
+
# Update global unique proximity pairs only when both have canonical IDs
|
657
|
+
id_i = det_i.get("track_id")
|
658
|
+
id_j = det_j.get("track_id")
|
659
|
+
if id_i is not None and id_j is not None:
|
660
|
+
pair_key = frozenset({id_i, id_j})
|
661
|
+
if pair_key not in self._observed_proximity_pairs:
|
662
|
+
self._observed_proximity_pairs.add(pair_key)
|
663
|
+
self._total_proximity_count += 1
|
664
|
+
|
665
|
+
return frame_unique_count
|
608
666
|
|
609
667
|
def _generate_human_text_for_tracking(
|
610
|
-
self,
|
611
|
-
|
612
|
-
detections,
|
613
|
-
|
614
|
-
|
615
|
-
frame_id: str,
|
616
|
-
alerts:Any=
|
668
|
+
self,
|
669
|
+
_total_people: int,
|
670
|
+
detections,
|
671
|
+
_total_unique_count: int,
|
672
|
+
_config: ProximityConfig,
|
673
|
+
frame_id: str,
|
674
|
+
alerts: Any = None,
|
617
675
|
stream_info: Optional[Dict[str, Any]] = None) -> str:
|
618
676
|
"""Generate human-readable text for tracking stats in old format."""
|
619
|
-
from datetime import datetime, timezone
|
620
677
|
|
621
678
|
human_text_lines=[]
|
622
679
|
current_timestamp = self._get_current_timestamp_str(stream_info, precision=True, frame_id=frame_id)
|
@@ -625,7 +682,6 @@ class ProximityUseCase(BaseProcessor):
|
|
625
682
|
human_text_lines.append(f"CURRENT FRAME @ {current_timestamp}:")
|
626
683
|
|
627
684
|
# Add proximity count to human text
|
628
|
-
# Add proximity count to human text
|
629
685
|
proximity_count = self._count_proximity_events(detections)
|
630
686
|
if proximity_count > 0:
|
631
687
|
human_text_lines.append(f"\t- Current Frame Proximity: {proximity_count}")
|
@@ -635,7 +691,10 @@ class ProximityUseCase(BaseProcessor):
|
|
635
691
|
human_text_lines.append("")
|
636
692
|
if proximity_count > 0:
|
637
693
|
human_text_lines.append(f"TOTAL SINCE @ {start_timestamp}:")
|
638
|
-
|
694
|
+
# If tracking IDs are available, _total_proximity_count already includes this frame's new pairs
|
695
|
+
# Otherwise, fall back to showing the current frame's count
|
696
|
+
total_unique = self._total_proximity_count if self._total_proximity_count > 0 else proximity_count
|
697
|
+
human_text_lines.append(f"\t- Total Proximity Count: {total_unique}")
|
639
698
|
|
640
699
|
if alerts:
|
641
700
|
for alert in alerts:
|
@@ -712,7 +771,6 @@ class ProximityUseCase(BaseProcessor):
|
|
712
771
|
for zone_name, threshold in config.alert_config.occupancy_thresholds.items():
|
713
772
|
if zone_name in zone_analysis:
|
714
773
|
# Calculate zone_count robustly (supports int, list, dict values)
|
715
|
-
print('ZONEEE',zone_name, zone_analysis[zone_name])
|
716
774
|
zone_count = self._robust_zone_total(zone_analysis[zone_name])
|
717
775
|
if zone_count >= threshold:
|
718
776
|
alerts.append({
|
@@ -771,7 +829,7 @@ class ProximityUseCase(BaseProcessor):
|
|
771
829
|
|
772
830
|
return business_analytics
|
773
831
|
|
774
|
-
def _generate_summary(self,
|
832
|
+
def _generate_summary(self, _summary: dict, incidents: List, tracking_stats: List, business_analytics: List, _alerts: List) -> List[str]:
|
775
833
|
"""
|
776
834
|
Generate a human_text string for the tracking_stat, incident, business analytics and alerts.
|
777
835
|
"""
|
@@ -880,8 +938,8 @@ class ProximityUseCase(BaseProcessor):
|
|
880
938
|
prediction["frame_id"] = frame_id
|
881
939
|
predictions.append(prediction)
|
882
940
|
|
883
|
-
except Exception as e:
|
884
|
-
self.logger.warning(
|
941
|
+
except Exception as e: # noqa: BLE001
|
942
|
+
self.logger.warning("Failed to extract predictions: %s", str(e))
|
885
943
|
|
886
944
|
return predictions
|
887
945
|
|
@@ -939,7 +997,9 @@ class ProximityUseCase(BaseProcessor):
|
|
939
997
|
current_frame_tracks.add(canonical_id)
|
940
998
|
|
941
999
|
# Update total track IDs with new canonical IDs from current frame
|
942
|
-
old_total_count
|
1000
|
+
# old_total_count can be used for debugging or analytics if needed
|
1001
|
+
# Keeping it for potential future use but suppressing linter warning
|
1002
|
+
old_total_count = len(self._total_track_ids) # noqa: F841
|
943
1003
|
self._total_track_ids.update(current_frame_tracks)
|
944
1004
|
self._current_frame_track_ids = current_frame_tracks
|
945
1005
|
|
@@ -952,10 +1012,12 @@ class ProximityUseCase(BaseProcessor):
|
|
952
1012
|
new_tracks = current_frame_tracks - (self._total_track_ids - current_frame_tracks)
|
953
1013
|
if new_tracks:
|
954
1014
|
self.logger.debug(
|
955
|
-
|
1015
|
+
"Tracking state updated: %s new canonical track IDs added, total unique tracks: %s",
|
1016
|
+
len(new_tracks), self._total_count)
|
956
1017
|
else:
|
957
1018
|
self.logger.debug(
|
958
|
-
|
1019
|
+
"Tracking state updated: %s current frame canonical tracks, total unique tracks: %s",
|
1020
|
+
len(current_frame_tracks), self._total_count)
|
959
1021
|
|
960
1022
|
def get_total_count(self) -> int:
|
961
1023
|
"""Get the total count of unique people tracked across all calls."""
|
@@ -972,7 +1034,7 @@ class ProximityUseCase(BaseProcessor):
|
|
972
1034
|
def set_global_frame_offset(self, offset: int) -> None:
|
973
1035
|
"""Set the global frame offset for video chunk processing."""
|
974
1036
|
self._global_frame_offset = offset
|
975
|
-
self.logger.info(
|
1037
|
+
self.logger.info("Global frame offset set to: %s", offset)
|
976
1038
|
|
977
1039
|
def get_global_frame_offset(self) -> int:
|
978
1040
|
"""Get the current global frame offset."""
|
@@ -982,7 +1044,7 @@ class ProximityUseCase(BaseProcessor):
|
|
982
1044
|
"""Update global frame offset after processing a chunk."""
|
983
1045
|
old_offset = self._global_frame_offset
|
984
1046
|
self._global_frame_offset += frames_in_chunk
|
985
|
-
self.logger.info(
|
1047
|
+
self.logger.info("Global frame offset updated: %s -> %s (added %s frames)", old_offset, self._global_frame_offset, frames_in_chunk)
|
986
1048
|
|
987
1049
|
def get_global_frame_id(self, local_frame_id: str) -> str:
|
988
1050
|
"""Convert local frame ID to global frame ID."""
|
@@ -1093,14 +1155,14 @@ class ProximityUseCase(BaseProcessor):
|
|
1093
1155
|
# Update timestamp
|
1094
1156
|
self._last_update_time = time.time()
|
1095
1157
|
|
1096
|
-
self.logger.info(
|
1158
|
+
self.logger.info("Cleared %s current frame tracks and %s zone current tracks. Cumulative total preserved: %s", old_current_count, cleared_zone_tracks, self._total_count)
|
1097
1159
|
return old_current_count
|
1098
1160
|
|
1099
1161
|
def reset_frame_counter(self) -> None:
|
1100
1162
|
"""Reset only the frame counter."""
|
1101
1163
|
old_count = self._total_frame_counter
|
1102
1164
|
self._total_frame_counter = 0
|
1103
|
-
self.logger.info(
|
1165
|
+
self.logger.info("Frame counter reset from %s to 0", old_count)
|
1104
1166
|
|
1105
1167
|
def clear_expired_tracks(self, max_age_seconds: float = 300.0) -> int:
|
1106
1168
|
"""
|
@@ -1125,7 +1187,7 @@ class ProximityUseCase(BaseProcessor):
|
|
1125
1187
|
if current_time - self._last_update_time > max_age_seconds:
|
1126
1188
|
# Use the safe method that preserves cumulative totals
|
1127
1189
|
cleared_count = self.clear_current_frame_tracking()
|
1128
|
-
self.logger.info(
|
1190
|
+
self.logger.info("Manual cleanup: cleared %s expired current frame tracks (age > %ss)", cleared_count, max_age_seconds)
|
1129
1191
|
return cleared_count
|
1130
1192
|
return 0
|
1131
1193
|
|
@@ -1267,12 +1329,12 @@ class ProximityUseCase(BaseProcessor):
|
|
1267
1329
|
return datetime.now(timezone.utc).strftime("%Y-%m-%d-%H:%M:%S.%f UTC")
|
1268
1330
|
|
1269
1331
|
if stream_info.get("input_settings", {}).get("start_frame", "na") != "na":
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1332
|
+
if frame_id:
|
1333
|
+
start_time = int(frame_id)/stream_info.get("input_settings", {}).get("original_fps", 30)
|
1334
|
+
else:
|
1335
|
+
start_time = stream_info.get("input_settings", {}).get("start_frame", 30)/stream_info.get("input_settings", {}).get("original_fps", 30)
|
1336
|
+
stream_time_str = self._format_timestamp_for_video(start_time)
|
1337
|
+
return stream_time_str
|
1276
1338
|
else:
|
1277
1339
|
# For streams, use stream_time from stream_info
|
1278
1340
|
stream_time_str = stream_info.get("input_settings", {}).get("stream_info", {}).get("stream_time", "")
|
@@ -1284,7 +1346,7 @@ class ProximityUseCase(BaseProcessor):
|
|
1284
1346
|
dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
|
1285
1347
|
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
|
1286
1348
|
return self._format_timestamp_for_stream(timestamp)
|
1287
|
-
except:
|
1349
|
+
except Exception: # noqa: BLE001
|
1288
1350
|
# Fallback to current time if parsing fails
|
1289
1351
|
return self._format_timestamp_for_stream(time.time())
|
1290
1352
|
else:
|
@@ -1316,7 +1378,7 @@ class ProximityUseCase(BaseProcessor):
|
|
1316
1378
|
timestamp_str = stream_time_str.replace(" UTC", "")
|
1317
1379
|
dt = datetime.strptime(timestamp_str, "%Y-%m-%d-%H:%M:%S.%f")
|
1318
1380
|
self._tracking_start_time = dt.replace(tzinfo=timezone.utc).timestamp()
|
1319
|
-
except:
|
1381
|
+
except Exception: # noqa: BLE001
|
1320
1382
|
# Fallback to current time if parsing fails
|
1321
1383
|
self._tracking_start_time = time.time()
|
1322
1384
|
else:
|
@@ -1450,7 +1512,7 @@ class ProximityUseCase(BaseProcessor):
|
|
1450
1512
|
info["last_update"] = now
|
1451
1513
|
info["raw_ids"].add(raw_id)
|
1452
1514
|
self.logger.debug(
|
1453
|
-
|
1515
|
+
"Merged raw track %s into canonical track %s (IoU=%.2f)", raw_id, canonical_id, iou)
|
1454
1516
|
return canonical_id
|
1455
1517
|
|
1456
1518
|
# No match found – create a new canonical track
|
@@ -1461,7 +1523,7 @@ class ProximityUseCase(BaseProcessor):
|
|
1461
1523
|
"last_update": now,
|
1462
1524
|
"raw_ids": {raw_id},
|
1463
1525
|
}
|
1464
|
-
self.logger.debug(
|
1526
|
+
self.logger.debug("Registered new canonical track %s", canonical_id)
|
1465
1527
|
return canonical_id
|
1466
1528
|
|
1467
1529
|
def _format_timestamp(self, timestamp: float) -> str:
|
@@ -1603,5 +1665,5 @@ class ProximityUseCase(BaseProcessor):
|
|
1603
1665
|
self.smoothing_tracker = BBoxSmoothingTracker(smoothing_config)
|
1604
1666
|
|
1605
1667
|
smoothed_data = bbox_smoothing(data, self.smoothing_tracker.config, self.smoothing_tracker)
|
1606
|
-
self.logger.debug(
|
1668
|
+
self.logger.debug("Applied bbox smoothing to tracking results")
|
1607
1669
|
return smoothed_data
|
@@ -204,7 +204,7 @@ matrice/deploy/utils/post_processing/usecases/plaque_segmentation_img.py,sha256=
|
|
204
204
|
matrice/deploy/utils/post_processing/usecases/pothole_segmentation.py,sha256=jXTb8ZqInp5xJ-O3Zp3zQBiryFVD0-WBbhW6Kux_NDo,44905
|
205
205
|
matrice/deploy/utils/post_processing/usecases/ppe_compliance.py,sha256=G9P9j9E9nfNJInHJxmK1Lb4daFBlG5hq0aqotTLvFFE,30146
|
206
206
|
matrice/deploy/utils/post_processing/usecases/price_tag_detection.py,sha256=09Tp6MGAHh95s-NSAp-4WC9iCc20sajWApuUBAvgXiQ,39880
|
207
|
-
matrice/deploy/utils/post_processing/usecases/proximity_detection.py,sha256=
|
207
|
+
matrice/deploy/utils/post_processing/usecases/proximity_detection.py,sha256=HjUZMKZHAgpD_YiyTXFAoaO4awF_QkY9oflCIVFlsiM,81157
|
208
208
|
matrice/deploy/utils/post_processing/usecases/road_lane_detection.py,sha256=V_KxwBtAHSNkyoH8sXw-U-P3J8ToXtX3ncc69gn6Tds,31591
|
209
209
|
matrice/deploy/utils/post_processing/usecases/road_traffic_density.py,sha256=YiHQ0kKhXglagHPvygywxMqZAw8s0WharrBQqLQj2q4,40311
|
210
210
|
matrice/deploy/utils/post_processing/usecases/road_view_segmentation.py,sha256=BcBbOOg5622KuvzKrzs9cJW1wkRoIIcOab0N7BONQKQ,44986
|
@@ -243,8 +243,8 @@ matrice/deployment/camera_manager.py,sha256=e1Lc81RJP5wUWRdTgHO6tMWF9BkBdHOSVyx3
|
|
243
243
|
matrice/deployment/deployment.py,sha256=HFt151eWq6iqIAMsQvurpV2WNxW6Cx_gIUVfnVy5SWE,48093
|
244
244
|
matrice/deployment/inference_pipeline.py,sha256=6b4Mm3-qt-Zy0BeiJfFQdImOn3FzdNCY-7ET7Rp8PMk,37911
|
245
245
|
matrice/deployment/streaming_gateway_manager.py,sha256=ifYGl3g25wyU39HwhPQyI2OgF3M6oIqKMWt8RXtMxY8,21401
|
246
|
-
matrice-1.0.
|
247
|
-
matrice-1.0.
|
248
|
-
matrice-1.0.
|
249
|
-
matrice-1.0.
|
250
|
-
matrice-1.0.
|
246
|
+
matrice-1.0.99268.dist-info/licenses/LICENSE.txt,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
|
247
|
+
matrice-1.0.99268.dist-info/METADATA,sha256=aU45pkw_HtMNp9C-mI1pSRKXVAI9djwHr1UCaRvpbCA,14624
|
248
|
+
matrice-1.0.99268.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
249
|
+
matrice-1.0.99268.dist-info/top_level.txt,sha256=P97js8ur6o5ClRqMH3Cjoab_NqbJ6sOQ3rJmVzKBvMc,8
|
250
|
+
matrice-1.0.99268.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|