@scanly/browser 2.0.0
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.
- package/README.md +3 -0
- package/dist/batch/batch-controller.d.ts +71 -0
- package/dist/batch/batch-controller.d.ts.map +1 -0
- package/dist/batch/batch-controller.js +422 -0
- package/dist/batch/batch-controller.js.map +1 -0
- package/dist/batch/batch-session.d.ts +53 -0
- package/dist/batch/batch-session.d.ts.map +1 -0
- package/dist/batch/batch-session.js +267 -0
- package/dist/batch/batch-session.js.map +1 -0
- package/dist/batch/index.d.ts +4 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +4 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/batch/types.d.ts +101 -0
- package/dist/batch/types.d.ts.map +1 -0
- package/dist/batch/types.js +2 -0
- package/dist/batch/types.js.map +1 -0
- package/dist/browser-session.d.ts +51 -0
- package/dist/browser-session.d.ts.map +1 -0
- package/dist/browser-session.js +168 -0
- package/dist/browser-session.js.map +1 -0
- package/dist/camera-source.d.ts +89 -0
- package/dist/camera-source.d.ts.map +1 -0
- package/dist/camera-source.js +366 -0
- package/dist/camera-source.js.map +1 -0
- package/dist/camera-strategy.d.ts +36 -0
- package/dist/camera-strategy.d.ts.map +1 -0
- package/dist/camera-strategy.js +94 -0
- package/dist/camera-strategy.js.map +1 -0
- package/dist/decode-upload.d.ts +13 -0
- package/dist/decode-upload.d.ts.map +1 -0
- package/dist/decode-upload.js +23 -0
- package/dist/decode-upload.js.map +1 -0
- package/dist/image-loader.d.ts +11 -0
- package/dist/image-loader.d.ts.map +1 -0
- package/dist/image-loader.js +63 -0
- package/dist/image-loader.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +14 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scanner/camera-capabilities.d.ts +20 -0
- package/dist/scanner/camera-capabilities.d.ts.map +1 -0
- package/dist/scanner/camera-capabilities.js +181 -0
- package/dist/scanner/camera-capabilities.js.map +1 -0
- package/dist/scanner/camera-platform.d.ts +75 -0
- package/dist/scanner/camera-platform.d.ts.map +1 -0
- package/dist/scanner/camera-platform.js +145 -0
- package/dist/scanner/camera-platform.js.map +1 -0
- package/dist/scanner/decode-escalation.d.ts +20 -0
- package/dist/scanner/decode-escalation.d.ts.map +1 -0
- package/dist/scanner/decode-escalation.js +40 -0
- package/dist/scanner/decode-escalation.js.map +1 -0
- package/dist/scanner/frame-quality.d.ts +24 -0
- package/dist/scanner/frame-quality.d.ts.map +1 -0
- package/dist/scanner/frame-quality.js +90 -0
- package/dist/scanner/frame-quality.js.map +1 -0
- package/dist/scanner/frame-scheduler.d.ts +59 -0
- package/dist/scanner/frame-scheduler.d.ts.map +1 -0
- package/dist/scanner/frame-scheduler.js +148 -0
- package/dist/scanner/frame-scheduler.js.map +1 -0
- package/dist/scanner/frame-source.d.ts +70 -0
- package/dist/scanner/frame-source.d.ts.map +1 -0
- package/dist/scanner/frame-source.js +263 -0
- package/dist/scanner/frame-source.js.map +1 -0
- package/dist/scanner/index.d.ts +12 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +12 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/repeat-suppressor.d.ts +23 -0
- package/dist/scanner/repeat-suppressor.d.ts.map +1 -0
- package/dist/scanner/repeat-suppressor.js +69 -0
- package/dist/scanner/repeat-suppressor.js.map +1 -0
- package/dist/scanner/scanner-session.d.ts +160 -0
- package/dist/scanner/scanner-session.d.ts.map +1 -0
- package/dist/scanner/scanner-session.js +766 -0
- package/dist/scanner/scanner-session.js.map +1 -0
- package/dist/scanner/temporal-confirmation.d.ts +30 -0
- package/dist/scanner/temporal-confirmation.d.ts.map +1 -0
- package/dist/scanner/temporal-confirmation.js +71 -0
- package/dist/scanner/temporal-confirmation.js.map +1 -0
- package/dist/scanner/temporal-roi.d.ts +27 -0
- package/dist/scanner/temporal-roi.d.ts.map +1 -0
- package/dist/scanner/temporal-roi.js +50 -0
- package/dist/scanner/temporal-roi.js.map +1 -0
- package/dist/scanner/types.d.ts +232 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +2 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/tracking/barcode-tracker.d.ts +28 -0
- package/dist/tracking/barcode-tracker.d.ts.map +1 -0
- package/dist/tracking/barcode-tracker.js +279 -0
- package/dist/tracking/barcode-tracker.js.map +1 -0
- package/dist/tracking/geometry.d.ts +13 -0
- package/dist/tracking/geometry.d.ts.map +1 -0
- package/dist/tracking/geometry.js +51 -0
- package/dist/tracking/geometry.js.map +1 -0
- package/dist/tracking/index.d.ts +8 -0
- package/dist/tracking/index.d.ts.map +1 -0
- package/dist/tracking/index.js +8 -0
- package/dist/tracking/index.js.map +1 -0
- package/dist/tracking/scanner-tracking-runtime.d.ts +45 -0
- package/dist/tracking/scanner-tracking-runtime.d.ts.map +1 -0
- package/dist/tracking/scanner-tracking-runtime.js +93 -0
- package/dist/tracking/scanner-tracking-runtime.js.map +1 -0
- package/dist/tracking/track-association.d.ts +19 -0
- package/dist/tracking/track-association.d.ts.map +1 -0
- package/dist/tracking/track-association.js +191 -0
- package/dist/tracking/track-association.js.map +1 -0
- package/dist/tracking/track-overlay.d.ts +4 -0
- package/dist/tracking/track-overlay.d.ts.map +1 -0
- package/dist/tracking/track-overlay.js +16 -0
- package/dist/tracking/track-overlay.js.map +1 -0
- package/dist/tracking/track-roi-set.d.ts +17 -0
- package/dist/tracking/track-roi-set.d.ts.map +1 -0
- package/dist/tracking/track-roi-set.js +119 -0
- package/dist/tracking/track-roi-set.js.map +1 -0
- package/dist/tracking/types.d.ts +154 -0
- package/dist/tracking/types.d.ts.map +1 -0
- package/dist/tracking/types.js +2 -0
- package/dist/tracking/types.js.map +1 -0
- package/dist/worker/decode-worker.d.ts +2 -0
- package/dist/worker/decode-worker.d.ts.map +1 -0
- package/dist/worker/decode-worker.js +84 -0
- package/dist/worker/decode-worker.js.map +1 -0
- package/dist/worker/transferable-buffer.d.ts +18 -0
- package/dist/worker/transferable-buffer.d.ts.map +1 -0
- package/dist/worker/transferable-buffer.js +24 -0
- package/dist/worker/transferable-buffer.js.map +1 -0
- package/dist/worker/worker-client.d.ts +86 -0
- package/dist/worker/worker-client.d.ts.map +1 -0
- package/dist/worker/worker-client.js +286 -0
- package/dist/worker/worker-client.js.map +1 -0
- package/dist/worker/worker-messages.d.ts +75 -0
- package/dist/worker/worker-messages.d.ts.map +1 -0
- package/dist/worker/worker-messages.js +244 -0
- package/dist/worker/worker-messages.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { geometryArea, geometryCenter, geometryDistanceScale, geometryIoU } from "./geometry.js";
|
|
2
|
+
export const DEFAULT_ASSOCIATION_THRESHOLD = 2.5;
|
|
3
|
+
export const DEFAULT_ASSOCIATION_WEIGHTS = Object.freeze({
|
|
4
|
+
// Compatibility weights remain explicit in the public cost schema, while
|
|
5
|
+
// the semantic eligibility gate below takes precedence over every weight.
|
|
6
|
+
payloadMismatch: 8,
|
|
7
|
+
formatMismatch: 8,
|
|
8
|
+
spatialDistance: 0.9,
|
|
9
|
+
iouPenalty: 0.35,
|
|
10
|
+
geometrySize: 0.25,
|
|
11
|
+
// Prediction helps at crossings, but current geometry has the larger weight.
|
|
12
|
+
motionPrediction: 0.7,
|
|
13
|
+
timeSinceObservation: 0.08,
|
|
14
|
+
});
|
|
15
|
+
export function calculateAssociationCost(track, observation, frameId, options = {}) {
|
|
16
|
+
// Payload and format identify what was decoded, not merely how expensive a
|
|
17
|
+
// spatial association should be. A semantic mismatch is never a candidate,
|
|
18
|
+
// even when callers deliberately raise the threshold or zero custom weights.
|
|
19
|
+
if (track.payload !== observation.payload || track.format !== observation.format) {
|
|
20
|
+
return Number.POSITIVE_INFINITY;
|
|
21
|
+
}
|
|
22
|
+
const weights = resolveWeights(options.weights);
|
|
23
|
+
const currentCenter = geometryCenter(track.geometry);
|
|
24
|
+
const observedCenter = geometryCenter(observation.geometry);
|
|
25
|
+
const elapsedFrames = Math.max(1, frameId - track.lastFrameId);
|
|
26
|
+
const predictedCenter = track.velocity
|
|
27
|
+
? {
|
|
28
|
+
x: currentCenter.x + track.velocity.x * elapsedFrames,
|
|
29
|
+
y: currentCenter.y + track.velocity.y * elapsedFrames,
|
|
30
|
+
}
|
|
31
|
+
: currentCenter;
|
|
32
|
+
const scale = geometryDistanceScale(track.geometry, observation.geometry);
|
|
33
|
+
const spatialDistance = Math.hypot(observedCenter.x - currentCenter.x, observedCenter.y - currentCenter.y) / scale;
|
|
34
|
+
const predictionDistance = Math.hypot(observedCenter.x - predictedCenter.x, observedCenter.y - predictedCenter.y) / scale;
|
|
35
|
+
const directionConflict = motionDirectionConflict(track, currentCenter, observedCenter, elapsedFrames);
|
|
36
|
+
const sizePenalty = Math.min(4, Math.abs(Math.log(geometryArea(observation.geometry) / geometryArea(track.geometry))));
|
|
37
|
+
const elapsedTimeFrames = options.timestamp === undefined
|
|
38
|
+
? 0
|
|
39
|
+
: Math.max(0, (options.timestamp - track.lastSeenAt) / positive(options.nominalFrameDurationMs, 1000 / 30) - 1);
|
|
40
|
+
const missingFrames = Math.max(track.missedFrameCount, frameId - track.lastFrameId - 1, elapsedTimeFrames);
|
|
41
|
+
const cost = spatialDistance * weights.spatialDistance
|
|
42
|
+
+ (1 - geometryIoU(track.geometry, observation.geometry)) * weights.iouPenalty
|
|
43
|
+
+ sizePenalty * weights.geometrySize
|
|
44
|
+
+ (predictionDistance + directionConflict) * weights.motionPrediction
|
|
45
|
+
+ missingFrames * weights.timeSinceObservation;
|
|
46
|
+
return Number.isFinite(cost) ? cost : Number.MAX_SAFE_INTEGER;
|
|
47
|
+
}
|
|
48
|
+
function motionDirectionConflict(track, current, observed, elapsedFrames) {
|
|
49
|
+
if (!track.velocity)
|
|
50
|
+
return 0;
|
|
51
|
+
const expectedX = track.velocity.x * elapsedFrames;
|
|
52
|
+
const expectedY = track.velocity.y * elapsedFrames;
|
|
53
|
+
const expectedMagnitude = Math.hypot(expectedX, expectedY);
|
|
54
|
+
if (expectedMagnitude <= Number.EPSILON)
|
|
55
|
+
return 0;
|
|
56
|
+
const actualX = observed.x - current.x;
|
|
57
|
+
const actualY = observed.y - current.y;
|
|
58
|
+
const actualMagnitude = Math.hypot(actualX, actualY);
|
|
59
|
+
// At a crossing, choosing the other object often looks like an implausible
|
|
60
|
+
// stop at the previous position. Preserve that evidence without rejecting a
|
|
61
|
+
// real stop outright: this is a soft cost and remains under the threshold.
|
|
62
|
+
if (actualMagnitude < expectedMagnitude * 0.25)
|
|
63
|
+
return 1;
|
|
64
|
+
const cosine = Math.max(-1, Math.min(1, (actualX * expectedX + actualY * expectedY) / (actualMagnitude * expectedMagnitude)));
|
|
65
|
+
return (1 - cosine) / 2;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Globally minimizes the bounded track/observation cost matrix. Dummy columns
|
|
69
|
+
* model an unmatched track, so an over-threshold pair can never steal a valid
|
|
70
|
+
* observation from another track.
|
|
71
|
+
*/
|
|
72
|
+
export function associateTracks(tracks, observations, frameId, options = {}) {
|
|
73
|
+
const threshold = nonNegative(options.threshold, DEFAULT_ASSOCIATION_THRESHOLD);
|
|
74
|
+
const costMatrix = tracks.map((track) => observations.map((observation) => calculateAssociationCost(track, observation, frameId, options)));
|
|
75
|
+
if (tracks.length === 0 || observations.length === 0) {
|
|
76
|
+
return {
|
|
77
|
+
matches: [],
|
|
78
|
+
unmatchedTrackIndices: tracks.map((_, index) => index),
|
|
79
|
+
unmatchedObservationIndices: observations.map((_, index) => index),
|
|
80
|
+
costMatrix,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// One dummy column per track guarantees columns >= rows and permits every
|
|
84
|
+
// row to choose the unmatched cost independently.
|
|
85
|
+
const assignmentMatrix = costMatrix.map((row) => [
|
|
86
|
+
...row,
|
|
87
|
+
...Array.from({ length: tracks.length }, () => threshold),
|
|
88
|
+
]);
|
|
89
|
+
const assignedColumns = hungarianRowsToColumns(assignmentMatrix);
|
|
90
|
+
const matchedObservations = new Set();
|
|
91
|
+
const matches = assignedColumns.flatMap((column, trackIndex) => {
|
|
92
|
+
if (column < 0 || column >= observations.length)
|
|
93
|
+
return [];
|
|
94
|
+
const track = tracks[trackIndex];
|
|
95
|
+
const observation = observations[column];
|
|
96
|
+
if (!track || !observation || track.payload !== observation.payload || track.format !== observation.format)
|
|
97
|
+
return [];
|
|
98
|
+
const cost = costMatrix[trackIndex]?.[column] ?? Number.MAX_SAFE_INTEGER;
|
|
99
|
+
if (!Number.isFinite(cost) || cost > threshold)
|
|
100
|
+
return [];
|
|
101
|
+
matchedObservations.add(column);
|
|
102
|
+
return [{ trackIndex, observationIndex: column, cost }];
|
|
103
|
+
});
|
|
104
|
+
const matchedTracks = new Set(matches.map((match) => match.trackIndex));
|
|
105
|
+
return {
|
|
106
|
+
matches,
|
|
107
|
+
unmatchedTrackIndices: tracks.map((_, index) => index).filter((index) => !matchedTracks.has(index)),
|
|
108
|
+
unmatchedObservationIndices: observations.map((_, index) => index).filter((index) => !matchedObservations.has(index)),
|
|
109
|
+
costMatrix,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function resolveWeights(input) {
|
|
113
|
+
return {
|
|
114
|
+
payloadMismatch: nonNegative(input?.payloadMismatch, DEFAULT_ASSOCIATION_WEIGHTS.payloadMismatch),
|
|
115
|
+
formatMismatch: nonNegative(input?.formatMismatch, DEFAULT_ASSOCIATION_WEIGHTS.formatMismatch),
|
|
116
|
+
spatialDistance: nonNegative(input?.spatialDistance, DEFAULT_ASSOCIATION_WEIGHTS.spatialDistance),
|
|
117
|
+
iouPenalty: nonNegative(input?.iouPenalty, DEFAULT_ASSOCIATION_WEIGHTS.iouPenalty),
|
|
118
|
+
geometrySize: nonNegative(input?.geometrySize, DEFAULT_ASSOCIATION_WEIGHTS.geometrySize),
|
|
119
|
+
motionPrediction: nonNegative(input?.motionPrediction, DEFAULT_ASSOCIATION_WEIGHTS.motionPrediction),
|
|
120
|
+
timeSinceObservation: nonNegative(input?.timeSinceObservation, DEFAULT_ASSOCIATION_WEIGHTS.timeSinceObservation),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function nonNegative(value, fallback) {
|
|
124
|
+
return value === undefined || !Number.isFinite(value) ? fallback : Math.max(0, value);
|
|
125
|
+
}
|
|
126
|
+
function positive(value, fallback) {
|
|
127
|
+
return value === undefined || !Number.isFinite(value) ? fallback : Math.max(Number.EPSILON, value);
|
|
128
|
+
}
|
|
129
|
+
/** Hungarian minimum-cost assignment for a finite matrix with rows <= columns. */
|
|
130
|
+
function hungarianRowsToColumns(matrix) {
|
|
131
|
+
const rowCount = matrix.length;
|
|
132
|
+
const columnCount = matrix[0]?.length ?? 0;
|
|
133
|
+
if (rowCount === 0)
|
|
134
|
+
return [];
|
|
135
|
+
if (columnCount < rowCount)
|
|
136
|
+
throw new RangeError("Hungarian assignment requires at least as many columns as rows.");
|
|
137
|
+
const rowPotential = new Array(rowCount + 1).fill(0);
|
|
138
|
+
const columnPotential = new Array(columnCount + 1).fill(0);
|
|
139
|
+
const columnMatch = new Array(columnCount + 1).fill(0);
|
|
140
|
+
const predecessor = new Array(columnCount + 1).fill(0);
|
|
141
|
+
for (let row = 1; row <= rowCount; row += 1) {
|
|
142
|
+
columnMatch[0] = row;
|
|
143
|
+
let currentColumn = 0;
|
|
144
|
+
const minimum = new Array(columnCount + 1).fill(Number.POSITIVE_INFINITY);
|
|
145
|
+
const used = new Array(columnCount + 1).fill(false);
|
|
146
|
+
do {
|
|
147
|
+
used[currentColumn] = true;
|
|
148
|
+
const currentRow = columnMatch[currentColumn] ?? 0;
|
|
149
|
+
let delta = Number.POSITIVE_INFINITY;
|
|
150
|
+
let nextColumn = 0;
|
|
151
|
+
for (let column = 1; column <= columnCount; column += 1) {
|
|
152
|
+
if (used[column])
|
|
153
|
+
continue;
|
|
154
|
+
const raw = matrix[currentRow - 1]?.[column - 1] ?? Number.MAX_SAFE_INTEGER;
|
|
155
|
+
const reduced = raw - (rowPotential[currentRow] ?? 0) - (columnPotential[column] ?? 0);
|
|
156
|
+
if (reduced < (minimum[column] ?? Number.POSITIVE_INFINITY)) {
|
|
157
|
+
minimum[column] = reduced;
|
|
158
|
+
predecessor[column] = currentColumn;
|
|
159
|
+
}
|
|
160
|
+
if ((minimum[column] ?? Number.POSITIVE_INFINITY) < delta) {
|
|
161
|
+
delta = minimum[column] ?? Number.POSITIVE_INFINITY;
|
|
162
|
+
nextColumn = column;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
for (let column = 0; column <= columnCount; column += 1) {
|
|
166
|
+
if (used[column]) {
|
|
167
|
+
const matchedRow = columnMatch[column] ?? 0;
|
|
168
|
+
rowPotential[matchedRow] = (rowPotential[matchedRow] ?? 0) + delta;
|
|
169
|
+
columnPotential[column] = (columnPotential[column] ?? 0) - delta;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
minimum[column] = (minimum[column] ?? Number.POSITIVE_INFINITY) - delta;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
currentColumn = nextColumn;
|
|
176
|
+
} while ((columnMatch[currentColumn] ?? 0) !== 0);
|
|
177
|
+
do {
|
|
178
|
+
const nextColumn = predecessor[currentColumn] ?? 0;
|
|
179
|
+
columnMatch[currentColumn] = columnMatch[nextColumn] ?? 0;
|
|
180
|
+
currentColumn = nextColumn;
|
|
181
|
+
} while (currentColumn !== 0);
|
|
182
|
+
}
|
|
183
|
+
const assignment = new Array(rowCount).fill(-1);
|
|
184
|
+
for (let column = 1; column <= columnCount; column += 1) {
|
|
185
|
+
const row = columnMatch[column] ?? 0;
|
|
186
|
+
if (row > 0)
|
|
187
|
+
assignment[row - 1] = column - 1;
|
|
188
|
+
}
|
|
189
|
+
return assignment;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=track-association.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-association.js","sourceRoot":"","sources":["../../src/tracking/track-association.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BarcodeTrack, TrackOverlayModel } from "./types.js";
|
|
2
|
+
export declare function createTrackOverlayModel(track: BarcodeTrack): TrackOverlayModel;
|
|
3
|
+
export declare function createTrackOverlayModels(tracks: readonly BarcodeTrack[]): readonly TrackOverlayModel[];
|
|
4
|
+
//# sourceMappingURL=track-overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-overlay.d.ts","sourceRoot":"","sources":["../../src/tracking/track-overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAW9E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,iBAAiB,EAAE,CAEtG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function createTrackOverlayModel(track) {
|
|
2
|
+
return {
|
|
3
|
+
trackId: track.trackId,
|
|
4
|
+
physicalInstanceId: track.physicalInstanceId,
|
|
5
|
+
payload: track.payload,
|
|
6
|
+
format: track.format,
|
|
7
|
+
state: track.state,
|
|
8
|
+
boundingBox: { ...track.geometry.boundingBox },
|
|
9
|
+
cornerPoints: track.geometry.cornerPoints.map((point) => ({ ...point })),
|
|
10
|
+
...(track.velocity ? { velocity: { ...track.velocity } } : {}),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function createTrackOverlayModels(tracks) {
|
|
14
|
+
return tracks.map(createTrackOverlayModel);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=track-overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-overlay.js","sourceRoot":"","sources":["../../src/tracking/track-overlay.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,uBAAuB,CAAC,KAAmB;IACzD,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE;QAC9C,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACxE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAA+B;IACtE,OAAO,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BarcodeTrack, TrackROIFrame, TrackROIPlan, TrackROISetOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Produces a bounded, renderer/decoder-neutral multi-target ROI plan. The plan
|
|
4
|
+
* always schedules a periodic global scan so ROI optimization cannot hide a
|
|
5
|
+
* newly entering barcode indefinitely.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TrackROISet {
|
|
8
|
+
private readonly options;
|
|
9
|
+
private lastGlobalFrame;
|
|
10
|
+
private lastSize;
|
|
11
|
+
constructor(options?: TrackROISetOptions);
|
|
12
|
+
plan(tracks: readonly BarcodeTrack[], frame: TrackROIFrame): TrackROIPlan;
|
|
13
|
+
get size(): number;
|
|
14
|
+
reset(): void;
|
|
15
|
+
private roiFor;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=track-roi-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-roi-set.d.ts","sourceRoot":"","sources":["../../src/tracking/track-roi-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAW1G;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAK;gBAET,OAAO,GAAE,kBAAuB;IAgB5C,IAAI,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,KAAK,EAAE,aAAa,GAAG,YAAY;IA2BzE,IAAI,IAAI,IAAI,MAAM,CAA0B;IAE5C,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,MAAM;CAwBf"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { translateGeometry } from "./geometry.js";
|
|
2
|
+
const DEFAULT_MAX_ROIS = 32;
|
|
3
|
+
const DEFAULT_MAX_CANDIDATE_TRACKS = 128;
|
|
4
|
+
const HARD_MAX_CANDIDATE_TRACKS = 128;
|
|
5
|
+
const HARD_MAX_ROIS = 32;
|
|
6
|
+
const HARD_MAX_UNCOVERED_GRID_SIZE = 16;
|
|
7
|
+
const HARD_MAX_UNCOVERED_REGIONS = 64;
|
|
8
|
+
const HARD_MAX_GRID_CELL_CHECKS = HARD_MAX_UNCOVERED_GRID_SIZE ** 2;
|
|
9
|
+
/**
|
|
10
|
+
* Produces a bounded, renderer/decoder-neutral multi-target ROI plan. The plan
|
|
11
|
+
* always schedules a periodic global scan so ROI optimization cannot hide a
|
|
12
|
+
* newly entering barcode indefinitely.
|
|
13
|
+
*/
|
|
14
|
+
export class TrackROISet {
|
|
15
|
+
options;
|
|
16
|
+
lastGlobalFrame;
|
|
17
|
+
lastSize = 0;
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.options = {
|
|
20
|
+
maxCandidateTracks: boundedPositiveInteger(options.maxCandidateTracks, DEFAULT_MAX_CANDIDATE_TRACKS, HARD_MAX_CANDIDATE_TRACKS),
|
|
21
|
+
maxROIs: boundedPositiveInteger(options.maxROIs, DEFAULT_MAX_ROIS, HARD_MAX_ROIS),
|
|
22
|
+
expansion: bounded(options.expansion, 0.25, 0, 2),
|
|
23
|
+
missedFrameExpansion: bounded(options.missedFrameExpansion, 0.15, 0, 1),
|
|
24
|
+
globalScanIntervalFrames: positiveInteger(options.globalScanIntervalFrames, 10),
|
|
25
|
+
uncoveredGridSize: boundedPositiveInteger(options.uncoveredGridSize, 4, HARD_MAX_UNCOVERED_GRID_SIZE),
|
|
26
|
+
maxUncoveredRegions: boundedPositiveInteger(options.maxUncoveredRegions, 16, HARD_MAX_UNCOVERED_REGIONS),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
plan(tracks, frame) {
|
|
30
|
+
validateFrame(frame);
|
|
31
|
+
// Only a fixed prefix is inspected. The runtime tracker itself is bounded,
|
|
32
|
+
// but TrackROISet is public and must remain safe with arbitrary callers.
|
|
33
|
+
const eligible = tracks
|
|
34
|
+
.slice(0, this.options.maxCandidateTracks)
|
|
35
|
+
.filter((track) => track.state === "confirmed" || track.state === "lost")
|
|
36
|
+
.sort((a, b) => statePriority(a.state) - statePriority(b.state) || a.trackId.localeCompare(b.trackId))
|
|
37
|
+
.slice(0, this.options.maxROIs);
|
|
38
|
+
const trackedROIs = eligible.map((track) => this.roiFor(track, frame));
|
|
39
|
+
const uncoveredRegions = createUncoveredGrid(trackedROIs, this.options.uncoveredGridSize, this.options.maxUncoveredRegions);
|
|
40
|
+
const includeFullFrame = trackedROIs.length === 0
|
|
41
|
+
|| this.lastGlobalFrame === undefined
|
|
42
|
+
|| frame.frameId - this.lastGlobalFrame >= this.options.globalScanIntervalFrames;
|
|
43
|
+
if (includeFullFrame)
|
|
44
|
+
this.lastGlobalFrame = frame.frameId;
|
|
45
|
+
this.lastSize = trackedROIs.length;
|
|
46
|
+
const phases = [];
|
|
47
|
+
if (trackedROIs.length > 0)
|
|
48
|
+
phases.push("tracked-rois");
|
|
49
|
+
if (uncoveredRegions.length > 0)
|
|
50
|
+
phases.push("uncovered-regions");
|
|
51
|
+
if (includeFullFrame)
|
|
52
|
+
phases.push("full-frame");
|
|
53
|
+
return { frameId: frame.frameId, trackedROIs, uncoveredRegions, includeFullFrame, phases };
|
|
54
|
+
}
|
|
55
|
+
get size() { return this.lastSize; }
|
|
56
|
+
reset() {
|
|
57
|
+
this.lastGlobalFrame = undefined;
|
|
58
|
+
this.lastSize = 0;
|
|
59
|
+
}
|
|
60
|
+
roiFor(track, frame) {
|
|
61
|
+
const deltaFrames = Math.max(0, frame.frameId - track.lastFrameId);
|
|
62
|
+
const predicted = Boolean(track.velocity && deltaFrames > 0);
|
|
63
|
+
const geometry = predicted && track.velocity
|
|
64
|
+
? translateGeometry(track.geometry, track.velocity.x * deltaFrames, track.velocity.y * deltaFrames)
|
|
65
|
+
: track.geometry;
|
|
66
|
+
const expansion = this.options.expansion + track.missedFrameCount * this.options.missedFrameExpansion;
|
|
67
|
+
const dx = geometry.boundingBox.width * expansion;
|
|
68
|
+
const dy = geometry.boundingBox.height * expansion;
|
|
69
|
+
const left = clamp(geometry.boundingBox.x - dx, 0, frame.width);
|
|
70
|
+
const top = clamp(geometry.boundingBox.y - dy, 0, frame.height);
|
|
71
|
+
const right = clamp(geometry.boundingBox.x + geometry.boundingBox.width + dx, left, frame.width);
|
|
72
|
+
const bottom = clamp(geometry.boundingBox.y + geometry.boundingBox.height + dy, top, frame.height);
|
|
73
|
+
return {
|
|
74
|
+
trackId: track.trackId,
|
|
75
|
+
state: track.state,
|
|
76
|
+
x: left / frame.width,
|
|
77
|
+
y: top / frame.height,
|
|
78
|
+
width: (right - left) / frame.width,
|
|
79
|
+
height: (bottom - top) / frame.height,
|
|
80
|
+
predicted,
|
|
81
|
+
missCount: track.missedFrameCount,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function createUncoveredGrid(tracked, gridSize, maximum) {
|
|
86
|
+
if (tracked.length === 0)
|
|
87
|
+
return [];
|
|
88
|
+
const cellSize = 1 / gridSize;
|
|
89
|
+
const uncovered = [];
|
|
90
|
+
const cellChecks = Math.min(HARD_MAX_GRID_CELL_CHECKS, gridSize * gridSize);
|
|
91
|
+
for (let index = 0; index < cellChecks && uncovered.length < maximum; index += 1) {
|
|
92
|
+
const row = Math.floor(index / gridSize);
|
|
93
|
+
const column = index % gridSize;
|
|
94
|
+
const cell = { x: column * cellSize, y: row * cellSize, width: cellSize, height: cellSize };
|
|
95
|
+
if (!tracked.some((roi) => rectanglesIntersect(cell, roi)))
|
|
96
|
+
uncovered.push(cell);
|
|
97
|
+
}
|
|
98
|
+
return uncovered;
|
|
99
|
+
}
|
|
100
|
+
function rectanglesIntersect(a, b) {
|
|
101
|
+
return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
|
|
102
|
+
}
|
|
103
|
+
function statePriority(state) { return state === "confirmed" ? 0 : 1; }
|
|
104
|
+
function clamp(value, minimum, maximum) { return Math.max(minimum, Math.min(maximum, value)); }
|
|
105
|
+
function positiveInteger(value, fallback) {
|
|
106
|
+
return value === undefined || !Number.isFinite(value) ? fallback : Math.max(1, Math.floor(value));
|
|
107
|
+
}
|
|
108
|
+
function boundedPositiveInteger(value, fallback, maximum) {
|
|
109
|
+
return Math.min(maximum, positiveInteger(value, fallback));
|
|
110
|
+
}
|
|
111
|
+
function bounded(value, fallback, minimum, maximum) {
|
|
112
|
+
return value === undefined || !Number.isFinite(value) ? fallback : clamp(value, minimum, maximum);
|
|
113
|
+
}
|
|
114
|
+
function validateFrame(frame) {
|
|
115
|
+
if (!Number.isInteger(frame.frameId) || frame.frameId < 0 || !Number.isFinite(frame.width) || !Number.isFinite(frame.height) || frame.width <= 0 || frame.height <= 0) {
|
|
116
|
+
throw new RangeError("TrackROISet requires a non-negative frameId and positive finite frame dimensions.");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=track-roi-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-roi-set.js","sourceRoot":"","sources":["../../src/tracking/track-roi-set.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { DecodedBarcode } from "@scanly/core";
|
|
2
|
+
import type { BarcodeGeometry } from "../scanner/types.js";
|
|
3
|
+
/** Lifecycle of one physical barcode identity. */
|
|
4
|
+
export type BarcodeTrackState = "tentative" | "confirmed" | "lost" | "retired";
|
|
5
|
+
/**
|
|
6
|
+
* One decoder observation in a frame. Observations deliberately do not carry
|
|
7
|
+
* identity: assigning a stable physical identity is BarcodeTracker's job.
|
|
8
|
+
*/
|
|
9
|
+
export interface BarcodeObservation {
|
|
10
|
+
payload: string;
|
|
11
|
+
format: DecodedBarcode["format"];
|
|
12
|
+
geometry: BarcodeGeometry;
|
|
13
|
+
confidence?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Stable, SDK-owned view of a physical barcode instance. */
|
|
16
|
+
export interface BarcodeTrack {
|
|
17
|
+
trackId: string;
|
|
18
|
+
payload: string;
|
|
19
|
+
format: DecodedBarcode["format"];
|
|
20
|
+
state: BarcodeTrackState;
|
|
21
|
+
firstSeenAt: number;
|
|
22
|
+
lastSeenAt: number;
|
|
23
|
+
firstFrameId: number;
|
|
24
|
+
lastFrameId: number;
|
|
25
|
+
observationCount: number;
|
|
26
|
+
missedFrameCount: number;
|
|
27
|
+
geometry: BarcodeGeometry;
|
|
28
|
+
/** Center displacement in image coordinates per processed frame. */
|
|
29
|
+
velocity?: {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
};
|
|
33
|
+
physicalInstanceId: string;
|
|
34
|
+
}
|
|
35
|
+
export interface TrackingFrame {
|
|
36
|
+
frameId: number;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
}
|
|
39
|
+
export interface BarcodeTrackerOptions {
|
|
40
|
+
/** Maximum live (tentative, confirmed, or lost) identities. */
|
|
41
|
+
maxTracks?: number;
|
|
42
|
+
/** Public scanner-facing alias for maxTracks. maxTracks takes precedence. */
|
|
43
|
+
maxTrackedBarcodes?: number;
|
|
44
|
+
/** Maximum observations considered from any one frame. */
|
|
45
|
+
maxObservations?: number;
|
|
46
|
+
/** Maximum accepted association cost. */
|
|
47
|
+
associationThreshold?: number;
|
|
48
|
+
/** Observations required before a new identity is confirmed. */
|
|
49
|
+
confirmationObservations?: number;
|
|
50
|
+
/** Consecutive missing frames retained for occlusion recovery. */
|
|
51
|
+
maxMissedFrames?: number;
|
|
52
|
+
/** EMA weight applied to the newest measured velocity. */
|
|
53
|
+
velocitySmoothing?: number;
|
|
54
|
+
association?: Partial<TrackAssociationWeights>;
|
|
55
|
+
}
|
|
56
|
+
export interface TrackAssociationWeights {
|
|
57
|
+
payloadMismatch: number;
|
|
58
|
+
formatMismatch: number;
|
|
59
|
+
spatialDistance: number;
|
|
60
|
+
iouPenalty: number;
|
|
61
|
+
geometrySize: number;
|
|
62
|
+
motionPrediction: number;
|
|
63
|
+
timeSinceObservation: number;
|
|
64
|
+
}
|
|
65
|
+
export interface TrackAssociationMatch {
|
|
66
|
+
trackIndex: number;
|
|
67
|
+
observationIndex: number;
|
|
68
|
+
cost: number;
|
|
69
|
+
}
|
|
70
|
+
export interface TrackAssociationResult {
|
|
71
|
+
matches: readonly TrackAssociationMatch[];
|
|
72
|
+
unmatchedTrackIndices: readonly number[];
|
|
73
|
+
unmatchedObservationIndices: readonly number[];
|
|
74
|
+
/** Rows are tracks and columns are observations. */
|
|
75
|
+
costMatrix: readonly (readonly number[])[];
|
|
76
|
+
}
|
|
77
|
+
export interface BarcodeTrackerUpdate {
|
|
78
|
+
frameId: number;
|
|
79
|
+
timestamp: number;
|
|
80
|
+
matchedTracks: readonly BarcodeTrack[];
|
|
81
|
+
newTracks: readonly BarcodeTrack[];
|
|
82
|
+
updatedTracks: readonly BarcodeTrack[];
|
|
83
|
+
lostTracks: readonly BarcodeTrack[];
|
|
84
|
+
restoredTracks: readonly BarcodeTrack[];
|
|
85
|
+
retiredTracks: readonly BarcodeTrack[];
|
|
86
|
+
tracks: readonly BarcodeTrack[];
|
|
87
|
+
ignoredObservationCount: number;
|
|
88
|
+
association: TrackAssociationResult;
|
|
89
|
+
}
|
|
90
|
+
export interface TrackingStatistics {
|
|
91
|
+
processedFrames: number;
|
|
92
|
+
receivedObservations: number;
|
|
93
|
+
consideredObservations: number;
|
|
94
|
+
ignoredObservations: number;
|
|
95
|
+
matchedObservationCount: number;
|
|
96
|
+
createdTrackCount: number;
|
|
97
|
+
confirmedTrackCount: number;
|
|
98
|
+
lostTransitionCount: number;
|
|
99
|
+
restoredTrackCount: number;
|
|
100
|
+
retiredTrackCount: number;
|
|
101
|
+
activeTrackCount: number;
|
|
102
|
+
lostTrackCount: number;
|
|
103
|
+
pendingObservationCount: number;
|
|
104
|
+
peakTrackCount: number;
|
|
105
|
+
associationP50Ms: number;
|
|
106
|
+
associationP95Ms: number;
|
|
107
|
+
}
|
|
108
|
+
export interface TrackROIFrame {
|
|
109
|
+
frameId: number;
|
|
110
|
+
width: number;
|
|
111
|
+
height: number;
|
|
112
|
+
}
|
|
113
|
+
export interface TrackROI {
|
|
114
|
+
trackId: string;
|
|
115
|
+
state: BarcodeTrackState;
|
|
116
|
+
x: number;
|
|
117
|
+
y: number;
|
|
118
|
+
width: number;
|
|
119
|
+
height: number;
|
|
120
|
+
predicted: boolean;
|
|
121
|
+
missCount: number;
|
|
122
|
+
}
|
|
123
|
+
export interface TrackROIPlan {
|
|
124
|
+
frameId: number;
|
|
125
|
+
trackedROIs: readonly TrackROI[];
|
|
126
|
+
uncoveredRegions: readonly Omit<TrackROI, "trackId" | "state" | "predicted" | "missCount">[];
|
|
127
|
+
includeFullFrame: boolean;
|
|
128
|
+
phases: readonly ("tracked-rois" | "uncovered-regions" | "full-frame")[];
|
|
129
|
+
}
|
|
130
|
+
export interface TrackROISetOptions {
|
|
131
|
+
/** Maximum input candidates inspected before ROI prioritization. */
|
|
132
|
+
maxCandidateTracks?: number;
|
|
133
|
+
maxROIs?: number;
|
|
134
|
+
expansion?: number;
|
|
135
|
+
missedFrameExpansion?: number;
|
|
136
|
+
globalScanIntervalFrames?: number;
|
|
137
|
+
uncoveredGridSize?: number;
|
|
138
|
+
maxUncoveredRegions?: number;
|
|
139
|
+
}
|
|
140
|
+
/** Renderer-neutral overlay data; Canvas/SVG ownership stays with applications. */
|
|
141
|
+
export interface TrackOverlayModel {
|
|
142
|
+
trackId: string;
|
|
143
|
+
physicalInstanceId: string;
|
|
144
|
+
payload: string;
|
|
145
|
+
format: DecodedBarcode["format"];
|
|
146
|
+
state: BarcodeTrackState;
|
|
147
|
+
boundingBox: BarcodeGeometry["boundingBox"];
|
|
148
|
+
cornerPoints: BarcodeGeometry["cornerPoints"];
|
|
149
|
+
velocity?: {
|
|
150
|
+
x: number;
|
|
151
|
+
y: number;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tracking/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tracking/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode-worker.d.ts","sourceRoot":"","sources":["../../src/worker/decode-worker.ts"],"names":[],"mappings":"AAuFA,OAAO,EAAE,CAAC"}
|