updateTracker method
Updates multi-barcode spatial tracker with newly detected frame barcodes.
Enhanced v3.0: uses exponential smoothing for bounding box positions to reduce jitter in live camera feeds.
Implementation
List<TrackedBarcode> updateTracker(List<BarcodeResult> frameBarcodes) {
final now = DateTime.now();
final updatedKeys = <String>{};
for (final b in frameBarcodes) {
final bBox = b.boundingBox ?? Rect.zero;
final centerB = bBox.center;
String? matchedId;
double minCenterDist = double.infinity;
// Find closest existing track with matching payload
for (final track in _activeTracks.values) {
if (track.rawValue == b.rawValue) {
final dist = (track.boundingBox.center - centerB).distance;
if (dist < 150.0 && dist < minCenterDist) {
minCenterDist = dist;
matchedId = track.id;
}
}
}
if (matchedId != null) {
final existing = _activeTracks[matchedId]!;
// Exponential smoothing for bounding box (α = 0.3)
const alpha = 0.3;
final smoothedBox = Rect.fromLTRB(
existing.boundingBox.left * (1 - alpha) + bBox.left * alpha,
existing.boundingBox.top * (1 - alpha) + bBox.top * alpha,
existing.boundingBox.right * (1 - alpha) + bBox.right * alpha,
existing.boundingBox.bottom * (1 - alpha) + bBox.bottom * alpha,
);
_activeTracks[matchedId] = existing.copyWith(
boundingBox: smoothedBox,
corners: b.corners ?? existing.corners,
lastSeenTime: now,
hitCount: existing.hitCount + 1,
);
updatedKeys.add(matchedId);
} else {
final newId = 'track_${_nextId++}';
_activeTracks[newId] = TrackedBarcode(
id: newId,
rawValue: b.rawValue,
format: b.format,
boundingBox: bBox,
corners: b.corners ?? [],
firstDetectedTime: now,
lastSeenTime: now,
);
updatedKeys.add(newId);
}
}
// Prune tracks not seen in last 2 seconds (up from 1.5s for better stability)
_activeTracks.removeWhere((id, track) {
return !updatedKeys.contains(id) &&
now.difference(track.lastSeenTime).inMilliseconds > 2000;
});
return _activeTracks.values.toList();
}