pixelflow 0.3.1__tar.gz → 0.3.2__tar.gz
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.
- {pixelflow-0.3.1 → pixelflow-0.3.2}/PKG-INFO +1 -1
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/__init__.py +1 -1
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/smoother.py +48 -11
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow.egg-info/PKG-INFO +1 -1
- {pixelflow-0.3.1 → pixelflow-0.3.2}/LICENSE +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/README.md +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/__init__.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/anchors.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/blur.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/box.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/classification.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/crossing.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/dot.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/filled_box.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/fps_counter.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/grid_overlay.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/heatmap.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/keypoint.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/keypoint_skeleton.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/label.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/mask.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/motion_dots.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/motion_trails.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/oval.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/pixelate.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/polygon.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/scale_bar.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/utils.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/annotators/zones.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/arrays.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/assets.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/buffer.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/classifications/__init__.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/classifications/classifications.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/classifications/converters.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/colors.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/crossings.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/detections/__init__.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/detections/converters.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/detections/detections.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/detections/filters.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/labels.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/media.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/slicer.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/strategies.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/timer.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/tracker/__init__.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/tracker/bytetrack.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/tracker/kalman_filter.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/tracker/matching.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/tracker/track.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/transforms/__init__.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/transforms/detections.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/transforms/image.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/transforms/inverse.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/validators.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow/zones.py +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow.egg-info/SOURCES.txt +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow.egg-info/dependency_links.txt +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow.egg-info/requires.txt +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pixelflow.egg-info/top_level.txt +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/pyproject.toml +0 -0
- {pixelflow-0.3.1 → pixelflow-0.3.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pixelflow
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Computer vision processing library for visualizing and analyzing detection results from ML models
|
|
5
5
|
Author-email: Emrah Nazif <emrah@datamarkin.com>, Datamarkin <support@datamarkin.com>
|
|
6
6
|
License: MIT
|
|
@@ -7,6 +7,7 @@ scores, and interpolate missing detections. Designed to work seamlessly with Pix
|
|
|
7
7
|
buffer system for high-quality temporal smoothing in real-time applications.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
import warnings
|
|
10
11
|
from typing import Optional, Dict, List, Tuple, Union, TYPE_CHECKING
|
|
11
12
|
from collections import defaultdict
|
|
12
13
|
import numpy as np
|
|
@@ -107,22 +108,64 @@ def smooth(buffer: 'Buffer', temporal_weight_decay: float = 0.8) -> Detections:
|
|
|
107
108
|
|
|
108
109
|
# Group all detections by tracker_id across all temporal frames
|
|
109
110
|
tracker_detections = _collect_temporal_detections(context)
|
|
110
|
-
|
|
111
|
+
|
|
112
|
+
# Smoothing groups a detection with its own past and future, which only a
|
|
113
|
+
# tracker_id can establish. Untracked detections group into nothing, so
|
|
114
|
+
# returning them unsmoothed says so rather than dropping them silently.
|
|
115
|
+
if len(raw_results) > 0 and not tracker_detections:
|
|
116
|
+
warnings.warn(
|
|
117
|
+
"No detections have tracker_id. Smoothing matches each detection to "
|
|
118
|
+
"itself across frames, which requires tracking. "
|
|
119
|
+
"Make sure to call tracker.update(results) before buffering.",
|
|
120
|
+
UserWarning,
|
|
121
|
+
stacklevel=2,
|
|
122
|
+
)
|
|
123
|
+
return raw_results
|
|
124
|
+
|
|
125
|
+
# A tracker present in this frame is smoothed from its neighbours; one absent
|
|
126
|
+
# from it is interpolated between them. Both paths split on the same set, so
|
|
127
|
+
# neither can claim a tracker the other is already handling.
|
|
128
|
+
current_tracker_ids = _current_tracker_ids(context)
|
|
129
|
+
|
|
111
130
|
# Generate smoothed detections for each tracker
|
|
112
131
|
smoothed_detections = Detections()
|
|
113
132
|
for tracker_id, detections in tracker_detections.items():
|
|
133
|
+
if tracker_id not in current_tracker_ids:
|
|
134
|
+
continue
|
|
114
135
|
smoothed_detection = _smooth_temporal_detections(detections, temporal_weight_decay)
|
|
115
136
|
if smoothed_detection is not None:
|
|
116
137
|
smoothed_detections.add_detection(smoothed_detection)
|
|
117
|
-
|
|
138
|
+
|
|
118
139
|
# Check for missing detections that can be interpolated
|
|
119
140
|
missing_detections = _find_missing_detections(context, tracker_detections)
|
|
120
141
|
for interpolated_detection in missing_detections:
|
|
121
142
|
smoothed_detections.add_detection(interpolated_detection)
|
|
122
|
-
|
|
143
|
+
|
|
123
144
|
return smoothed_detections
|
|
124
145
|
|
|
125
146
|
|
|
147
|
+
def _current_tracker_ids(context: Dict) -> set:
|
|
148
|
+
"""
|
|
149
|
+
Tracker IDs present in the frame being smoothed.
|
|
150
|
+
|
|
151
|
+
This set is what divides the two halves of `smooth`: a tracker inside it is
|
|
152
|
+
smoothed from its neighbours, one outside it is interpolated between them.
|
|
153
|
+
One definition, so the two halves cannot disagree and emit the same
|
|
154
|
+
tracker_id twice in a single frame.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
context (Dict): Temporal context dictionary from `Buffer.get_temporal_context`.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
set: Tracker IDs found in the current frame, empty if it has none.
|
|
161
|
+
"""
|
|
162
|
+
current_detections = context['current_results']
|
|
163
|
+
if not current_detections:
|
|
164
|
+
return set()
|
|
165
|
+
return {detection.tracker_id for detection in current_detections.detections
|
|
166
|
+
if detection.tracker_id is not None}
|
|
167
|
+
|
|
168
|
+
|
|
126
169
|
def _collect_temporal_detections(context: Dict) -> Dict[int, List[Tuple[str, int, Detection]]]:
|
|
127
170
|
"""
|
|
128
171
|
Aggregate detections by tracker ID across all temporal frames.
|
|
@@ -498,14 +541,8 @@ def _find_missing_detections(context: Dict, tracker_detections: Dict[int, List[T
|
|
|
498
541
|
- Complexity: O(k*n) where k=trackers, n=avg detections per tracker
|
|
499
542
|
- Minimal overhead when no missing detections found
|
|
500
543
|
"""
|
|
501
|
-
current_tracker_ids =
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
# Get tracker IDs present in current frame
|
|
505
|
-
if current_detections:
|
|
506
|
-
current_tracker_ids = {detection.tracker_id for detection in current_detections.detections
|
|
507
|
-
if detection.tracker_id is not None}
|
|
508
|
-
|
|
544
|
+
current_tracker_ids = _current_tracker_ids(context)
|
|
545
|
+
|
|
509
546
|
missing_detections = []
|
|
510
547
|
|
|
511
548
|
# Check each tracker in temporal detections
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pixelflow
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Computer vision processing library for visualizing and analyzing detection results from ML models
|
|
5
5
|
Author-email: Emrah Nazif <emrah@datamarkin.com>, Datamarkin <support@datamarkin.com>
|
|
6
6
|
License: MIT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|