Skip to content

Commit e06f79f

Browse files
used the latest classification features vector instead of the detection similarity vecto
1 parent bd25319 commit e06f79f

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

ami/ml/models/pipeline.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,8 @@ def save_results(
887887
# logger=job_logger,
888888
# )
889889
job_logger.info(f"Creating occurrences for {len(detections)} detections ")
890+
job_logger.info("type logger: " + str(type(job_logger)))
891+
890892
assign_occurrences_by_tracking(detections=detections, logger=job_logger)
891893

892894
# Update precalculated counts on source images and events

ami/ml/tracking.py

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import logging
21
import math
32
from collections import defaultdict
43
from collections.abc import Iterable
@@ -7,9 +6,7 @@
76

87
from ami.main.models import Detection, Occurrence
98

10-
logger = logging.getLogger(__name__)
11-
12-
TRACKING_COST_THRESHOLD = 0.25
9+
TRACKING_COST_THRESHOLD = 2
1310

1411

1512
def cosine_similarity(v1: Iterable[float], v2: Iterable[float]) -> float:
@@ -60,48 +57,68 @@ def total_cost(f1, f2, bb1, bb2, diag):
6057
)
6158

6259

60+
def get_latest_feature_vector(detection: Detection):
61+
return (
62+
detection.classifications.filter(features_2048__isnull=False)
63+
.order_by("-timestamp")
64+
.values_list("features_2048", flat=True)
65+
.first()
66+
)
67+
68+
6369
def assign_occurrences_by_tracking(
6470
detections: list[Detection],
65-
logger: logging.Logger,
71+
logger,
6672
) -> None:
6773
"""
6874
Perform object tracking by assigning detections across multiple source images
69-
to the same Occurrence if they are similar enough.
75+
to the same Occurrence if they are similar enough, based on the latest classification feature vectors.
7076
"""
71-
logger.info(f"Starting to assign occurrences by tracking.{len(detections)} detections found.")
72-
# Group detections by source image and sort
77+
logger.info(f"Starting to assign occurrences by tracking. {len(detections)} detections found.")
78+
79+
# Group detections by source image timestamp
7380
image_to_dets = defaultdict(list)
7481
for det in detections:
7582
image_to_dets[det.source_image.timestamp].append(det)
76-
sorted_images = sorted(image_to_dets.keys())
77-
logger.info(f"Found {len(sorted_images)} source images with detections.")
83+
sorted_timestamps = sorted(image_to_dets.keys())
84+
logger.info(f"Found {len(sorted_timestamps)} source images with detections.")
85+
7886
last_detections = []
7987

80-
for t in sorted_images:
81-
current_detections = image_to_dets[t]
82-
logger.info(f"Processing {len(current_detections)} detections at {t}")
88+
for timestamp in sorted_timestamps:
89+
current_detections = image_to_dets[timestamp]
90+
logger.info(f"Processing {len(current_detections)} detections at {timestamp}")
91+
8392
for det in current_detections:
93+
det_vec = get_latest_feature_vector(det)
94+
if det_vec is None:
95+
logger.info(f"No features for detection {det.id}, skipping.")
96+
continue
97+
8498
best_match = None
8599
best_cost = float("inf")
86100

87101
for prev in last_detections:
88-
if prev.similarity_vector is None or det.similarity_vector is None:
102+
prev_vec = get_latest_feature_vector(prev)
103+
if prev_vec is None:
89104
continue
90105

91106
cost = total_cost(
92-
det.similarity_vector,
93-
prev.similarity_vector,
107+
det_vec,
108+
prev_vec,
94109
det.bbox,
95110
prev.bbox,
96111
image_diagonal(det.source_image.width, det.source_image.height),
97112
)
98113

114+
logger.info(f"Comparing detection {det.id} with previous {prev.id}: cost = {cost:.4f}")
99115
if cost < best_cost:
100116
best_cost = cost
101117
best_match = prev
102118

103119
if best_match and best_cost < TRACKING_COST_THRESHOLD:
104120
det.occurrence = best_match.occurrence
121+
logger.info(f"Assigned detection {det.id} to existing occurrence {best_match.occurrence.pk}")
105122
else:
106123
occurrence = Occurrence.objects.create(event=det.source_image.event)
107124
det.occurrence = occurrence

0 commit comments

Comments
 (0)