matrice-analytics 0.1.60__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_analytics/__init__.py +28 -0
- matrice_analytics/boundary_drawing_internal/README.md +305 -0
- matrice_analytics/boundary_drawing_internal/__init__.py +45 -0
- matrice_analytics/boundary_drawing_internal/boundary_drawing_internal.py +1207 -0
- matrice_analytics/boundary_drawing_internal/boundary_drawing_tool.py +429 -0
- matrice_analytics/boundary_drawing_internal/boundary_tool_template.html +1036 -0
- matrice_analytics/boundary_drawing_internal/data/.gitignore +12 -0
- matrice_analytics/boundary_drawing_internal/example_usage.py +206 -0
- matrice_analytics/boundary_drawing_internal/usage/README.md +110 -0
- matrice_analytics/boundary_drawing_internal/usage/boundary_drawer_launcher.py +102 -0
- matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py +107 -0
- matrice_analytics/post_processing/README.md +455 -0
- matrice_analytics/post_processing/__init__.py +732 -0
- matrice_analytics/post_processing/advanced_tracker/README.md +650 -0
- matrice_analytics/post_processing/advanced_tracker/__init__.py +17 -0
- matrice_analytics/post_processing/advanced_tracker/base.py +99 -0
- matrice_analytics/post_processing/advanced_tracker/config.py +77 -0
- matrice_analytics/post_processing/advanced_tracker/kalman_filter.py +370 -0
- matrice_analytics/post_processing/advanced_tracker/matching.py +195 -0
- matrice_analytics/post_processing/advanced_tracker/strack.py +230 -0
- matrice_analytics/post_processing/advanced_tracker/tracker.py +367 -0
- matrice_analytics/post_processing/config.py +146 -0
- matrice_analytics/post_processing/core/__init__.py +63 -0
- matrice_analytics/post_processing/core/base.py +704 -0
- matrice_analytics/post_processing/core/config.py +3291 -0
- matrice_analytics/post_processing/core/config_utils.py +925 -0
- matrice_analytics/post_processing/face_reg/__init__.py +43 -0
- matrice_analytics/post_processing/face_reg/compare_similarity.py +556 -0
- matrice_analytics/post_processing/face_reg/embedding_manager.py +950 -0
- matrice_analytics/post_processing/face_reg/face_recognition.py +2234 -0
- matrice_analytics/post_processing/face_reg/face_recognition_client.py +606 -0
- matrice_analytics/post_processing/face_reg/people_activity_logging.py +321 -0
- matrice_analytics/post_processing/ocr/__init__.py +0 -0
- matrice_analytics/post_processing/ocr/easyocr_extractor.py +250 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/__init__.py +9 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/__init__.py +4 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/cli.py +33 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/dataset_stats.py +139 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/export.py +398 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/train.py +447 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/utils.py +129 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/valid.py +93 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/validate_dataset.py +240 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_augmentation.py +176 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_predictions.py +96 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/__init__.py +3 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/process.py +246 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/types.py +60 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/utils.py +87 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/__init__.py +3 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/config.py +82 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/hub.py +141 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/plate_recognizer.py +323 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/py.typed +0 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/__init__.py +0 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/__init__.py +0 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/augmentation.py +101 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/dataset.py +97 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/__init__.py +0 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/config.py +114 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/layers.py +553 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/loss.py +55 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/metric.py +86 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_builders.py +95 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_schema.py +395 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/__init__.py +0 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/backend_utils.py +38 -0
- matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/utils.py +214 -0
- matrice_analytics/post_processing/ocr/postprocessing.py +270 -0
- matrice_analytics/post_processing/ocr/preprocessing.py +52 -0
- matrice_analytics/post_processing/post_processor.py +1175 -0
- matrice_analytics/post_processing/test_cases/__init__.py +1 -0
- matrice_analytics/post_processing/test_cases/run_tests.py +143 -0
- matrice_analytics/post_processing/test_cases/test_advanced_customer_service.py +841 -0
- matrice_analytics/post_processing/test_cases/test_basic_counting_tracking.py +523 -0
- matrice_analytics/post_processing/test_cases/test_comprehensive.py +531 -0
- matrice_analytics/post_processing/test_cases/test_config.py +852 -0
- matrice_analytics/post_processing/test_cases/test_customer_service.py +585 -0
- matrice_analytics/post_processing/test_cases/test_data_generators.py +583 -0
- matrice_analytics/post_processing/test_cases/test_people_counting.py +510 -0
- matrice_analytics/post_processing/test_cases/test_processor.py +524 -0
- matrice_analytics/post_processing/test_cases/test_usecases.py +165 -0
- matrice_analytics/post_processing/test_cases/test_utilities.py +356 -0
- matrice_analytics/post_processing/test_cases/test_utils.py +743 -0
- matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py +604 -0
- matrice_analytics/post_processing/usecases/__init__.py +267 -0
- matrice_analytics/post_processing/usecases/abandoned_object_detection.py +797 -0
- matrice_analytics/post_processing/usecases/advanced_customer_service.py +1601 -0
- matrice_analytics/post_processing/usecases/age_detection.py +842 -0
- matrice_analytics/post_processing/usecases/age_gender_detection.py +1085 -0
- matrice_analytics/post_processing/usecases/anti_spoofing_detection.py +656 -0
- matrice_analytics/post_processing/usecases/assembly_line_detection.py +841 -0
- matrice_analytics/post_processing/usecases/banana_defect_detection.py +624 -0
- matrice_analytics/post_processing/usecases/basic_counting_tracking.py +667 -0
- matrice_analytics/post_processing/usecases/blood_cancer_detection_img.py +881 -0
- matrice_analytics/post_processing/usecases/car_damage_detection.py +834 -0
- matrice_analytics/post_processing/usecases/car_part_segmentation.py +946 -0
- matrice_analytics/post_processing/usecases/car_service.py +1601 -0
- matrice_analytics/post_processing/usecases/cardiomegaly_classification.py +864 -0
- matrice_analytics/post_processing/usecases/cell_microscopy_segmentation.py +897 -0
- matrice_analytics/post_processing/usecases/chicken_pose_detection.py +648 -0
- matrice_analytics/post_processing/usecases/child_monitoring.py +814 -0
- matrice_analytics/post_processing/usecases/color/clip.py +660 -0
- matrice_analytics/post_processing/usecases/color/clip_processor/merges.txt +48895 -0
- matrice_analytics/post_processing/usecases/color/clip_processor/preprocessor_config.json +28 -0
- matrice_analytics/post_processing/usecases/color/clip_processor/special_tokens_map.json +30 -0
- matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer.json +245079 -0
- matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer_config.json +32 -0
- matrice_analytics/post_processing/usecases/color/clip_processor/vocab.json +1 -0
- matrice_analytics/post_processing/usecases/color/color_map_utils.py +70 -0
- matrice_analytics/post_processing/usecases/color/color_mapper.py +468 -0
- matrice_analytics/post_processing/usecases/color_detection.py +1936 -0
- matrice_analytics/post_processing/usecases/color_map_utils.py +70 -0
- matrice_analytics/post_processing/usecases/concrete_crack_detection.py +827 -0
- matrice_analytics/post_processing/usecases/crop_weed_detection.py +781 -0
- matrice_analytics/post_processing/usecases/customer_service.py +1008 -0
- matrice_analytics/post_processing/usecases/defect_detection_products.py +936 -0
- matrice_analytics/post_processing/usecases/distracted_driver_detection.py +822 -0
- matrice_analytics/post_processing/usecases/drone_traffic_monitoring.py +585 -0
- matrice_analytics/post_processing/usecases/drowsy_driver_detection.py +829 -0
- matrice_analytics/post_processing/usecases/dwell_detection.py +829 -0
- matrice_analytics/post_processing/usecases/emergency_vehicle_detection.py +827 -0
- matrice_analytics/post_processing/usecases/face_emotion.py +813 -0
- matrice_analytics/post_processing/usecases/face_recognition.py +827 -0
- matrice_analytics/post_processing/usecases/fashion_detection.py +835 -0
- matrice_analytics/post_processing/usecases/field_mapping.py +902 -0
- matrice_analytics/post_processing/usecases/fire_detection.py +1146 -0
- matrice_analytics/post_processing/usecases/flare_analysis.py +836 -0
- matrice_analytics/post_processing/usecases/flower_segmentation.py +1006 -0
- matrice_analytics/post_processing/usecases/gas_leak_detection.py +837 -0
- matrice_analytics/post_processing/usecases/gender_detection.py +832 -0
- matrice_analytics/post_processing/usecases/human_activity_recognition.py +871 -0
- matrice_analytics/post_processing/usecases/intrusion_detection.py +1672 -0
- matrice_analytics/post_processing/usecases/leaf.py +821 -0
- matrice_analytics/post_processing/usecases/leaf_disease.py +840 -0
- matrice_analytics/post_processing/usecases/leak_detection.py +837 -0
- matrice_analytics/post_processing/usecases/license_plate_detection.py +1188 -0
- matrice_analytics/post_processing/usecases/license_plate_monitoring.py +1781 -0
- matrice_analytics/post_processing/usecases/litter_monitoring.py +717 -0
- matrice_analytics/post_processing/usecases/mask_detection.py +869 -0
- matrice_analytics/post_processing/usecases/natural_disaster.py +907 -0
- matrice_analytics/post_processing/usecases/parking.py +787 -0
- matrice_analytics/post_processing/usecases/parking_space_detection.py +822 -0
- matrice_analytics/post_processing/usecases/pcb_defect_detection.py +888 -0
- matrice_analytics/post_processing/usecases/pedestrian_detection.py +808 -0
- matrice_analytics/post_processing/usecases/people_counting.py +706 -0
- matrice_analytics/post_processing/usecases/people_counting_bckp.py +1683 -0
- matrice_analytics/post_processing/usecases/people_tracking.py +1842 -0
- matrice_analytics/post_processing/usecases/pipeline_detection.py +605 -0
- matrice_analytics/post_processing/usecases/plaque_segmentation_img.py +874 -0
- matrice_analytics/post_processing/usecases/pothole_segmentation.py +915 -0
- matrice_analytics/post_processing/usecases/ppe_compliance.py +645 -0
- matrice_analytics/post_processing/usecases/price_tag_detection.py +822 -0
- matrice_analytics/post_processing/usecases/proximity_detection.py +1901 -0
- matrice_analytics/post_processing/usecases/road_lane_detection.py +623 -0
- matrice_analytics/post_processing/usecases/road_traffic_density.py +832 -0
- matrice_analytics/post_processing/usecases/road_view_segmentation.py +915 -0
- matrice_analytics/post_processing/usecases/shelf_inventory_detection.py +583 -0
- matrice_analytics/post_processing/usecases/shoplifting_detection.py +822 -0
- matrice_analytics/post_processing/usecases/shopping_cart_analysis.py +899 -0
- matrice_analytics/post_processing/usecases/skin_cancer_classification_img.py +864 -0
- matrice_analytics/post_processing/usecases/smoker_detection.py +833 -0
- matrice_analytics/post_processing/usecases/solar_panel.py +810 -0
- matrice_analytics/post_processing/usecases/suspicious_activity_detection.py +1030 -0
- matrice_analytics/post_processing/usecases/template_usecase.py +380 -0
- matrice_analytics/post_processing/usecases/theft_detection.py +648 -0
- matrice_analytics/post_processing/usecases/traffic_sign_monitoring.py +724 -0
- matrice_analytics/post_processing/usecases/underground_pipeline_defect_detection.py +775 -0
- matrice_analytics/post_processing/usecases/underwater_pollution_detection.py +842 -0
- matrice_analytics/post_processing/usecases/vehicle_monitoring.py +1029 -0
- matrice_analytics/post_processing/usecases/warehouse_object_segmentation.py +899 -0
- matrice_analytics/post_processing/usecases/waterbody_segmentation.py +923 -0
- matrice_analytics/post_processing/usecases/weapon_detection.py +771 -0
- matrice_analytics/post_processing/usecases/weld_defect_detection.py +615 -0
- matrice_analytics/post_processing/usecases/wildlife_monitoring.py +898 -0
- matrice_analytics/post_processing/usecases/windmill_maintenance.py +834 -0
- matrice_analytics/post_processing/usecases/wound_segmentation.py +856 -0
- matrice_analytics/post_processing/utils/__init__.py +150 -0
- matrice_analytics/post_processing/utils/advanced_counting_utils.py +400 -0
- matrice_analytics/post_processing/utils/advanced_helper_utils.py +317 -0
- matrice_analytics/post_processing/utils/advanced_tracking_utils.py +461 -0
- matrice_analytics/post_processing/utils/alerting_utils.py +213 -0
- matrice_analytics/post_processing/utils/category_mapping_utils.py +94 -0
- matrice_analytics/post_processing/utils/color_utils.py +592 -0
- matrice_analytics/post_processing/utils/counting_utils.py +182 -0
- matrice_analytics/post_processing/utils/filter_utils.py +261 -0
- matrice_analytics/post_processing/utils/format_utils.py +293 -0
- matrice_analytics/post_processing/utils/geometry_utils.py +300 -0
- matrice_analytics/post_processing/utils/smoothing_utils.py +358 -0
- matrice_analytics/post_processing/utils/tracking_utils.py +234 -0
- matrice_analytics/py.typed +0 -0
- matrice_analytics-0.1.60.dist-info/METADATA +481 -0
- matrice_analytics-0.1.60.dist-info/RECORD +196 -0
- matrice_analytics-0.1.60.dist-info/WHEEL +5 -0
- matrice_analytics-0.1.60.dist-info/licenses/LICENSE.txt +21 -0
- matrice_analytics-0.1.60.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
# Advanced Tracker Integration Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to integrate the `AdvancedTracker` into any post-processing use case to enable object tracking capabilities.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `AdvancedTracker` is a BYTETracker-inspired implementation that can be added to any use case to convert raw detection results into tracking results. This enables persistent object identification across frames and improves downstream processing accuracy.
|
|
8
|
+
|
|
9
|
+
## Quick Integration
|
|
10
|
+
|
|
11
|
+
### 1. Import the Tracker
|
|
12
|
+
|
|
13
|
+
Add this import to your use case file:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from ..advanced_tracker import AdvancedTracker, TrackerConfig
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 2. Initialize the Tracker
|
|
20
|
+
|
|
21
|
+
In your use case class `__init__` method:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
def __init__(self):
|
|
25
|
+
super().__init__("your_use_case_name")
|
|
26
|
+
self.category = "your_category"
|
|
27
|
+
|
|
28
|
+
# Initialize the tracker
|
|
29
|
+
self.tracker = AdvancedTracker(TrackerConfig())
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 3. Apply Tracking in Process Method
|
|
33
|
+
|
|
34
|
+
In your `process` method, **before** any other processing:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
def process(self, data, config, context=None, stream_info=None):
|
|
38
|
+
# Apply tracking to raw detections
|
|
39
|
+
tracking_results = self.tracker.update(data)
|
|
40
|
+
|
|
41
|
+
# Continue with your existing processing logic using tracking_results
|
|
42
|
+
# instead of the original data
|
|
43
|
+
return self._process_tracking_results(tracking_results, config, context)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Configuration Parameters
|
|
47
|
+
|
|
48
|
+
The `TrackerConfig` class provides several parameters to customize tracking behavior:
|
|
49
|
+
|
|
50
|
+
### Core Tracking Parameters
|
|
51
|
+
|
|
52
|
+
| Parameter | Type | Default | Description |
|
|
53
|
+
|-----------|------|---------|-------------|
|
|
54
|
+
| `track_high_thresh` | float | 0.6 | High confidence threshold for primary association |
|
|
55
|
+
| `track_low_thresh` | float | 0.1 | Low confidence threshold for secondary association |
|
|
56
|
+
| `new_track_thresh` | float | 0.7 | Minimum confidence to create new tracks |
|
|
57
|
+
| `match_thresh` | float | 0.8 | IoU threshold for track-detection matching |
|
|
58
|
+
|
|
59
|
+
### Buffer and Timing Parameters
|
|
60
|
+
|
|
61
|
+
| Parameter | Type | Default | Description |
|
|
62
|
+
|-----------|------|---------|-------------|
|
|
63
|
+
| `track_buffer` | int | 30 | Number of frames to keep lost tracks |
|
|
64
|
+
| `max_time_lost` | int | 30 | Maximum frames before removing lost tracks |
|
|
65
|
+
| `frame_rate` | int | 30 | Video frame rate (used for timing calculations) |
|
|
66
|
+
|
|
67
|
+
### Algorithm Settings
|
|
68
|
+
|
|
69
|
+
| Parameter | Type | Default | Description |
|
|
70
|
+
|-----------|------|---------|-------------|
|
|
71
|
+
| `fuse_score` | bool | True | Fuse IoU distance with detection scores |
|
|
72
|
+
| `enable_gmc` | bool | True | Enable Generalized Motion Compensation |
|
|
73
|
+
| `gmc_method` | str | "sparseOptFlow" | GMC method: "orb", "sift", "ecc", "sparseOptFlow", "none" |
|
|
74
|
+
| `gmc_downscale` | int | 2 | Downscale factor for GMC processing |
|
|
75
|
+
|
|
76
|
+
### Output Format Settings
|
|
77
|
+
|
|
78
|
+
| Parameter | Type | Default | Description |
|
|
79
|
+
|-----------|------|---------|-------------|
|
|
80
|
+
| `output_format` | str | "tracking" | Output format: "tracking" or "detection" |
|
|
81
|
+
|
|
82
|
+
### Smoothing Parameters
|
|
83
|
+
|
|
84
|
+
| Parameter | Type | Default | Description |
|
|
85
|
+
|-----------|------|---------|-------------|
|
|
86
|
+
| `enable_smoothing` | bool | True | Enable bounding box smoothing |
|
|
87
|
+
| `smoothing_algorithm` | str | "observability" | Smoothing algorithm: "window" or "observability" |
|
|
88
|
+
| `smoothing_window_size` | int | 20 | Window size for smoothing |
|
|
89
|
+
| `smoothing_cooldown_frames` | int | 5 | Cooldown frames for smoothing |
|
|
90
|
+
|
|
91
|
+
## Example Configurations
|
|
92
|
+
|
|
93
|
+
### High-Precision Tracking
|
|
94
|
+
```python
|
|
95
|
+
config = TrackerConfig(
|
|
96
|
+
track_high_thresh=0.8,
|
|
97
|
+
track_low_thresh=0.3,
|
|
98
|
+
new_track_thresh=0.9,
|
|
99
|
+
match_thresh=0.9,
|
|
100
|
+
track_buffer=50,
|
|
101
|
+
fuse_score=True
|
|
102
|
+
)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Real-Time Tracking
|
|
106
|
+
```python
|
|
107
|
+
config = TrackerConfig(
|
|
108
|
+
track_high_thresh=0.4,
|
|
109
|
+
track_low_thresh=0.1,
|
|
110
|
+
new_track_thresh=0.5,
|
|
111
|
+
match_thresh=0.6,
|
|
112
|
+
track_buffer=20,
|
|
113
|
+
enable_gmc=False, # Disable for speed
|
|
114
|
+
fuse_score=False # Disable for speed
|
|
115
|
+
)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Robust Tracking (for noisy detections)
|
|
119
|
+
```python
|
|
120
|
+
config = TrackerConfig(
|
|
121
|
+
track_high_thresh=0.3,
|
|
122
|
+
track_low_thresh=0.05,
|
|
123
|
+
new_track_thresh=0.4,
|
|
124
|
+
match_thresh=0.5,
|
|
125
|
+
track_buffer=60,
|
|
126
|
+
enable_smoothing=True,
|
|
127
|
+
smoothing_algorithm="observability",
|
|
128
|
+
smoothing_window_size=30
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Input/Output Formats
|
|
133
|
+
|
|
134
|
+
The `AdvancedTracker` accepts various input formats and returns the same format with additional tracking information. The tracker automatically detects the input format and returns results in the corresponding format.
|
|
135
|
+
|
|
136
|
+
### Input Format Structures
|
|
137
|
+
|
|
138
|
+
#### 1. Single Frame Detection (List[Dict])
|
|
139
|
+
|
|
140
|
+
**Format:** List of detection dictionaries for a single frame
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
# Input: Single frame detections
|
|
144
|
+
detections = [
|
|
145
|
+
{
|
|
146
|
+
"bounding_box": {"xmin": 100, "ymin": 200, "xmax": 150, "ymax": 280},
|
|
147
|
+
"confidence": 0.85,
|
|
148
|
+
"category": "person"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"bounding_box": {"x": 175, "y": 275, "width": 50, "height": 80}, # Center format
|
|
152
|
+
"confidence": 0.92,
|
|
153
|
+
"category": "car"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"bounding_box": {"x1": 250, "y1": 300, "x2": 300, "y2": 380}, # Alternative format
|
|
157
|
+
"confidence": 0.78,
|
|
158
|
+
"category": "bicycle"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Output:** Same list with added tracking fields
|
|
164
|
+
```python
|
|
165
|
+
# Output: Single frame with tracking info
|
|
166
|
+
tracking_results = [
|
|
167
|
+
{
|
|
168
|
+
"bounding_box": {"xmin": 98, "ymin": 198, "xmax": 148, "ymax": 278},
|
|
169
|
+
"confidence": 0.85,
|
|
170
|
+
"category": "person",
|
|
171
|
+
"track_id": 1, # ← ADDED: Unique track identifier
|
|
172
|
+
"frame_id": 1 # ← ADDED: Current frame number
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"bounding_box": {"xmin": 172, "ymin": 272, "xmax": 222, "ymax": 352},
|
|
176
|
+
"confidence": 0.92,
|
|
177
|
+
"category": "car",
|
|
178
|
+
"track_id": 2, # ← ADDED: Unique track identifier
|
|
179
|
+
"frame_id": 1 # ← ADDED: Current frame number
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"bounding_box": {"xmin": 250, "ymin": 300, "xmax": 300, "ymax": 380},
|
|
183
|
+
"confidence": 0.78,
|
|
184
|
+
"category": "bicycle",
|
|
185
|
+
"track_id": 3, # ← ADDED: Unique track identifier
|
|
186
|
+
"frame_id": 1 # ← ADDED: Current frame number
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### 2. Multi-Frame Detection (Dict[str, List[Dict]])
|
|
192
|
+
|
|
193
|
+
**Format:** Dictionary with frame keys and detection lists
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# Input: Multi-frame detections
|
|
197
|
+
detections = {
|
|
198
|
+
"frame_1": [
|
|
199
|
+
{
|
|
200
|
+
"bounding_box": {"xmin": 100, "ymin": 200, "xmax": 150, "ymax": 280},
|
|
201
|
+
"confidence": 0.85,
|
|
202
|
+
"category": "person"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"bounding_box": {"xmin": 175, "ymin": 275, "xmax": 225, "ymax": 355},
|
|
206
|
+
"confidence": 0.92,
|
|
207
|
+
"category": "car"
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
"frame_2": [
|
|
211
|
+
{
|
|
212
|
+
"bounding_box": {"xmin": 105, "ymin": 205, "xmax": 155, "ymax": 285},
|
|
213
|
+
"confidence": 0.87,
|
|
214
|
+
"category": "person"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"bounding_box": {"xmin": 180, "ymin": 280, "xmax": 230, "ymax": 360},
|
|
218
|
+
"confidence": 0.89,
|
|
219
|
+
"category": "car"
|
|
220
|
+
}
|
|
221
|
+
],
|
|
222
|
+
"frame_3": [
|
|
223
|
+
{
|
|
224
|
+
"bounding_box": {"xmin": 110, "ymin": 210, "xmax": 160, "ymax": 290},
|
|
225
|
+
"confidence": 0.86,
|
|
226
|
+
"category": "person"
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Output:** Same dictionary structure with tracking info
|
|
233
|
+
```python
|
|
234
|
+
# Output: Multi-frame with tracking info
|
|
235
|
+
tracking_results = {
|
|
236
|
+
"frame_1": [
|
|
237
|
+
{
|
|
238
|
+
"bounding_box": {"xmin": 100, "ymin": 200, "xmax": 150, "ymax": 280},
|
|
239
|
+
"confidence": 0.85,
|
|
240
|
+
"category": "person",
|
|
241
|
+
"track_id": 1, # ← ADDED: Same track ID across frames
|
|
242
|
+
"frame_id": 1 # ← ADDED: Frame number
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"bounding_box": {"xmin": 175, "ymin": 275, "xmax": 225, "ymax": 355},
|
|
246
|
+
"confidence": 0.92,
|
|
247
|
+
"category": "car",
|
|
248
|
+
"track_id": 2, # ← ADDED: Same track ID across frames
|
|
249
|
+
"frame_id": 1 # ← ADDED: Frame number
|
|
250
|
+
}
|
|
251
|
+
],
|
|
252
|
+
"frame_2": [
|
|
253
|
+
{
|
|
254
|
+
"bounding_box": {"xmin": 105, "ymin": 205, "xmax": 155, "ymax": 285},
|
|
255
|
+
"confidence": 0.87,
|
|
256
|
+
"category": "person",
|
|
257
|
+
"track_id": 1, # ← ADDED: Same track ID (person from frame_1)
|
|
258
|
+
"frame_id": 2 # ← ADDED: Frame number
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"bounding_box": {"xmin": 180, "ymin": 280, "xmax": 230, "ymax": 360},
|
|
262
|
+
"confidence": 0.89,
|
|
263
|
+
"category": "car",
|
|
264
|
+
"track_id": 2, # ← ADDED: Same track ID (car from frame_1)
|
|
265
|
+
"frame_id": 2 # ← ADDED: Frame number
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
"frame_3": [
|
|
269
|
+
{
|
|
270
|
+
"bounding_box": {"xmin": 110, "ymin": 210, "xmax": 160, "ymax": 290},
|
|
271
|
+
"confidence": 0.86,
|
|
272
|
+
"category": "person",
|
|
273
|
+
"track_id": 1, # ← ADDED: Same track ID (person from previous frames)
|
|
274
|
+
"frame_id": 3 # ← ADDED: Frame number
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### 3. Supported Bounding Box Formats
|
|
281
|
+
|
|
282
|
+
The tracker automatically detects and converts between different bounding box formats:
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
# Format 1: Corner coordinates (xmin, ymin, xmax, ymax)
|
|
286
|
+
{
|
|
287
|
+
"bounding_box": {"xmin": 100, "ymin": 200, "xmax": 150, "ymax": 280}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
# Format 2: Center coordinates (x, y, width, height)
|
|
291
|
+
{
|
|
292
|
+
"bounding_box": {"x": 125, "y": 240, "width": 50, "height": 80}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
# Format 3: Alternative corner format (x1, y1, x2, y2)
|
|
296
|
+
{
|
|
297
|
+
"bounding_box": {"x1": 100, "y1": 200, "x2": 150, "y2": 280}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
# Format 4: List format [xmin, ymin, xmax, ymax]
|
|
301
|
+
{
|
|
302
|
+
"bounding_box": [100, 200, 150, 280]
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Note:** The tracker always returns bounding boxes in `{"xmin": ..., "ymin": ..., "xmax": ..., "ymax": ...}` format.
|
|
307
|
+
|
|
308
|
+
#### 4. Required and Optional Fields
|
|
309
|
+
|
|
310
|
+
**Required Fields:**
|
|
311
|
+
- `bounding_box`: Bounding box coordinates (any supported format)
|
|
312
|
+
- `confidence`: Detection confidence score (float, 0.0-1.0)
|
|
313
|
+
- `category`: Object category/class (string)
|
|
314
|
+
|
|
315
|
+
**Optional Fields:**
|
|
316
|
+
- `features`: Feature vector for tracking (numpy array)
|
|
317
|
+
- `score`: Alternative to `confidence` (float)
|
|
318
|
+
- `class`: Alternative to `category` (string)
|
|
319
|
+
|
|
320
|
+
**Added Fields (Output Only):**
|
|
321
|
+
- `track_id`: Unique identifier for the tracked object (int)
|
|
322
|
+
- `frame_id`: Current frame number (int)
|
|
323
|
+
|
|
324
|
+
### Complete Input/Output Examples
|
|
325
|
+
|
|
326
|
+
#### Example 1: People Detection
|
|
327
|
+
```python
|
|
328
|
+
# Input
|
|
329
|
+
people_detections = [
|
|
330
|
+
{
|
|
331
|
+
"bounding_box": {"xmin": 50, "ymin": 100, "xmax": 120, "ymax": 200},
|
|
332
|
+
"confidence": 0.95,
|
|
333
|
+
"category": "person"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"bounding_box": {"xmin": 200, "ymin": 150, "xmax": 280, "ymax": 250},
|
|
337
|
+
"confidence": 0.88,
|
|
338
|
+
"category": "person"
|
|
339
|
+
}
|
|
340
|
+
]
|
|
341
|
+
|
|
342
|
+
# Output
|
|
343
|
+
tracked_people = [
|
|
344
|
+
{
|
|
345
|
+
"bounding_box": {"xmin": 50, "ymin": 100, "xmax": 120, "ymax": 200},
|
|
346
|
+
"confidence": 0.95,
|
|
347
|
+
"category": "person",
|
|
348
|
+
"track_id": 1,
|
|
349
|
+
"frame_id": 1
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"bounding_box": {"xmin": 200, "ymin": 150, "xmax": 280, "ymax": 250},
|
|
353
|
+
"confidence": 0.88,
|
|
354
|
+
"category": "person",
|
|
355
|
+
"track_id": 2,
|
|
356
|
+
"frame_id": 1
|
|
357
|
+
}
|
|
358
|
+
]
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
#### Example 2: Vehicle Tracking Across Frames
|
|
362
|
+
```python
|
|
363
|
+
# Input: Frame 1
|
|
364
|
+
frame1_detections = {
|
|
365
|
+
"frame_001": [
|
|
366
|
+
{"bounding_box": {"xmin": 100, "ymin": 200, "xmax": 180, "ymax": 280}, "confidence": 0.92, "category": "car"},
|
|
367
|
+
{"bounding_box": {"xmin": 300, "ymin": 250, "xmax": 380, "ymax": 330}, "confidence": 0.85, "category": "truck"}
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
# Output: Frame 1
|
|
372
|
+
frame1_tracked = {
|
|
373
|
+
"frame_001": [
|
|
374
|
+
{"bounding_box": {"xmin": 100, "ymin": 200, "xmax": 180, "ymax": 280}, "confidence": 0.92, "category": "car", "track_id": 1, "frame_id": 1},
|
|
375
|
+
{"bounding_box": {"xmin": 300, "ymin": 250, "xmax": 380, "ymax": 330}, "confidence": 0.85, "category": "truck", "track_id": 2, "frame_id": 1}
|
|
376
|
+
]
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
# Input: Frame 2 (same vehicles, moved positions)
|
|
380
|
+
frame2_detections = {
|
|
381
|
+
"frame_002": [
|
|
382
|
+
{"bounding_box": {"xmin": 110, "ymin": 210, "xmax": 190, "ymax": 290}, "confidence": 0.90, "category": "car"},
|
|
383
|
+
{"bounding_box": {"xmin": 310, "ymin": 260, "xmax": 390, "ymax": 340}, "confidence": 0.87, "category": "truck"}
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
# Output: Frame 2 (same track IDs maintained)
|
|
388
|
+
frame2_tracked = {
|
|
389
|
+
"frame_002": [
|
|
390
|
+
{"bounding_box": {"xmin": 110, "ymin": 210, "xmax": 190, "ymax": 290}, "confidence": 0.90, "category": "car", "track_id": 1, "frame_id": 2},
|
|
391
|
+
{"bounding_box": {"xmin": 310, "ymin": 260, "xmax": 390, "ymax": 340}, "confidence": 0.87, "category": "truck", "track_id": 2, "frame_id": 2}
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
#### Example 3: Mixed Categories
|
|
397
|
+
```python
|
|
398
|
+
# Input: Mixed object types
|
|
399
|
+
mixed_detections = [
|
|
400
|
+
{"bounding_box": {"x": 100, "y": 150, "width": 60, "height": 120}, "confidence": 0.95, "category": "person"},
|
|
401
|
+
{"bounding_box": {"xmin": 200, "ymin": 200, "xmax": 280, "ymax": 280}, "confidence": 0.88, "category": "car"},
|
|
402
|
+
{"bounding_box": [300, 250, 350, 320], "confidence": 0.92, "category": "bicycle"}
|
|
403
|
+
]
|
|
404
|
+
|
|
405
|
+
# Output: All converted to standard format with tracking
|
|
406
|
+
mixed_tracked = [
|
|
407
|
+
{"bounding_box": {"xmin": 70, "ymin": 90, "xmax": 130, "ymax": 210}, "confidence": 0.95, "category": "person", "track_id": 1, "frame_id": 1},
|
|
408
|
+
{"bounding_box": {"xmin": 200, "ymin": 200, "xmax": 280, "ymax": 280}, "confidence": 0.88, "category": "car", "track_id": 2, "frame_id": 1},
|
|
409
|
+
{"bounding_box": {"xmin": 300, "ymin": 250, "xmax": 350, "ymax": 320}, "confidence": 0.92, "category": "bicycle", "track_id": 3, "frame_id": 1}
|
|
410
|
+
]
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Key Features of Input/Output Format
|
|
414
|
+
|
|
415
|
+
1. **Format Preservation**: Output format matches input format exactly
|
|
416
|
+
2. **Automatic Conversion**: Supports multiple bounding box formats
|
|
417
|
+
3. **Track ID Consistency**: Same objects get same track IDs across frames
|
|
418
|
+
4. **Frame ID Addition**: Each detection gets a frame ID
|
|
419
|
+
5. **Standardized Output**: All bounding boxes converted to xmin/ymin/xmax/ymax format
|
|
420
|
+
|
|
421
|
+
## State Preservation Implementation
|
|
422
|
+
|
|
423
|
+
### ⚠️ Important: Preserving Tracker State
|
|
424
|
+
|
|
425
|
+
The `AdvancedTracker` maintains state across multiple frames to enable persistent object tracking. **It's crucial to preserve the tracker instance** rather than creating a new one for each frame.
|
|
426
|
+
|
|
427
|
+
### Correct Implementation Pattern
|
|
428
|
+
|
|
429
|
+
```python
|
|
430
|
+
class YourUseCase(BaseProcessor):
|
|
431
|
+
def __init__(self):
|
|
432
|
+
super().__init__("your_use_case_name")
|
|
433
|
+
self.category = "your_category"
|
|
434
|
+
|
|
435
|
+
# Initialize tracker as None - will be created on first use
|
|
436
|
+
self.tracker = None
|
|
437
|
+
|
|
438
|
+
def process(self, data, config, context=None, stream_info=None):
|
|
439
|
+
# Create tracker instance if it doesn't exist (preserves state across frames)
|
|
440
|
+
if self.tracker is None:
|
|
441
|
+
from ..advanced_tracker import AdvancedTracker, TrackerConfig
|
|
442
|
+
tracker_config = TrackerConfig()
|
|
443
|
+
self.tracker = AdvancedTracker(tracker_config)
|
|
444
|
+
self.logger.info("Initialized AdvancedTracker for tracking")
|
|
445
|
+
|
|
446
|
+
# Apply tracking (same instance used across frames)
|
|
447
|
+
tracking_results = self.tracker.update(data)
|
|
448
|
+
|
|
449
|
+
# Continue with your processing logic
|
|
450
|
+
return self._process_results(tracking_results, config, context)
|
|
451
|
+
|
|
452
|
+
def reset_tracker(self) -> None:
|
|
453
|
+
"""
|
|
454
|
+
Reset the tracker instance when needed.
|
|
455
|
+
|
|
456
|
+
Call this when:
|
|
457
|
+
- Starting a completely new tracking session
|
|
458
|
+
- Switching to a different video/stream
|
|
459
|
+
- Manual reset requested by user
|
|
460
|
+
"""
|
|
461
|
+
if self.tracker is not None:
|
|
462
|
+
self.tracker.reset()
|
|
463
|
+
self.logger.info("AdvancedTracker reset for new tracking session")
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### ❌ Incorrect Implementation (Don't Do This)
|
|
467
|
+
|
|
468
|
+
```python
|
|
469
|
+
def process(self, data, config, context=None):
|
|
470
|
+
# WRONG: Creates new tracker every time - loses all state!
|
|
471
|
+
tracker = AdvancedTracker(TrackerConfig()) # New instance each call
|
|
472
|
+
tracking_results = tracker.update(data) # No state preservation
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Why State Preservation Matters
|
|
476
|
+
|
|
477
|
+
1. **Track Continuity**: The same object gets the same `track_id` across frames
|
|
478
|
+
2. **Lost Track Recovery**: Objects temporarily occluded can be re-associated
|
|
479
|
+
3. **Performance**: No need to re-initialize tracking state for each frame
|
|
480
|
+
4. **Accuracy**: Better tracking results with historical context
|
|
481
|
+
|
|
482
|
+
### Integration Examples
|
|
483
|
+
|
|
484
|
+
#### Vehicle Monitoring Use Case
|
|
485
|
+
```python
|
|
486
|
+
class VehicleMonitoringUseCase(BaseProcessor):
|
|
487
|
+
def __init__(self):
|
|
488
|
+
super().__init__("vehicle_monitoring")
|
|
489
|
+
self.category = "traffic"
|
|
490
|
+
|
|
491
|
+
# Initialize tracker as None - will be created on first use
|
|
492
|
+
self.tracker = None
|
|
493
|
+
|
|
494
|
+
def process(self, data, config, context=None, stream_info=None):
|
|
495
|
+
# Create tracker instance if it doesn't exist (preserves state across frames)
|
|
496
|
+
if self.tracker is None:
|
|
497
|
+
tracker_config = TrackerConfig(
|
|
498
|
+
track_high_thresh=0.6,
|
|
499
|
+
track_low_thresh=0.2,
|
|
500
|
+
new_track_thresh=0.7,
|
|
501
|
+
track_buffer=40,
|
|
502
|
+
enable_smoothing=True
|
|
503
|
+
)
|
|
504
|
+
self.tracker = AdvancedTracker(tracker_config)
|
|
505
|
+
self.logger.info("Initialized AdvancedTracker for vehicle monitoring")
|
|
506
|
+
|
|
507
|
+
# Apply tracking (same instance used across frames)
|
|
508
|
+
tracking_results = self.tracker.update(data)
|
|
509
|
+
|
|
510
|
+
# Process tracking results instead of raw detections
|
|
511
|
+
return self._process_vehicle_monitoring(tracking_results, config, context, stream_info)
|
|
512
|
+
|
|
513
|
+
def reset_tracker(self) -> None:
|
|
514
|
+
"""Reset tracker for new tracking session."""
|
|
515
|
+
if self.tracker is not None:
|
|
516
|
+
self.tracker.reset()
|
|
517
|
+
self.logger.info("Vehicle monitoring tracker reset")
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
#### People Counting Use Case
|
|
521
|
+
```python
|
|
522
|
+
class PeopleCountingUseCase(BaseProcessor):
|
|
523
|
+
def __init__(self):
|
|
524
|
+
super().__init__("people_counting")
|
|
525
|
+
self.category = "general"
|
|
526
|
+
|
|
527
|
+
# Initialize tracker as None - will be created on first use
|
|
528
|
+
self.tracker = None
|
|
529
|
+
|
|
530
|
+
def process(self, data, config, context=None):
|
|
531
|
+
# Create tracker instance if it doesn't exist (preserves state across frames)
|
|
532
|
+
if self.tracker is None:
|
|
533
|
+
tracker_config = TrackerConfig(
|
|
534
|
+
track_high_thresh=0.5,
|
|
535
|
+
track_low_thresh=0.1,
|
|
536
|
+
new_track_thresh=0.6,
|
|
537
|
+
track_buffer=30,
|
|
538
|
+
enable_smoothing=True,
|
|
539
|
+
smoothing_algorithm="observability"
|
|
540
|
+
)
|
|
541
|
+
self.tracker = AdvancedTracker(tracker_config)
|
|
542
|
+
self.logger.info("Initialized AdvancedTracker for people counting")
|
|
543
|
+
|
|
544
|
+
# Apply tracking to get persistent people IDs
|
|
545
|
+
tracking_results = self.tracker.update(data)
|
|
546
|
+
|
|
547
|
+
# Use tracking results for counting and zone analysis
|
|
548
|
+
return self._process_people_counting(tracking_results, config, context)
|
|
549
|
+
|
|
550
|
+
def reset_tracker(self) -> None:
|
|
551
|
+
"""Reset tracker for new tracking session."""
|
|
552
|
+
if self.tracker is not None:
|
|
553
|
+
self.tracker.reset()
|
|
554
|
+
self.logger.info("People counting tracker reset")
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
#### PPE Compliance Use Case (Real Implementation)
|
|
558
|
+
```python
|
|
559
|
+
class PPEComplianceUseCase(BaseProcessor):
|
|
560
|
+
def __init__(self):
|
|
561
|
+
super().__init__("ppe_compliance_detection")
|
|
562
|
+
self.category = "ppe"
|
|
563
|
+
|
|
564
|
+
# List of violation categories to track
|
|
565
|
+
self.violation_categories = ["NO-Hardhat", "NO-Mask", "NO-Safety Vest"]
|
|
566
|
+
|
|
567
|
+
# Initialize smoothing tracker
|
|
568
|
+
self.smoothing_tracker = None
|
|
569
|
+
|
|
570
|
+
# Initialize advanced tracker (will be created on first use)
|
|
571
|
+
self.tracker = None
|
|
572
|
+
|
|
573
|
+
def process(self, data, config, context=None, stream_info=None):
|
|
574
|
+
# ... existing preprocessing ...
|
|
575
|
+
|
|
576
|
+
# Advanced tracking (BYTETracker-like)
|
|
577
|
+
try:
|
|
578
|
+
from ..advanced_tracker import AdvancedTracker
|
|
579
|
+
from ..advanced_tracker.config import TrackerConfig
|
|
580
|
+
|
|
581
|
+
# Create tracker instance if it doesn't exist (preserves state across frames)
|
|
582
|
+
if self.tracker is None:
|
|
583
|
+
tracker_config = TrackerConfig()
|
|
584
|
+
self.tracker = AdvancedTracker(tracker_config)
|
|
585
|
+
self.logger.info("Initialized AdvancedTracker for PPE compliance tracking")
|
|
586
|
+
|
|
587
|
+
processed_data = self.tracker.update(processed_data)
|
|
588
|
+
except Exception as e:
|
|
589
|
+
self.logger.warning(f"AdvancedTracker failed: {e}")
|
|
590
|
+
|
|
591
|
+
# ... continue with processing ...
|
|
592
|
+
|
|
593
|
+
def reset_tracker(self) -> None:
|
|
594
|
+
"""Reset the advanced tracker instance."""
|
|
595
|
+
if self.tracker is not None:
|
|
596
|
+
self.tracker.reset()
|
|
597
|
+
self.logger.info("AdvancedTracker reset for new tracking session")
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
## Best Practices
|
|
601
|
+
|
|
602
|
+
### 1. Tracker Initialization
|
|
603
|
+
- Initialize the tracker as `None` in `__init__` and create it on first use
|
|
604
|
+
- This preserves state across multiple `process()` calls
|
|
605
|
+
- Use appropriate configuration based on your use case requirements
|
|
606
|
+
|
|
607
|
+
### 2. Processing Order
|
|
608
|
+
- Always apply tracking **before** any other processing
|
|
609
|
+
- Use tracking results for all downstream operations
|
|
610
|
+
|
|
611
|
+
### 3. Configuration Tuning
|
|
612
|
+
- Start with default settings and tune based on your specific use case
|
|
613
|
+
- Higher thresholds = more precise but fewer tracks
|
|
614
|
+
- Lower thresholds = more tracks but potentially less accurate
|
|
615
|
+
|
|
616
|
+
### 4. State Management
|
|
617
|
+
- The tracker maintains state across calls, so it's suitable for video streams
|
|
618
|
+
- Use `tracker.reset()` if you need to start fresh tracking
|
|
619
|
+
|
|
620
|
+
### 5. Performance Considerations
|
|
621
|
+
- Disable GMC (`enable_gmc=False`) for faster processing
|
|
622
|
+
- Reduce `track_buffer` for memory efficiency
|
|
623
|
+
- Adjust `frame_rate` to match your video source
|
|
624
|
+
|
|
625
|
+
## Troubleshooting
|
|
626
|
+
|
|
627
|
+
### Common Issues
|
|
628
|
+
|
|
629
|
+
1. **No tracks being created**: Lower `new_track_thresh` and `track_high_thresh`
|
|
630
|
+
2. **Too many false tracks**: Increase `new_track_thresh` and `match_thresh`
|
|
631
|
+
3. **Tracks disappearing quickly**: Increase `track_buffer` and `max_time_lost`
|
|
632
|
+
4. **Poor tracking accuracy**: Enable smoothing and adjust thresholds
|
|
633
|
+
|
|
634
|
+
### Debug Information
|
|
635
|
+
The tracker provides debug information through logging:
|
|
636
|
+
```python
|
|
637
|
+
import logging
|
|
638
|
+
logging.getLogger('advanced_tracker').setLevel(logging.DEBUG)
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
## Advanced Usage
|
|
642
|
+
|
|
643
|
+
### Custom Distance Metrics
|
|
644
|
+
You can extend the matching logic by modifying the `matching.py` file to add custom distance metrics for your specific use case.
|
|
645
|
+
|
|
646
|
+
### Multi-Camera Tracking
|
|
647
|
+
For multi-camera scenarios, you can use the `location` attribute in tracks to associate objects across cameras.
|
|
648
|
+
|
|
649
|
+
### Track Persistence
|
|
650
|
+
The tracker maintains track state across calls, making it suitable for long video sequences or real-time streams.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Advanced tracker module for post-processing operations.
|
|
3
|
+
|
|
4
|
+
This module provides advanced tracking capabilities similar to BYTETracker from Ultralytics,
|
|
5
|
+
with support for various input formats and output formats.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .tracker import AdvancedTracker
|
|
9
|
+
from .config import TrackerConfig
|
|
10
|
+
from .base import BaseTrack, TrackState
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"AdvancedTracker",
|
|
14
|
+
"TrackerConfig",
|
|
15
|
+
"BaseTrack",
|
|
16
|
+
"TrackState"
|
|
17
|
+
]
|