dgenerate-ultralytics-headless 8.3.137__py3-none-any.whl → 8.3.224__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.
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/METADATA +41 -34
- dgenerate_ultralytics_headless-8.3.224.dist-info/RECORD +285 -0
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/WHEEL +1 -1
- tests/__init__.py +7 -6
- tests/conftest.py +15 -39
- tests/test_cli.py +17 -17
- tests/test_cuda.py +17 -8
- tests/test_engine.py +36 -10
- tests/test_exports.py +98 -37
- tests/test_integrations.py +12 -15
- tests/test_python.py +126 -82
- tests/test_solutions.py +319 -135
- ultralytics/__init__.py +27 -9
- ultralytics/cfg/__init__.py +83 -87
- ultralytics/cfg/datasets/Argoverse.yaml +4 -4
- ultralytics/cfg/datasets/DOTAv1.5.yaml +2 -2
- ultralytics/cfg/datasets/DOTAv1.yaml +2 -2
- ultralytics/cfg/datasets/GlobalWheat2020.yaml +2 -2
- ultralytics/cfg/datasets/HomeObjects-3K.yaml +4 -5
- ultralytics/cfg/datasets/ImageNet.yaml +3 -3
- ultralytics/cfg/datasets/Objects365.yaml +24 -20
- ultralytics/cfg/datasets/SKU-110K.yaml +9 -9
- ultralytics/cfg/datasets/VOC.yaml +10 -13
- ultralytics/cfg/datasets/VisDrone.yaml +43 -33
- ultralytics/cfg/datasets/african-wildlife.yaml +5 -5
- ultralytics/cfg/datasets/brain-tumor.yaml +4 -5
- ultralytics/cfg/datasets/carparts-seg.yaml +5 -5
- ultralytics/cfg/datasets/coco-pose.yaml +26 -4
- ultralytics/cfg/datasets/coco.yaml +4 -4
- ultralytics/cfg/datasets/coco128-seg.yaml +2 -2
- ultralytics/cfg/datasets/coco128.yaml +2 -2
- ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
- ultralytics/cfg/datasets/coco8-multispectral.yaml +2 -2
- ultralytics/cfg/datasets/coco8-pose.yaml +23 -2
- ultralytics/cfg/datasets/coco8-seg.yaml +2 -2
- ultralytics/cfg/datasets/coco8.yaml +2 -2
- ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
- ultralytics/cfg/datasets/crack-seg.yaml +5 -5
- ultralytics/cfg/datasets/dog-pose.yaml +32 -4
- ultralytics/cfg/datasets/dota8-multispectral.yaml +2 -2
- ultralytics/cfg/datasets/dota8.yaml +2 -2
- ultralytics/cfg/datasets/hand-keypoints.yaml +29 -4
- ultralytics/cfg/datasets/lvis.yaml +9 -9
- ultralytics/cfg/datasets/medical-pills.yaml +4 -5
- ultralytics/cfg/datasets/open-images-v7.yaml +7 -10
- ultralytics/cfg/datasets/package-seg.yaml +5 -5
- ultralytics/cfg/datasets/signature.yaml +4 -4
- ultralytics/cfg/datasets/tiger-pose.yaml +20 -4
- ultralytics/cfg/datasets/xView.yaml +5 -5
- ultralytics/cfg/default.yaml +96 -93
- ultralytics/cfg/trackers/botsort.yaml +16 -17
- ultralytics/cfg/trackers/bytetrack.yaml +9 -11
- ultralytics/data/__init__.py +4 -4
- ultralytics/data/annotator.py +12 -12
- ultralytics/data/augment.py +531 -564
- ultralytics/data/base.py +76 -81
- ultralytics/data/build.py +206 -42
- ultralytics/data/converter.py +179 -78
- ultralytics/data/dataset.py +121 -121
- ultralytics/data/loaders.py +114 -91
- ultralytics/data/split.py +28 -15
- ultralytics/data/split_dota.py +67 -48
- ultralytics/data/utils.py +110 -89
- ultralytics/engine/exporter.py +422 -460
- ultralytics/engine/model.py +224 -252
- ultralytics/engine/predictor.py +94 -89
- ultralytics/engine/results.py +345 -595
- ultralytics/engine/trainer.py +231 -134
- ultralytics/engine/tuner.py +279 -73
- ultralytics/engine/validator.py +53 -46
- ultralytics/hub/__init__.py +26 -28
- ultralytics/hub/auth.py +30 -16
- ultralytics/hub/google/__init__.py +34 -36
- ultralytics/hub/session.py +53 -77
- ultralytics/hub/utils.py +23 -109
- ultralytics/models/__init__.py +1 -1
- ultralytics/models/fastsam/__init__.py +1 -1
- ultralytics/models/fastsam/model.py +36 -18
- ultralytics/models/fastsam/predict.py +33 -44
- ultralytics/models/fastsam/utils.py +4 -5
- ultralytics/models/fastsam/val.py +12 -14
- ultralytics/models/nas/__init__.py +1 -1
- ultralytics/models/nas/model.py +16 -20
- ultralytics/models/nas/predict.py +12 -14
- ultralytics/models/nas/val.py +4 -5
- ultralytics/models/rtdetr/__init__.py +1 -1
- ultralytics/models/rtdetr/model.py +9 -9
- ultralytics/models/rtdetr/predict.py +22 -17
- ultralytics/models/rtdetr/train.py +20 -16
- ultralytics/models/rtdetr/val.py +79 -59
- ultralytics/models/sam/__init__.py +8 -2
- ultralytics/models/sam/amg.py +53 -38
- ultralytics/models/sam/build.py +29 -31
- ultralytics/models/sam/model.py +33 -38
- ultralytics/models/sam/modules/blocks.py +159 -182
- ultralytics/models/sam/modules/decoders.py +38 -47
- ultralytics/models/sam/modules/encoders.py +114 -133
- ultralytics/models/sam/modules/memory_attention.py +38 -31
- ultralytics/models/sam/modules/sam.py +114 -93
- ultralytics/models/sam/modules/tiny_encoder.py +268 -291
- ultralytics/models/sam/modules/transformer.py +59 -66
- ultralytics/models/sam/modules/utils.py +55 -72
- ultralytics/models/sam/predict.py +745 -341
- ultralytics/models/utils/loss.py +118 -107
- ultralytics/models/utils/ops.py +118 -71
- ultralytics/models/yolo/__init__.py +1 -1
- ultralytics/models/yolo/classify/predict.py +28 -26
- ultralytics/models/yolo/classify/train.py +50 -81
- ultralytics/models/yolo/classify/val.py +68 -61
- ultralytics/models/yolo/detect/predict.py +12 -15
- ultralytics/models/yolo/detect/train.py +56 -46
- ultralytics/models/yolo/detect/val.py +279 -223
- ultralytics/models/yolo/model.py +167 -86
- ultralytics/models/yolo/obb/predict.py +7 -11
- ultralytics/models/yolo/obb/train.py +23 -25
- ultralytics/models/yolo/obb/val.py +107 -99
- ultralytics/models/yolo/pose/__init__.py +1 -1
- ultralytics/models/yolo/pose/predict.py +12 -14
- ultralytics/models/yolo/pose/train.py +31 -69
- ultralytics/models/yolo/pose/val.py +119 -254
- ultralytics/models/yolo/segment/predict.py +21 -25
- ultralytics/models/yolo/segment/train.py +12 -66
- ultralytics/models/yolo/segment/val.py +126 -305
- ultralytics/models/yolo/world/train.py +53 -45
- ultralytics/models/yolo/world/train_world.py +51 -32
- ultralytics/models/yolo/yoloe/__init__.py +7 -7
- ultralytics/models/yolo/yoloe/predict.py +30 -37
- ultralytics/models/yolo/yoloe/train.py +89 -71
- ultralytics/models/yolo/yoloe/train_seg.py +15 -17
- ultralytics/models/yolo/yoloe/val.py +56 -41
- ultralytics/nn/__init__.py +9 -11
- ultralytics/nn/autobackend.py +179 -107
- ultralytics/nn/modules/__init__.py +67 -67
- ultralytics/nn/modules/activation.py +8 -7
- ultralytics/nn/modules/block.py +302 -323
- ultralytics/nn/modules/conv.py +61 -104
- ultralytics/nn/modules/head.py +488 -186
- ultralytics/nn/modules/transformer.py +183 -123
- ultralytics/nn/modules/utils.py +15 -20
- ultralytics/nn/tasks.py +327 -203
- ultralytics/nn/text_model.py +81 -65
- ultralytics/py.typed +1 -0
- ultralytics/solutions/__init__.py +12 -12
- ultralytics/solutions/ai_gym.py +19 -27
- ultralytics/solutions/analytics.py +36 -26
- ultralytics/solutions/config.py +29 -28
- ultralytics/solutions/distance_calculation.py +23 -24
- ultralytics/solutions/heatmap.py +17 -19
- ultralytics/solutions/instance_segmentation.py +21 -19
- ultralytics/solutions/object_blurrer.py +16 -17
- ultralytics/solutions/object_counter.py +48 -53
- ultralytics/solutions/object_cropper.py +22 -16
- ultralytics/solutions/parking_management.py +61 -58
- ultralytics/solutions/queue_management.py +19 -19
- ultralytics/solutions/region_counter.py +63 -50
- ultralytics/solutions/security_alarm.py +22 -25
- ultralytics/solutions/similarity_search.py +107 -60
- ultralytics/solutions/solutions.py +343 -262
- ultralytics/solutions/speed_estimation.py +35 -31
- ultralytics/solutions/streamlit_inference.py +104 -40
- ultralytics/solutions/templates/similarity-search.html +31 -24
- ultralytics/solutions/trackzone.py +24 -24
- ultralytics/solutions/vision_eye.py +11 -12
- ultralytics/trackers/__init__.py +1 -1
- ultralytics/trackers/basetrack.py +18 -27
- ultralytics/trackers/bot_sort.py +48 -39
- ultralytics/trackers/byte_tracker.py +94 -94
- ultralytics/trackers/track.py +7 -16
- ultralytics/trackers/utils/gmc.py +37 -69
- ultralytics/trackers/utils/kalman_filter.py +68 -76
- ultralytics/trackers/utils/matching.py +13 -17
- ultralytics/utils/__init__.py +251 -275
- ultralytics/utils/autobatch.py +19 -7
- ultralytics/utils/autodevice.py +68 -38
- ultralytics/utils/benchmarks.py +169 -130
- ultralytics/utils/callbacks/base.py +12 -13
- ultralytics/utils/callbacks/clearml.py +14 -15
- ultralytics/utils/callbacks/comet.py +139 -66
- ultralytics/utils/callbacks/dvc.py +19 -27
- ultralytics/utils/callbacks/hub.py +8 -6
- ultralytics/utils/callbacks/mlflow.py +6 -10
- ultralytics/utils/callbacks/neptune.py +11 -19
- ultralytics/utils/callbacks/platform.py +73 -0
- ultralytics/utils/callbacks/raytune.py +3 -4
- ultralytics/utils/callbacks/tensorboard.py +9 -12
- ultralytics/utils/callbacks/wb.py +33 -30
- ultralytics/utils/checks.py +163 -114
- ultralytics/utils/cpu.py +89 -0
- ultralytics/utils/dist.py +24 -20
- ultralytics/utils/downloads.py +176 -146
- ultralytics/utils/errors.py +11 -13
- ultralytics/utils/events.py +113 -0
- ultralytics/utils/export/__init__.py +7 -0
- ultralytics/utils/{export.py → export/engine.py} +81 -63
- ultralytics/utils/export/imx.py +294 -0
- ultralytics/utils/export/tensorflow.py +217 -0
- ultralytics/utils/files.py +33 -36
- ultralytics/utils/git.py +137 -0
- ultralytics/utils/instance.py +105 -120
- ultralytics/utils/logger.py +404 -0
- ultralytics/utils/loss.py +99 -61
- ultralytics/utils/metrics.py +649 -478
- ultralytics/utils/nms.py +337 -0
- ultralytics/utils/ops.py +263 -451
- ultralytics/utils/patches.py +70 -31
- ultralytics/utils/plotting.py +253 -223
- ultralytics/utils/tal.py +48 -61
- ultralytics/utils/torch_utils.py +244 -251
- ultralytics/utils/tqdm.py +438 -0
- ultralytics/utils/triton.py +22 -23
- ultralytics/utils/tuner.py +11 -10
- dgenerate_ultralytics_headless-8.3.137.dist-info/RECORD +0 -272
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import copy
|
|
4
6
|
|
|
5
7
|
import cv2
|
|
@@ -9,8 +11,7 @@ from ultralytics.utils import LOGGER
|
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class GMC:
|
|
12
|
-
"""
|
|
13
|
-
Generalized Motion Compensation (GMC) class for tracking and object detection in video frames.
|
|
14
|
+
"""Generalized Motion Compensation (GMC) class for tracking and object detection in video frames.
|
|
14
15
|
|
|
15
16
|
This class provides methods for tracking and detecting objects based on several tracking algorithms including ORB,
|
|
16
17
|
SIFT, ECC, and Sparse Optical Flow. It also supports downscaling of frames for computational efficiency.
|
|
@@ -41,8 +42,7 @@ class GMC:
|
|
|
41
42
|
"""
|
|
42
43
|
|
|
43
44
|
def __init__(self, method: str = "sparseOptFlow", downscale: int = 2) -> None:
|
|
44
|
-
"""
|
|
45
|
-
Initialize a Generalized Motion Compensation (GMC) object with tracking method and downscale factor.
|
|
45
|
+
"""Initialize a Generalized Motion Compensation (GMC) object with tracking method and downscale factor.
|
|
46
46
|
|
|
47
47
|
Args:
|
|
48
48
|
method (str): The tracking method to use. Options include 'orb', 'sift', 'ecc', 'sparseOptFlow', 'none'.
|
|
@@ -88,13 +88,12 @@ class GMC:
|
|
|
88
88
|
self.prevDescriptors = None
|
|
89
89
|
self.initializedFirstFrame = False
|
|
90
90
|
|
|
91
|
-
def apply(self, raw_frame: np.ndarray, detections: list = None) -> np.ndarray:
|
|
92
|
-
"""
|
|
93
|
-
Apply object detection on a raw frame using the specified method.
|
|
91
|
+
def apply(self, raw_frame: np.ndarray, detections: list | None = None) -> np.ndarray:
|
|
92
|
+
"""Apply object detection on a raw frame using the specified method.
|
|
94
93
|
|
|
95
94
|
Args:
|
|
96
95
|
raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).
|
|
97
|
-
detections (
|
|
96
|
+
detections (list, optional): List of detections to be used in the processing.
|
|
98
97
|
|
|
99
98
|
Returns:
|
|
100
99
|
(np.ndarray): Transformation matrix with shape (2, 3).
|
|
@@ -116,8 +115,7 @@ class GMC:
|
|
|
116
115
|
return np.eye(2, 3)
|
|
117
116
|
|
|
118
117
|
def apply_ecc(self, raw_frame: np.ndarray) -> np.ndarray:
|
|
119
|
-
"""
|
|
120
|
-
Apply the ECC (Enhanced Correlation Coefficient) algorithm to a raw frame for motion compensation.
|
|
118
|
+
"""Apply the ECC (Enhanced Correlation Coefficient) algorithm to a raw frame for motion compensation.
|
|
121
119
|
|
|
122
120
|
Args:
|
|
123
121
|
raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).
|
|
@@ -136,23 +134,18 @@ class GMC:
|
|
|
136
134
|
frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGR2GRAY) if c == 3 else raw_frame
|
|
137
135
|
H = np.eye(2, 3, dtype=np.float32)
|
|
138
136
|
|
|
139
|
-
# Downscale image
|
|
137
|
+
# Downscale image for computational efficiency
|
|
140
138
|
if self.downscale > 1.0:
|
|
141
139
|
frame = cv2.GaussianBlur(frame, (3, 3), 1.5)
|
|
142
140
|
frame = cv2.resize(frame, (width // self.downscale, height // self.downscale))
|
|
143
141
|
|
|
144
|
-
# Handle first frame
|
|
142
|
+
# Handle first frame initialization
|
|
145
143
|
if not self.initializedFirstFrame:
|
|
146
|
-
# Initialize data
|
|
147
144
|
self.prevFrame = frame.copy()
|
|
148
|
-
|
|
149
|
-
# Initialization done
|
|
150
145
|
self.initializedFirstFrame = True
|
|
151
|
-
|
|
152
146
|
return H
|
|
153
147
|
|
|
154
|
-
# Run the ECC algorithm
|
|
155
|
-
# (cc, H) = cv2.findTransformECC(self.prevFrame, frame, H, self.warp_mode, self.criteria)
|
|
148
|
+
# Run the ECC algorithm to find transformation matrix
|
|
156
149
|
try:
|
|
157
150
|
(_, H) = cv2.findTransformECC(self.prevFrame, frame, H, self.warp_mode, self.criteria, None, 1)
|
|
158
151
|
except Exception as e:
|
|
@@ -160,13 +153,12 @@ class GMC:
|
|
|
160
153
|
|
|
161
154
|
return H
|
|
162
155
|
|
|
163
|
-
def apply_features(self, raw_frame: np.ndarray, detections: list = None) -> np.ndarray:
|
|
164
|
-
"""
|
|
165
|
-
Apply feature-based methods like ORB or SIFT to a raw frame.
|
|
156
|
+
def apply_features(self, raw_frame: np.ndarray, detections: list | None = None) -> np.ndarray:
|
|
157
|
+
"""Apply feature-based methods like ORB or SIFT to a raw frame.
|
|
166
158
|
|
|
167
159
|
Args:
|
|
168
160
|
raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).
|
|
169
|
-
detections (
|
|
161
|
+
detections (list, optional): List of detections to be used in the processing.
|
|
170
162
|
|
|
171
163
|
Returns:
|
|
172
164
|
(np.ndarray): Transformation matrix with shape (2, 3).
|
|
@@ -182,55 +174,50 @@ class GMC:
|
|
|
182
174
|
frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGR2GRAY) if c == 3 else raw_frame
|
|
183
175
|
H = np.eye(2, 3)
|
|
184
176
|
|
|
185
|
-
# Downscale image
|
|
177
|
+
# Downscale image for computational efficiency
|
|
186
178
|
if self.downscale > 1.0:
|
|
187
179
|
frame = cv2.resize(frame, (width // self.downscale, height // self.downscale))
|
|
188
180
|
width = width // self.downscale
|
|
189
181
|
height = height // self.downscale
|
|
190
182
|
|
|
191
|
-
#
|
|
183
|
+
# Create mask for keypoint detection, excluding border regions
|
|
192
184
|
mask = np.zeros_like(frame)
|
|
193
185
|
mask[int(0.02 * height) : int(0.98 * height), int(0.02 * width) : int(0.98 * width)] = 255
|
|
186
|
+
|
|
187
|
+
# Exclude detection regions from mask to avoid tracking detected objects
|
|
194
188
|
if detections is not None:
|
|
195
189
|
for det in detections:
|
|
196
190
|
tlbr = (det[:4] / self.downscale).astype(np.int_)
|
|
197
191
|
mask[tlbr[1] : tlbr[3], tlbr[0] : tlbr[2]] = 0
|
|
198
192
|
|
|
193
|
+
# Find keypoints and compute descriptors
|
|
199
194
|
keypoints = self.detector.detect(frame, mask)
|
|
200
|
-
|
|
201
|
-
# Compute the descriptors
|
|
202
195
|
keypoints, descriptors = self.extractor.compute(frame, keypoints)
|
|
203
196
|
|
|
204
|
-
# Handle first frame
|
|
197
|
+
# Handle first frame initialization
|
|
205
198
|
if not self.initializedFirstFrame:
|
|
206
|
-
# Initialize data
|
|
207
199
|
self.prevFrame = frame.copy()
|
|
208
200
|
self.prevKeyPoints = copy.copy(keypoints)
|
|
209
201
|
self.prevDescriptors = copy.copy(descriptors)
|
|
210
|
-
|
|
211
|
-
# Initialization done
|
|
212
202
|
self.initializedFirstFrame = True
|
|
213
|
-
|
|
214
203
|
return H
|
|
215
204
|
|
|
216
|
-
# Match descriptors
|
|
205
|
+
# Match descriptors between previous and current frame
|
|
217
206
|
knnMatches = self.matcher.knnMatch(self.prevDescriptors, descriptors, 2)
|
|
218
207
|
|
|
219
|
-
# Filter matches based on
|
|
208
|
+
# Filter matches based on spatial distance constraints
|
|
220
209
|
matches = []
|
|
221
210
|
spatialDistances = []
|
|
222
|
-
|
|
223
211
|
maxSpatialDistance = 0.25 * np.array([width, height])
|
|
224
212
|
|
|
225
213
|
# Handle empty matches case
|
|
226
214
|
if len(knnMatches) == 0:
|
|
227
|
-
# Store to next iteration
|
|
228
215
|
self.prevFrame = frame.copy()
|
|
229
216
|
self.prevKeyPoints = copy.copy(keypoints)
|
|
230
217
|
self.prevDescriptors = copy.copy(descriptors)
|
|
231
|
-
|
|
232
218
|
return H
|
|
233
219
|
|
|
220
|
+
# Apply Lowe's ratio test and spatial distance filtering
|
|
234
221
|
for m, n in knnMatches:
|
|
235
222
|
if m.distance < 0.9 * n.distance:
|
|
236
223
|
prevKeyPointLocation = self.prevKeyPoints[m.queryIdx].pt
|
|
@@ -247,11 +234,12 @@ class GMC:
|
|
|
247
234
|
spatialDistances.append(spatialDistance)
|
|
248
235
|
matches.append(m)
|
|
249
236
|
|
|
237
|
+
# Filter outliers using statistical analysis
|
|
250
238
|
meanSpatialDistances = np.mean(spatialDistances, 0)
|
|
251
239
|
stdSpatialDistances = np.std(spatialDistances, 0)
|
|
252
|
-
|
|
253
240
|
inliers = (spatialDistances - meanSpatialDistances) < 2.5 * stdSpatialDistances
|
|
254
241
|
|
|
242
|
+
# Extract good matches and corresponding points
|
|
255
243
|
goodMatches = []
|
|
256
244
|
prevPoints = []
|
|
257
245
|
currPoints = []
|
|
@@ -264,39 +252,18 @@ class GMC:
|
|
|
264
252
|
prevPoints = np.array(prevPoints)
|
|
265
253
|
currPoints = np.array(currPoints)
|
|
266
254
|
|
|
267
|
-
#
|
|
268
|
-
# if False:
|
|
269
|
-
# import matplotlib.pyplot as plt
|
|
270
|
-
# matches_img = np.hstack((self.prevFrame, frame))
|
|
271
|
-
# matches_img = cv2.cvtColor(matches_img, cv2.COLOR_GRAY2BGR)
|
|
272
|
-
# W = self.prevFrame.shape[1]
|
|
273
|
-
# for m in goodMatches:
|
|
274
|
-
# prev_pt = np.array(self.prevKeyPoints[m.queryIdx].pt, dtype=np.int_)
|
|
275
|
-
# curr_pt = np.array(keypoints[m.trainIdx].pt, dtype=np.int_)
|
|
276
|
-
# curr_pt[0] += W
|
|
277
|
-
# color = np.random.randint(0, 255, 3)
|
|
278
|
-
# color = (int(color[0]), int(color[1]), int(color[2]))
|
|
279
|
-
#
|
|
280
|
-
# matches_img = cv2.line(matches_img, prev_pt, curr_pt, tuple(color), 1, cv2.LINE_AA)
|
|
281
|
-
# matches_img = cv2.circle(matches_img, prev_pt, 2, tuple(color), -1)
|
|
282
|
-
# matches_img = cv2.circle(matches_img, curr_pt, 2, tuple(color), -1)
|
|
283
|
-
#
|
|
284
|
-
# plt.figure()
|
|
285
|
-
# plt.imshow(matches_img)
|
|
286
|
-
# plt.show()
|
|
287
|
-
|
|
288
|
-
# Find rigid matrix
|
|
255
|
+
# Estimate transformation matrix using RANSAC
|
|
289
256
|
if prevPoints.shape[0] > 4:
|
|
290
257
|
H, inliers = cv2.estimateAffinePartial2D(prevPoints, currPoints, cv2.RANSAC)
|
|
291
258
|
|
|
292
|
-
#
|
|
259
|
+
# Scale translation components back to original resolution
|
|
293
260
|
if self.downscale > 1.0:
|
|
294
261
|
H[0, 2] *= self.downscale
|
|
295
262
|
H[1, 2] *= self.downscale
|
|
296
263
|
else:
|
|
297
264
|
LOGGER.warning("not enough matching points")
|
|
298
265
|
|
|
299
|
-
# Store
|
|
266
|
+
# Store current frame data for next iteration
|
|
300
267
|
self.prevFrame = frame.copy()
|
|
301
268
|
self.prevKeyPoints = copy.copy(keypoints)
|
|
302
269
|
self.prevDescriptors = copy.copy(descriptors)
|
|
@@ -304,8 +271,7 @@ class GMC:
|
|
|
304
271
|
return H
|
|
305
272
|
|
|
306
273
|
def apply_sparseoptflow(self, raw_frame: np.ndarray) -> np.ndarray:
|
|
307
|
-
"""
|
|
308
|
-
Apply Sparse Optical Flow method to a raw frame.
|
|
274
|
+
"""Apply Sparse Optical Flow method to a raw frame.
|
|
309
275
|
|
|
310
276
|
Args:
|
|
311
277
|
raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).
|
|
@@ -324,24 +290,24 @@ class GMC:
|
|
|
324
290
|
frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGR2GRAY) if c == 3 else raw_frame
|
|
325
291
|
H = np.eye(2, 3)
|
|
326
292
|
|
|
327
|
-
# Downscale image
|
|
293
|
+
# Downscale image for computational efficiency
|
|
328
294
|
if self.downscale > 1.0:
|
|
329
295
|
frame = cv2.resize(frame, (width // self.downscale, height // self.downscale))
|
|
330
296
|
|
|
331
|
-
# Find
|
|
297
|
+
# Find good features to track
|
|
332
298
|
keypoints = cv2.goodFeaturesToTrack(frame, mask=None, **self.feature_params)
|
|
333
299
|
|
|
334
|
-
# Handle first frame
|
|
300
|
+
# Handle first frame initialization
|
|
335
301
|
if not self.initializedFirstFrame or self.prevKeyPoints is None:
|
|
336
302
|
self.prevFrame = frame.copy()
|
|
337
303
|
self.prevKeyPoints = copy.copy(keypoints)
|
|
338
304
|
self.initializedFirstFrame = True
|
|
339
305
|
return H
|
|
340
306
|
|
|
341
|
-
#
|
|
307
|
+
# Calculate optical flow using Lucas-Kanade method
|
|
342
308
|
matchedKeypoints, status, _ = cv2.calcOpticalFlowPyrLK(self.prevFrame, frame, self.prevKeyPoints, None)
|
|
343
309
|
|
|
344
|
-
#
|
|
310
|
+
# Extract successfully tracked points
|
|
345
311
|
prevPoints = []
|
|
346
312
|
currPoints = []
|
|
347
313
|
|
|
@@ -353,16 +319,18 @@ class GMC:
|
|
|
353
319
|
prevPoints = np.array(prevPoints)
|
|
354
320
|
currPoints = np.array(currPoints)
|
|
355
321
|
|
|
356
|
-
#
|
|
322
|
+
# Estimate transformation matrix using RANSAC
|
|
357
323
|
if (prevPoints.shape[0] > 4) and (prevPoints.shape[0] == currPoints.shape[0]):
|
|
358
324
|
H, _ = cv2.estimateAffinePartial2D(prevPoints, currPoints, cv2.RANSAC)
|
|
359
325
|
|
|
326
|
+
# Scale translation components back to original resolution
|
|
360
327
|
if self.downscale > 1.0:
|
|
361
328
|
H[0, 2] *= self.downscale
|
|
362
329
|
H[1, 2] *= self.downscale
|
|
363
330
|
else:
|
|
364
331
|
LOGGER.warning("not enough matching points")
|
|
365
332
|
|
|
333
|
+
# Store current frame data for next iteration
|
|
366
334
|
self.prevFrame = frame.copy()
|
|
367
335
|
self.prevKeyPoints = copy.copy(keypoints)
|
|
368
336
|
|
|
@@ -5,11 +5,10 @@ import scipy.linalg
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class KalmanFilterXYAH:
|
|
8
|
-
"""
|
|
9
|
-
A KalmanFilterXYAH class for tracking bounding boxes in image space using a Kalman filter.
|
|
8
|
+
"""A KalmanFilterXYAH class for tracking bounding boxes in image space using a Kalman filter.
|
|
10
9
|
|
|
11
|
-
Implements a simple Kalman filter for tracking bounding boxes in image space. The 8-dimensional state space
|
|
12
|
-
|
|
10
|
+
Implements a simple Kalman filter for tracking bounding boxes in image space. The 8-dimensional state space (x, y,
|
|
11
|
+
a, h, vx, vy, va, vh) contains the bounding box center position (x, y), aspect ratio a, height h, and their
|
|
13
12
|
respective velocities. Object motion follows a constant velocity model, and bounding box location (x, y, a, h) is
|
|
14
13
|
taken as a direct observation of the state space (linear observation model).
|
|
15
14
|
|
|
@@ -20,12 +19,12 @@ class KalmanFilterXYAH:
|
|
|
20
19
|
_std_weight_velocity (float): Standard deviation weight for velocity.
|
|
21
20
|
|
|
22
21
|
Methods:
|
|
23
|
-
initiate:
|
|
24
|
-
predict:
|
|
25
|
-
project:
|
|
26
|
-
multi_predict:
|
|
27
|
-
update:
|
|
28
|
-
gating_distance:
|
|
22
|
+
initiate: Create a track from an unassociated measurement.
|
|
23
|
+
predict: Run the Kalman filter prediction step.
|
|
24
|
+
project: Project the state distribution to measurement space.
|
|
25
|
+
multi_predict: Run the Kalman filter prediction step (vectorized version).
|
|
26
|
+
update: Run the Kalman filter correction step.
|
|
27
|
+
gating_distance: Compute the gating distance between state distribution and measurements.
|
|
29
28
|
|
|
30
29
|
Examples:
|
|
31
30
|
Initialize the Kalman filter and create a track from a measurement
|
|
@@ -37,8 +36,7 @@ class KalmanFilterXYAH:
|
|
|
37
36
|
"""
|
|
38
37
|
|
|
39
38
|
def __init__(self):
|
|
40
|
-
"""
|
|
41
|
-
Initialize Kalman filter model matrices with motion and observation uncertainty weights.
|
|
39
|
+
"""Initialize Kalman filter model matrices with motion and observation uncertainty weights.
|
|
42
40
|
|
|
43
41
|
The Kalman filter is initialized with an 8-dimensional state space (x, y, a, h, vx, vy, va, vh), where (x, y)
|
|
44
42
|
represents the bounding box center position, 'a' is the aspect ratio, 'h' is the height, and their respective
|
|
@@ -62,16 +60,16 @@ class KalmanFilterXYAH:
|
|
|
62
60
|
self._std_weight_velocity = 1.0 / 160
|
|
63
61
|
|
|
64
62
|
def initiate(self, measurement: np.ndarray):
|
|
65
|
-
"""
|
|
66
|
-
Create a track from an unassociated measurement.
|
|
63
|
+
"""Create a track from an unassociated measurement.
|
|
67
64
|
|
|
68
65
|
Args:
|
|
69
66
|
measurement (np.ndarray): Bounding box coordinates (x, y, a, h) with center position (x, y), aspect ratio a,
|
|
70
67
|
and height h.
|
|
71
68
|
|
|
72
69
|
Returns:
|
|
73
|
-
(np.ndarray): Mean vector (8-dimensional) of the new track. Unobserved velocities are initialized to 0
|
|
74
|
-
|
|
70
|
+
mean (np.ndarray): Mean vector (8-dimensional) of the new track. Unobserved velocities are initialized to 0
|
|
71
|
+
mean.
|
|
72
|
+
covariance (np.ndarray): Covariance matrix (8x8 dimensional) of the new track.
|
|
75
73
|
|
|
76
74
|
Examples:
|
|
77
75
|
>>> kf = KalmanFilterXYAH()
|
|
@@ -96,16 +94,16 @@ class KalmanFilterXYAH:
|
|
|
96
94
|
return mean, covariance
|
|
97
95
|
|
|
98
96
|
def predict(self, mean: np.ndarray, covariance: np.ndarray):
|
|
99
|
-
"""
|
|
100
|
-
Run Kalman filter prediction step.
|
|
97
|
+
"""Run Kalman filter prediction step.
|
|
101
98
|
|
|
102
99
|
Args:
|
|
103
100
|
mean (np.ndarray): The 8-dimensional mean vector of the object state at the previous time step.
|
|
104
|
-
covariance (np.ndarray): The 8x8-dimensional covariance matrix of the object state at the previous time
|
|
101
|
+
covariance (np.ndarray): The 8x8-dimensional covariance matrix of the object state at the previous time
|
|
102
|
+
step.
|
|
105
103
|
|
|
106
104
|
Returns:
|
|
107
|
-
(np.ndarray): Mean vector of the predicted state. Unobserved velocities are initialized to 0 mean.
|
|
108
|
-
(np.ndarray): Covariance matrix of the predicted state.
|
|
105
|
+
mean (np.ndarray): Mean vector of the predicted state. Unobserved velocities are initialized to 0 mean.
|
|
106
|
+
covariance (np.ndarray): Covariance matrix of the predicted state.
|
|
109
107
|
|
|
110
108
|
Examples:
|
|
111
109
|
>>> kf = KalmanFilterXYAH()
|
|
@@ -133,16 +131,15 @@ class KalmanFilterXYAH:
|
|
|
133
131
|
return mean, covariance
|
|
134
132
|
|
|
135
133
|
def project(self, mean: np.ndarray, covariance: np.ndarray):
|
|
136
|
-
"""
|
|
137
|
-
Project state distribution to measurement space.
|
|
134
|
+
"""Project state distribution to measurement space.
|
|
138
135
|
|
|
139
136
|
Args:
|
|
140
137
|
mean (np.ndarray): The state's mean vector (8 dimensional array).
|
|
141
138
|
covariance (np.ndarray): The state's covariance matrix (8x8 dimensional).
|
|
142
139
|
|
|
143
140
|
Returns:
|
|
144
|
-
(np.ndarray): Projected mean of the given state estimate.
|
|
145
|
-
(np.ndarray): Projected covariance matrix of the given state estimate.
|
|
141
|
+
mean (np.ndarray): Projected mean of the given state estimate.
|
|
142
|
+
covariance (np.ndarray): Projected covariance matrix of the given state estimate.
|
|
146
143
|
|
|
147
144
|
Examples:
|
|
148
145
|
>>> kf = KalmanFilterXYAH()
|
|
@@ -163,16 +160,15 @@ class KalmanFilterXYAH:
|
|
|
163
160
|
return mean, covariance + innovation_cov
|
|
164
161
|
|
|
165
162
|
def multi_predict(self, mean: np.ndarray, covariance: np.ndarray):
|
|
166
|
-
"""
|
|
167
|
-
Run Kalman filter prediction step for multiple object states (Vectorized version).
|
|
163
|
+
"""Run Kalman filter prediction step for multiple object states (Vectorized version).
|
|
168
164
|
|
|
169
165
|
Args:
|
|
170
166
|
mean (np.ndarray): The Nx8 dimensional mean matrix of the object states at the previous time step.
|
|
171
167
|
covariance (np.ndarray): The Nx8x8 covariance matrix of the object states at the previous time step.
|
|
172
168
|
|
|
173
169
|
Returns:
|
|
174
|
-
(np.ndarray): Mean matrix of the predicted states with shape (N, 8).
|
|
175
|
-
(np.ndarray): Covariance matrix of the predicted states with shape (N, 8, 8).
|
|
170
|
+
mean (np.ndarray): Mean matrix of the predicted states with shape (N, 8).
|
|
171
|
+
covariance (np.ndarray): Covariance matrix of the predicted states with shape (N, 8, 8).
|
|
176
172
|
|
|
177
173
|
Examples:
|
|
178
174
|
>>> mean = np.random.rand(10, 8) # 10 object states
|
|
@@ -203,8 +199,7 @@ class KalmanFilterXYAH:
|
|
|
203
199
|
return mean, covariance
|
|
204
200
|
|
|
205
201
|
def update(self, mean: np.ndarray, covariance: np.ndarray, measurement: np.ndarray):
|
|
206
|
-
"""
|
|
207
|
-
Run Kalman filter correction step.
|
|
202
|
+
"""Run Kalman filter correction step.
|
|
208
203
|
|
|
209
204
|
Args:
|
|
210
205
|
mean (np.ndarray): The predicted state's mean vector (8 dimensional).
|
|
@@ -213,8 +208,8 @@ class KalmanFilterXYAH:
|
|
|
213
208
|
position, a the aspect ratio, and h the height of the bounding box.
|
|
214
209
|
|
|
215
210
|
Returns:
|
|
216
|
-
(np.ndarray): Measurement-corrected state mean.
|
|
217
|
-
(np.ndarray): Measurement-corrected state covariance.
|
|
211
|
+
new_mean (np.ndarray): Measurement-corrected state mean.
|
|
212
|
+
new_covariance (np.ndarray): Measurement-corrected state covariance.
|
|
218
213
|
|
|
219
214
|
Examples:
|
|
220
215
|
>>> kf = KalmanFilterXYAH()
|
|
@@ -243,8 +238,7 @@ class KalmanFilterXYAH:
|
|
|
243
238
|
only_position: bool = False,
|
|
244
239
|
metric: str = "maha",
|
|
245
240
|
) -> np.ndarray:
|
|
246
|
-
"""
|
|
247
|
-
Compute gating distance between state distribution and measurements.
|
|
241
|
+
"""Compute gating distance between state distribution and measurements.
|
|
248
242
|
|
|
249
243
|
A suitable distance threshold can be obtained from `chi2inv95`. If `only_position` is False, the chi-square
|
|
250
244
|
distribution has 4 degrees of freedom, otherwise 2.
|
|
@@ -252,11 +246,12 @@ class KalmanFilterXYAH:
|
|
|
252
246
|
Args:
|
|
253
247
|
mean (np.ndarray): Mean vector over the state distribution (8 dimensional).
|
|
254
248
|
covariance (np.ndarray): Covariance of the state distribution (8x8 dimensional).
|
|
255
|
-
measurements (np.ndarray): An (N, 4) matrix of N measurements, each in format (x, y, a, h) where (x, y) is
|
|
256
|
-
bounding box center position, a the aspect ratio, and h the height.
|
|
257
|
-
only_position (bool): If True, distance computation is done with respect to box center position
|
|
258
|
-
|
|
259
|
-
|
|
249
|
+
measurements (np.ndarray): An (N, 4) matrix of N measurements, each in format (x, y, a, h) where (x, y) is
|
|
250
|
+
the bounding box center position, a the aspect ratio, and h the height.
|
|
251
|
+
only_position (bool, optional): If True, distance computation is done with respect to box center position
|
|
252
|
+
only.
|
|
253
|
+
metric (str, optional): The metric to use for calculating the distance. Options are 'gaussian' for the
|
|
254
|
+
squared Euclidean distance and 'maha' for the squared Mahalanobis distance.
|
|
260
255
|
|
|
261
256
|
Returns:
|
|
262
257
|
(np.ndarray): Returns an array of length N, where the i-th element contains the squared distance between
|
|
@@ -287,12 +282,11 @@ class KalmanFilterXYAH:
|
|
|
287
282
|
|
|
288
283
|
|
|
289
284
|
class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
290
|
-
"""
|
|
291
|
-
A KalmanFilterXYWH class for tracking bounding boxes in image space using a Kalman filter.
|
|
285
|
+
"""A KalmanFilterXYWH class for tracking bounding boxes in image space using a Kalman filter.
|
|
292
286
|
|
|
293
|
-
Implements a Kalman filter for tracking bounding boxes with state space (x, y, w, h, vx, vy, vw, vh), where
|
|
294
|
-
|
|
295
|
-
|
|
287
|
+
Implements a Kalman filter for tracking bounding boxes with state space (x, y, w, h, vx, vy, vw, vh), where (x, y)
|
|
288
|
+
is the center position, w is the width, h is the height, and vx, vy, vw, vh are their respective velocities. The
|
|
289
|
+
object motion follows a constant velocity model, and the bounding box location (x, y, w, h) is taken as a direct
|
|
296
290
|
observation of the state space (linear observation model).
|
|
297
291
|
|
|
298
292
|
Attributes:
|
|
@@ -302,11 +296,11 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
302
296
|
_std_weight_velocity (float): Standard deviation weight for velocity.
|
|
303
297
|
|
|
304
298
|
Methods:
|
|
305
|
-
initiate:
|
|
306
|
-
predict:
|
|
307
|
-
project:
|
|
308
|
-
multi_predict:
|
|
309
|
-
update:
|
|
299
|
+
initiate: Create a track from an unassociated measurement.
|
|
300
|
+
predict: Run the Kalman filter prediction step.
|
|
301
|
+
project: Project the state distribution to measurement space.
|
|
302
|
+
multi_predict: Run the Kalman filter prediction step in a vectorized manner.
|
|
303
|
+
update: Run the Kalman filter correction step.
|
|
310
304
|
|
|
311
305
|
Examples:
|
|
312
306
|
Create a Kalman filter and initialize a track
|
|
@@ -318,15 +312,16 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
318
312
|
"""
|
|
319
313
|
|
|
320
314
|
def initiate(self, measurement: np.ndarray):
|
|
321
|
-
"""
|
|
322
|
-
Create track from unassociated measurement.
|
|
315
|
+
"""Create track from unassociated measurement.
|
|
323
316
|
|
|
324
317
|
Args:
|
|
325
|
-
measurement (np.ndarray): Bounding box coordinates (x, y, w, h) with center position (x, y), width, and
|
|
318
|
+
measurement (np.ndarray): Bounding box coordinates (x, y, w, h) with center position (x, y), width, and
|
|
319
|
+
height.
|
|
326
320
|
|
|
327
321
|
Returns:
|
|
328
|
-
(np.ndarray): Mean vector (8 dimensional) of the new track. Unobserved velocities are initialized to 0
|
|
329
|
-
|
|
322
|
+
mean (np.ndarray): Mean vector (8 dimensional) of the new track. Unobserved velocities are initialized to 0
|
|
323
|
+
mean.
|
|
324
|
+
covariance (np.ndarray): Covariance matrix (8x8 dimensional) of the new track.
|
|
330
325
|
|
|
331
326
|
Examples:
|
|
332
327
|
>>> kf = KalmanFilterXYWH()
|
|
@@ -361,17 +356,17 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
361
356
|
covariance = np.diag(np.square(std))
|
|
362
357
|
return mean, covariance
|
|
363
358
|
|
|
364
|
-
def predict(self, mean, covariance):
|
|
365
|
-
"""
|
|
366
|
-
Run Kalman filter prediction step.
|
|
359
|
+
def predict(self, mean: np.ndarray, covariance: np.ndarray):
|
|
360
|
+
"""Run Kalman filter prediction step.
|
|
367
361
|
|
|
368
362
|
Args:
|
|
369
363
|
mean (np.ndarray): The 8-dimensional mean vector of the object state at the previous time step.
|
|
370
|
-
covariance (np.ndarray): The 8x8-dimensional covariance matrix of the object state at the previous time
|
|
364
|
+
covariance (np.ndarray): The 8x8-dimensional covariance matrix of the object state at the previous time
|
|
365
|
+
step.
|
|
371
366
|
|
|
372
367
|
Returns:
|
|
373
|
-
(np.ndarray): Mean vector of the predicted state. Unobserved velocities are initialized to 0 mean.
|
|
374
|
-
(np.ndarray): Covariance matrix of the predicted state.
|
|
368
|
+
mean (np.ndarray): Mean vector of the predicted state. Unobserved velocities are initialized to 0 mean.
|
|
369
|
+
covariance (np.ndarray): Covariance matrix of the predicted state.
|
|
375
370
|
|
|
376
371
|
Examples:
|
|
377
372
|
>>> kf = KalmanFilterXYWH()
|
|
@@ -398,17 +393,16 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
398
393
|
|
|
399
394
|
return mean, covariance
|
|
400
395
|
|
|
401
|
-
def project(self, mean, covariance):
|
|
402
|
-
"""
|
|
403
|
-
Project state distribution to measurement space.
|
|
396
|
+
def project(self, mean: np.ndarray, covariance: np.ndarray):
|
|
397
|
+
"""Project state distribution to measurement space.
|
|
404
398
|
|
|
405
399
|
Args:
|
|
406
400
|
mean (np.ndarray): The state's mean vector (8 dimensional array).
|
|
407
401
|
covariance (np.ndarray): The state's covariance matrix (8x8 dimensional).
|
|
408
402
|
|
|
409
403
|
Returns:
|
|
410
|
-
(np.ndarray): Projected mean of the given state estimate.
|
|
411
|
-
(np.ndarray): Projected covariance matrix of the given state estimate.
|
|
404
|
+
mean (np.ndarray): Projected mean of the given state estimate.
|
|
405
|
+
covariance (np.ndarray): Projected covariance matrix of the given state estimate.
|
|
412
406
|
|
|
413
407
|
Examples:
|
|
414
408
|
>>> kf = KalmanFilterXYWH()
|
|
@@ -428,17 +422,16 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
428
422
|
covariance = np.linalg.multi_dot((self._update_mat, covariance, self._update_mat.T))
|
|
429
423
|
return mean, covariance + innovation_cov
|
|
430
424
|
|
|
431
|
-
def multi_predict(self, mean, covariance):
|
|
432
|
-
"""
|
|
433
|
-
Run Kalman filter prediction step (Vectorized version).
|
|
425
|
+
def multi_predict(self, mean: np.ndarray, covariance: np.ndarray):
|
|
426
|
+
"""Run Kalman filter prediction step (Vectorized version).
|
|
434
427
|
|
|
435
428
|
Args:
|
|
436
429
|
mean (np.ndarray): The Nx8 dimensional mean matrix of the object states at the previous time step.
|
|
437
430
|
covariance (np.ndarray): The Nx8x8 covariance matrix of the object states at the previous time step.
|
|
438
431
|
|
|
439
432
|
Returns:
|
|
440
|
-
(np.ndarray): Mean matrix of the predicted states with shape (N, 8).
|
|
441
|
-
(np.ndarray): Covariance matrix of the predicted states with shape (N, 8, 8).
|
|
433
|
+
mean (np.ndarray): Mean matrix of the predicted states with shape (N, 8).
|
|
434
|
+
covariance (np.ndarray): Covariance matrix of the predicted states with shape (N, 8, 8).
|
|
442
435
|
|
|
443
436
|
Examples:
|
|
444
437
|
>>> mean = np.random.rand(5, 8) # 5 objects with 8-dimensional state vectors
|
|
@@ -469,9 +462,8 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
469
462
|
|
|
470
463
|
return mean, covariance
|
|
471
464
|
|
|
472
|
-
def update(self, mean, covariance, measurement):
|
|
473
|
-
"""
|
|
474
|
-
Run Kalman filter correction step.
|
|
465
|
+
def update(self, mean: np.ndarray, covariance: np.ndarray, measurement: np.ndarray):
|
|
466
|
+
"""Run Kalman filter correction step.
|
|
475
467
|
|
|
476
468
|
Args:
|
|
477
469
|
mean (np.ndarray): The predicted state's mean vector (8 dimensional).
|
|
@@ -480,8 +472,8 @@ class KalmanFilterXYWH(KalmanFilterXYAH):
|
|
|
480
472
|
position, w the width, and h the height of the bounding box.
|
|
481
473
|
|
|
482
474
|
Returns:
|
|
483
|
-
(np.ndarray): Measurement-corrected state mean.
|
|
484
|
-
(np.ndarray): Measurement-corrected state covariance.
|
|
475
|
+
new_mean (np.ndarray): Measurement-corrected state mean.
|
|
476
|
+
new_covariance (np.ndarray): Measurement-corrected state covariance.
|
|
485
477
|
|
|
486
478
|
Examples:
|
|
487
479
|
>>> kf = KalmanFilterXYWH()
|
|
@@ -17,9 +17,8 @@ except (ImportError, AssertionError, AttributeError):
|
|
|
17
17
|
import lap
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def linear_assignment(cost_matrix: np.ndarray, thresh: float, use_lap: bool = True)
|
|
21
|
-
"""
|
|
22
|
-
Perform linear assignment using either the scipy or lap.lapjv method.
|
|
20
|
+
def linear_assignment(cost_matrix: np.ndarray, thresh: float, use_lap: bool = True):
|
|
21
|
+
"""Perform linear assignment using either the scipy or lap.lapjv method.
|
|
23
22
|
|
|
24
23
|
Args:
|
|
25
24
|
cost_matrix (np.ndarray): The matrix containing cost values for assignments, with shape (N, M).
|
|
@@ -62,12 +61,11 @@ def linear_assignment(cost_matrix: np.ndarray, thresh: float, use_lap: bool = Tr
|
|
|
62
61
|
|
|
63
62
|
|
|
64
63
|
def iou_distance(atracks: list, btracks: list) -> np.ndarray:
|
|
65
|
-
"""
|
|
66
|
-
Compute cost based on Intersection over Union (IoU) between tracks.
|
|
64
|
+
"""Compute cost based on Intersection over Union (IoU) between tracks.
|
|
67
65
|
|
|
68
66
|
Args:
|
|
69
|
-
atracks (
|
|
70
|
-
btracks (
|
|
67
|
+
atracks (list[STrack] | list[np.ndarray]): List of tracks 'a' or bounding boxes.
|
|
68
|
+
btracks (list[STrack] | list[np.ndarray]): List of tracks 'b' or bounding boxes.
|
|
71
69
|
|
|
72
70
|
Returns:
|
|
73
71
|
(np.ndarray): Cost matrix computed based on IoU with shape (len(atracks), len(btracks)).
|
|
@@ -78,7 +76,7 @@ def iou_distance(atracks: list, btracks: list) -> np.ndarray:
|
|
|
78
76
|
>>> btracks = [np.array([5, 5, 15, 15]), np.array([25, 25, 35, 35])]
|
|
79
77
|
>>> cost_matrix = iou_distance(atracks, btracks)
|
|
80
78
|
"""
|
|
81
|
-
if atracks and isinstance(atracks[0], np.ndarray) or btracks and isinstance(btracks[0], np.ndarray):
|
|
79
|
+
if (atracks and isinstance(atracks[0], np.ndarray)) or (btracks and isinstance(btracks[0], np.ndarray)):
|
|
82
80
|
atlbrs = atracks
|
|
83
81
|
btlbrs = btracks
|
|
84
82
|
else:
|
|
@@ -102,17 +100,16 @@ def iou_distance(atracks: list, btracks: list) -> np.ndarray:
|
|
|
102
100
|
|
|
103
101
|
|
|
104
102
|
def embedding_distance(tracks: list, detections: list, metric: str = "cosine") -> np.ndarray:
|
|
105
|
-
"""
|
|
106
|
-
Compute distance between tracks and detections based on embeddings.
|
|
103
|
+
"""Compute distance between tracks and detections based on embeddings.
|
|
107
104
|
|
|
108
105
|
Args:
|
|
109
|
-
tracks (
|
|
110
|
-
detections (
|
|
106
|
+
tracks (list[STrack]): List of tracks, where each track contains embedding features.
|
|
107
|
+
detections (list[BaseTrack]): List of detections, where each detection contains embedding features.
|
|
111
108
|
metric (str): Metric for distance computation. Supported metrics include 'cosine', 'euclidean', etc.
|
|
112
109
|
|
|
113
110
|
Returns:
|
|
114
|
-
(np.ndarray): Cost matrix computed based on embeddings with shape (N, M), where N is the number of tracks
|
|
115
|
-
|
|
111
|
+
(np.ndarray): Cost matrix computed based on embeddings with shape (N, M), where N is the number of tracks and M
|
|
112
|
+
is the number of detections.
|
|
116
113
|
|
|
117
114
|
Examples:
|
|
118
115
|
Compute the embedding distance between tracks and detections using cosine metric
|
|
@@ -132,12 +129,11 @@ def embedding_distance(tracks: list, detections: list, metric: str = "cosine") -
|
|
|
132
129
|
|
|
133
130
|
|
|
134
131
|
def fuse_score(cost_matrix: np.ndarray, detections: list) -> np.ndarray:
|
|
135
|
-
"""
|
|
136
|
-
Fuse cost matrix with detection scores to produce a single similarity matrix.
|
|
132
|
+
"""Fuse cost matrix with detection scores to produce a single similarity matrix.
|
|
137
133
|
|
|
138
134
|
Args:
|
|
139
135
|
cost_matrix (np.ndarray): The matrix containing cost values for assignments, with shape (N, M).
|
|
140
|
-
detections (
|
|
136
|
+
detections (list[BaseTrack]): List of detections, each containing a score attribute.
|
|
141
137
|
|
|
142
138
|
Returns:
|
|
143
139
|
(np.ndarray): Fused similarity matrix with shape (N, M).
|