@srsergio/taptapp-ar 1.0.9 → 1.0.10

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.
Files changed (122) hide show
  1. package/dist/compiler/controller.d.ts +15 -22
  2. package/dist/compiler/controller.js +73 -92
  3. package/dist/compiler/detector/crop-detector.d.ts +20 -51
  4. package/dist/compiler/detector/crop-detector.js +21 -15
  5. package/dist/compiler/input-loader.d.ts +15 -17
  6. package/dist/compiler/input-loader.js +58 -76
  7. package/dist/compiler/matching/hamming-distance.js +4 -4
  8. package/dist/compiler/matching/matcher.js +2 -2
  9. package/dist/compiler/matching/matching.d.ts +2 -16
  10. package/dist/compiler/matching/matching.js +72 -60
  11. package/dist/compiler/offline-compiler.d.ts +9 -29
  12. package/dist/compiler/offline-compiler.js +38 -72
  13. package/dist/compiler/three.js +0 -4
  14. package/dist/compiler/tracker/tracker.d.ts +26 -12
  15. package/dist/compiler/tracker/tracker.js +158 -259
  16. package/package.json +1 -1
  17. package/src/compiler/controller.js +71 -93
  18. package/src/compiler/detector/crop-detector.js +26 -15
  19. package/src/compiler/input-loader.js +62 -88
  20. package/src/compiler/matching/hamming-distance.js +4 -4
  21. package/src/compiler/matching/hough.js +1 -1
  22. package/src/compiler/matching/matcher.js +2 -2
  23. package/src/compiler/matching/matching.js +80 -72
  24. package/src/compiler/offline-compiler.js +38 -75
  25. package/src/compiler/three.js +0 -4
  26. package/src/compiler/tracker/tracker.js +183 -283
  27. package/dist/compiler/compiler-base.d.ts +0 -8
  28. package/dist/compiler/compiler-base.js +0 -179
  29. package/dist/compiler/compiler.d.ts +0 -9
  30. package/dist/compiler/compiler.js +0 -24
  31. package/dist/compiler/compiler.worker.d.ts +0 -1
  32. package/dist/compiler/compiler.worker.js +0 -28
  33. package/dist/compiler/detector/detector.d.ts +0 -97
  34. package/dist/compiler/detector/detector.js +0 -1042
  35. package/dist/compiler/detector/kernels/cpu/binomialFilter.d.ts +0 -6
  36. package/dist/compiler/detector/kernels/cpu/binomialFilter.js +0 -50
  37. package/dist/compiler/detector/kernels/cpu/buildExtremas.d.ts +0 -6
  38. package/dist/compiler/detector/kernels/cpu/buildExtremas.js +0 -89
  39. package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.d.ts +0 -7
  40. package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.js +0 -79
  41. package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.d.ts +0 -6
  42. package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.js +0 -68
  43. package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.d.ts +0 -6
  44. package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.js +0 -57
  45. package/dist/compiler/detector/kernels/cpu/computeLocalization.d.ts +0 -6
  46. package/dist/compiler/detector/kernels/cpu/computeLocalization.js +0 -50
  47. package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.d.ts +0 -6
  48. package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -100
  49. package/dist/compiler/detector/kernels/cpu/downsampleBilinear.d.ts +0 -6
  50. package/dist/compiler/detector/kernels/cpu/downsampleBilinear.js +0 -29
  51. package/dist/compiler/detector/kernels/cpu/extremaReduction.d.ts +0 -6
  52. package/dist/compiler/detector/kernels/cpu/extremaReduction.js +0 -50
  53. package/dist/compiler/detector/kernels/cpu/fakeShader.d.ts +0 -20
  54. package/dist/compiler/detector/kernels/cpu/fakeShader.js +0 -80
  55. package/dist/compiler/detector/kernels/cpu/index.d.ts +0 -1
  56. package/dist/compiler/detector/kernels/cpu/index.js +0 -25
  57. package/dist/compiler/detector/kernels/cpu/prune.d.ts +0 -7
  58. package/dist/compiler/detector/kernels/cpu/prune.js +0 -62
  59. package/dist/compiler/detector/kernels/cpu/smoothHistograms.d.ts +0 -6
  60. package/dist/compiler/detector/kernels/cpu/smoothHistograms.js +0 -47
  61. package/dist/compiler/detector/kernels/cpu/upsampleBilinear.d.ts +0 -6
  62. package/dist/compiler/detector/kernels/cpu/upsampleBilinear.js +0 -43
  63. package/dist/compiler/detector/kernels/index.d.ts +0 -1
  64. package/dist/compiler/detector/kernels/index.js +0 -2
  65. package/dist/compiler/detector/kernels/webgl/binomialFilter.d.ts +0 -6
  66. package/dist/compiler/detector/kernels/webgl/binomialFilter.js +0 -67
  67. package/dist/compiler/detector/kernels/webgl/buildExtremas.d.ts +0 -6
  68. package/dist/compiler/detector/kernels/webgl/buildExtremas.js +0 -101
  69. package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.d.ts +0 -6
  70. package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.js +0 -78
  71. package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.d.ts +0 -6
  72. package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.js +0 -86
  73. package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.d.ts +0 -6
  74. package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.js +0 -52
  75. package/dist/compiler/detector/kernels/webgl/computeLocalization.d.ts +0 -6
  76. package/dist/compiler/detector/kernels/webgl/computeLocalization.js +0 -58
  77. package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.d.ts +0 -6
  78. package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.js +0 -116
  79. package/dist/compiler/detector/kernels/webgl/downsampleBilinear.d.ts +0 -6
  80. package/dist/compiler/detector/kernels/webgl/downsampleBilinear.js +0 -46
  81. package/dist/compiler/detector/kernels/webgl/extremaReduction.d.ts +0 -6
  82. package/dist/compiler/detector/kernels/webgl/extremaReduction.js +0 -48
  83. package/dist/compiler/detector/kernels/webgl/index.d.ts +0 -1
  84. package/dist/compiler/detector/kernels/webgl/index.js +0 -25
  85. package/dist/compiler/detector/kernels/webgl/smoothHistograms.d.ts +0 -6
  86. package/dist/compiler/detector/kernels/webgl/smoothHistograms.js +0 -49
  87. package/dist/compiler/detector/kernels/webgl/upsampleBilinear.d.ts +0 -6
  88. package/dist/compiler/detector/kernels/webgl/upsampleBilinear.js +0 -56
  89. package/dist/compiler/tensorflow-setup.d.ts +0 -6
  90. package/dist/compiler/tensorflow-setup.js +0 -99
  91. package/src/compiler/compiler-base.js +0 -210
  92. package/src/compiler/compiler.js +0 -25
  93. package/src/compiler/compiler.worker.js +0 -30
  94. package/src/compiler/detector/detector.js +0 -1119
  95. package/src/compiler/detector/kernels/cpu/binomialFilter.js +0 -58
  96. package/src/compiler/detector/kernels/cpu/buildExtremas.js +0 -108
  97. package/src/compiler/detector/kernels/cpu/computeExtremaAngles.js +0 -91
  98. package/src/compiler/detector/kernels/cpu/computeExtremaFreak.js +0 -92
  99. package/src/compiler/detector/kernels/cpu/computeFreakDescriptors.js +0 -68
  100. package/src/compiler/detector/kernels/cpu/computeLocalization.js +0 -67
  101. package/src/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -124
  102. package/src/compiler/detector/kernels/cpu/downsampleBilinear.js +0 -33
  103. package/src/compiler/detector/kernels/cpu/extremaReduction.js +0 -53
  104. package/src/compiler/detector/kernels/cpu/fakeShader.js +0 -88
  105. package/src/compiler/detector/kernels/cpu/index.js +0 -26
  106. package/src/compiler/detector/kernels/cpu/prune.js +0 -78
  107. package/src/compiler/detector/kernels/cpu/smoothHistograms.js +0 -57
  108. package/src/compiler/detector/kernels/cpu/upsampleBilinear.js +0 -51
  109. package/src/compiler/detector/kernels/index.js +0 -2
  110. package/src/compiler/detector/kernels/webgl/binomialFilter.js +0 -72
  111. package/src/compiler/detector/kernels/webgl/buildExtremas.js +0 -109
  112. package/src/compiler/detector/kernels/webgl/computeExtremaAngles.js +0 -82
  113. package/src/compiler/detector/kernels/webgl/computeExtremaFreak.js +0 -105
  114. package/src/compiler/detector/kernels/webgl/computeFreakDescriptors.js +0 -56
  115. package/src/compiler/detector/kernels/webgl/computeLocalization.js +0 -70
  116. package/src/compiler/detector/kernels/webgl/computeOrientationHistograms.js +0 -129
  117. package/src/compiler/detector/kernels/webgl/downsampleBilinear.js +0 -50
  118. package/src/compiler/detector/kernels/webgl/extremaReduction.js +0 -50
  119. package/src/compiler/detector/kernels/webgl/index.js +0 -26
  120. package/src/compiler/detector/kernels/webgl/smoothHistograms.js +0 -53
  121. package/src/compiler/detector/kernels/webgl/upsampleBilinear.js +0 -62
  122. package/src/compiler/tensorflow-setup.js +0 -116
@@ -1,5 +1,5 @@
1
1
  export class Controller {
2
- constructor({ inputWidth, inputHeight, onUpdate, debugMode, maxTrack, warmupTolerance, missTolerance, filterMinCF, filterBeta, }: {
2
+ constructor({ inputWidth, inputHeight, onUpdate, debugMode, maxTrack, warmupTolerance, missTolerance, filterMinCF, filterBeta, worker, }: {
3
3
  inputWidth: any;
4
4
  inputHeight: any;
5
5
  onUpdate?: null | undefined;
@@ -9,6 +9,7 @@ export class Controller {
9
9
  missTolerance?: null | undefined;
10
10
  filterMinCF?: null | undefined;
11
11
  filterBeta?: null | undefined;
12
+ worker?: null | undefined;
12
13
  });
13
14
  inputWidth: any;
14
15
  inputHeight: any;
@@ -25,12 +26,11 @@ export class Controller {
25
26
  processingVideo: boolean;
26
27
  interestedTargetIndex: number;
27
28
  trackingStates: any[];
29
+ worker: any;
28
30
  projectionTransform: number[][];
29
31
  projectionMatrix: number[];
30
- worker: any;
31
- workerMatchDone: ((data: any) => void) | null;
32
- workerTrackDone: ((data: any) => void) | null;
33
- showTFStats(): void;
32
+ _setupWorkerListener(): void;
33
+ _ensureWorker(): void;
34
34
  addImageTargets(fileURL: any): Promise<any>;
35
35
  addImageTargetsFromBuffer(buffer: any): {
36
36
  dimensions: any[][];
@@ -43,32 +43,23 @@ export class Controller {
43
43
  getProjectionMatrix(): number[];
44
44
  getRotatedZ90Matrix(m: any): any[];
45
45
  getWorldMatrix(modelViewTransform: any, targetIndex: any): any[];
46
- _detectAndMatch(inputT: any, targetIndexes: any): Promise<{
46
+ _detectAndMatch(inputData: any, targetIndexes: any): Promise<{
47
47
  targetIndex: any;
48
48
  modelViewTransform: any;
49
49
  }>;
50
- _trackAndUpdate(inputT: any, lastModelViewTransform: any, targetIndex: any): Promise<any>;
50
+ _trackAndUpdate(inputData: any, lastModelViewTransform: any, targetIndex: any): Promise<any>;
51
51
  processVideo(input: any): void;
52
52
  stopProcessVideo(): void;
53
53
  detect(input: any): Promise<{
54
- featurePoints: {
55
- maxima: boolean;
56
- x: number;
57
- y: number;
58
- scale: number;
59
- angle: any;
60
- descriptors: any[];
61
- }[];
54
+ featurePoints: any[];
62
55
  debugExtra: {
63
- pyramidImages: any[][];
64
- dogPyramidImages: any[];
65
- extremasResults: any[];
66
- extremaAngles: any;
67
- prunedExtremas: number[][];
68
- localizedExtremas: any;
69
- } | null;
56
+ projectedImage: number[];
57
+ } | {
58
+ projectedImage?: undefined;
59
+ };
70
60
  }>;
71
61
  match(featurePoints: any, targetIndex: any): Promise<{
62
+ targetIndex: any;
72
63
  modelViewTransform: any;
73
64
  debugExtra: any;
74
65
  }>;
@@ -86,7 +77,9 @@ export class Controller {
86
77
  }>;
87
78
  trackUpdate(modelViewTransform: any, trackFeatures: any): Promise<any>;
88
79
  _workerMatch(featurePoints: any, targetIndexes: any): Promise<any>;
80
+ workerMatchDone: ((data: any) => void) | undefined;
89
81
  _workerTrackUpdate(modelViewTransform: any, trackingFeatures: any): Promise<any>;
82
+ workerTrackDone: ((data: any) => void) | undefined;
90
83
  _glModelViewMatrix(modelViewTransform: any, targetIndex: any): any[];
91
84
  _glProjectionMatrix({ projectionTransform, width, height, near, far }: {
92
85
  projectionTransform: any;
@@ -1,17 +1,25 @@
1
- import { memory, nextFrame } from "@tensorflow/tfjs";
2
- const tf = { memory, nextFrame };
3
- import ControllerWorker from "./controller.worker.js?worker&inline";
4
1
  import { Tracker } from "./tracker/tracker.js";
5
2
  import { CropDetector } from "./detector/crop-detector.js";
6
- import { Compiler } from "./compiler.js";
3
+ import { OfflineCompiler as Compiler } from "./offline-compiler.js";
7
4
  import { InputLoader } from "./input-loader.js";
8
5
  import { OneEuroFilter } from "../libs/one-euro-filter.js";
6
+ let ControllerWorker;
7
+ // Conditional import for worker to avoid crash in non-vite environments
8
+ try {
9
+ const workerModule = await import("./controller.worker.js?worker&inline");
10
+ ControllerWorker = workerModule.default;
11
+ }
12
+ catch (e) {
13
+ // Fallback for tests or other environments
14
+ ControllerWorker = null;
15
+ }
9
16
  const DEFAULT_FILTER_CUTOFF = 0.001; // 1Hz. time period in milliseconds
10
17
  const DEFAULT_FILTER_BETA = 1000;
11
18
  const DEFAULT_WARMUP_TOLERANCE = 5;
12
19
  const DEFAULT_MISS_TOLERANCE = 5;
13
20
  class Controller {
14
- constructor({ inputWidth, inputHeight, onUpdate = null, debugMode = false, maxTrack = 1, warmupTolerance = null, missTolerance = null, filterMinCF = null, filterBeta = null, }) {
21
+ constructor({ inputWidth, inputHeight, onUpdate = null, debugMode = false, maxTrack = 1, warmupTolerance = null, missTolerance = null, filterMinCF = null, filterBeta = null, worker = null, // Allow custom worker injection
22
+ }) {
15
23
  this.inputWidth = inputWidth;
16
24
  this.inputHeight = inputHeight;
17
25
  this.maxTrack = maxTrack;
@@ -27,13 +35,13 @@ class Controller {
27
35
  this.processingVideo = false;
28
36
  this.interestedTargetIndex = -1;
29
37
  this.trackingStates = [];
38
+ this.worker = worker;
39
+ if (this.worker)
40
+ this._setupWorkerListener();
30
41
  const near = 10;
31
42
  const far = 100000;
32
- const fovy = (45.0 * Math.PI) / 180; // 45 in radian. field of view vertical
43
+ const fovy = (45.0 * Math.PI) / 180;
33
44
  const f = this.inputHeight / 2 / Math.tan(fovy / 2);
34
- // [fx s cx]
35
- // K = [ 0 fx cy]
36
- // [ 0 0 1]
37
45
  this.projectionTransform = [
38
46
  [f, 0, this.inputWidth / 2],
39
47
  [0, f, this.inputHeight / 2],
@@ -46,9 +54,10 @@ class Controller {
46
54
  near: near,
47
55
  far: far,
48
56
  });
49
- this.worker = new ControllerWorker(); //new Worker(new URL('./controller.worker.js', import.meta.url));
50
- this.workerMatchDone = null;
51
- this.workerTrackDone = null;
57
+ }
58
+ _setupWorkerListener() {
59
+ if (!this.worker)
60
+ return;
52
61
  this.worker.onmessage = (e) => {
53
62
  if (e.data.type === "matchDone" && this.workerMatchDone !== null) {
54
63
  this.workerMatchDone(e.data);
@@ -58,9 +67,13 @@ class Controller {
58
67
  }
59
68
  };
60
69
  }
61
- showTFStats() {
62
- console.log(tf.memory().numTensors);
63
- console.table(tf.memory());
70
+ _ensureWorker() {
71
+ if (this.worker)
72
+ return;
73
+ if (ControllerWorker) {
74
+ this.worker = new ControllerWorker();
75
+ this._setupWorkerListener();
76
+ }
64
77
  }
65
78
  addImageTargets(fileURL) {
66
79
  return new Promise(async (resolve) => {
@@ -77,34 +90,37 @@ class Controller {
77
90
  const matchingDataList = [];
78
91
  const dimensions = [];
79
92
  for (let i = 0; i < dataList.length; i++) {
80
- matchingDataList.push(dataList[i].matchingData);
81
- trackingDataList.push(dataList[i].trackingData);
82
- dimensions.push([dataList[i].targetImage.width, dataList[i].targetImage.height]);
93
+ const item = dataList[i];
94
+ matchingDataList.push(item.matchingData);
95
+ trackingDataList.push(item.trackingData);
96
+ dimensions.push([item.targetImage.width, item.targetImage.height]);
83
97
  }
84
98
  this.tracker = new Tracker(dimensions, trackingDataList, this.projectionTransform, this.inputWidth, this.inputHeight, this.debugMode);
85
- this.worker.postMessage({
86
- type: "setup",
87
- inputWidth: this.inputWidth,
88
- inputHeight: this.inputHeight,
89
- projectionTransform: this.projectionTransform,
90
- debugMode: this.debugMode,
91
- matchingDataList,
92
- });
99
+ this._ensureWorker();
100
+ if (this.worker) {
101
+ this.worker.postMessage({
102
+ type: "setup",
103
+ inputWidth: this.inputWidth,
104
+ inputHeight: this.inputHeight,
105
+ projectionTransform: this.projectionTransform,
106
+ debugMode: this.debugMode,
107
+ matchingDataList,
108
+ });
109
+ }
93
110
  this.markerDimensions = dimensions;
94
- return { dimensions: dimensions, matchingDataList, trackingDataList };
111
+ return { dimensions, matchingDataList, trackingDataList };
95
112
  }
96
113
  dispose() {
97
114
  this.stopProcessVideo();
98
- this.worker.postMessage({
99
- type: "dispose",
100
- });
115
+ if (this.worker) {
116
+ this.worker.postMessage({ type: "dispose" });
117
+ this.worker = null;
118
+ }
101
119
  }
102
- // warm up gpu - build kernels is slow
103
120
  dummyRun(input) {
104
- const inputT = this.inputLoader.loadInput(input);
105
- this.cropDetector.detect(inputT);
106
- this.tracker.dummyRun(inputT);
107
- inputT.dispose();
121
+ const inputData = this.inputLoader.loadInput(input);
122
+ this.cropDetector.detect(inputData);
123
+ this.tracker.dummyRun(inputData);
108
124
  }
109
125
  getProjectionMatrix() {
110
126
  return this.projectionMatrix;
@@ -139,13 +155,13 @@ class Controller {
139
155
  getWorldMatrix(modelViewTransform, targetIndex) {
140
156
  return this._glModelViewMatrix(modelViewTransform, targetIndex);
141
157
  }
142
- async _detectAndMatch(inputT, targetIndexes) {
143
- const { featurePoints } = this.cropDetector.detectMoving(inputT);
158
+ async _detectAndMatch(inputData, targetIndexes) {
159
+ const { featurePoints } = this.cropDetector.detectMoving(inputData);
144
160
  const { targetIndex: matchedTargetIndex, modelViewTransform } = await this._workerMatch(featurePoints, targetIndexes);
145
161
  return { targetIndex: matchedTargetIndex, modelViewTransform };
146
162
  }
147
- async _trackAndUpdate(inputT, lastModelViewTransform, targetIndex) {
148
- const { worldCoords, screenCoords } = this.tracker.track(inputT, lastModelViewTransform, targetIndex);
163
+ async _trackAndUpdate(inputData, lastModelViewTransform, targetIndex) {
164
+ const { worldCoords, screenCoords } = this.tracker.track(inputData, lastModelViewTransform, targetIndex);
149
165
  if (worldCoords.length < 4)
150
166
  return null;
151
167
  const modelViewTransform = await this._workerTrackUpdate(lastModelViewTransform, {
@@ -168,13 +184,12 @@ class Controller {
168
184
  trackMiss: 0,
169
185
  filter: new OneEuroFilter({ minCutOff: this.filterMinCF, beta: this.filterBeta }),
170
186
  });
171
- //console.log("filterMinCF", this.filterMinCF, this.filterBeta);
172
187
  }
173
188
  const startProcessing = async () => {
174
189
  while (true) {
175
190
  if (!this.processingVideo)
176
191
  break;
177
- const inputT = this.inputLoader.loadInput(input);
192
+ const inputData = this.inputLoader.loadInput(input);
178
193
  const nTracking = this.trackingStates.reduce((acc, s) => {
179
194
  return acc + (!!s.isTracking ? 1 : 0);
180
195
  }, 0);
@@ -189,7 +204,7 @@ class Controller {
189
204
  continue;
190
205
  matchingIndexes.push(i);
191
206
  }
192
- const { targetIndex: matchedTargetIndex, modelViewTransform } = await this._detectAndMatch(inputT, matchingIndexes);
207
+ const { targetIndex: matchedTargetIndex, modelViewTransform } = await this._detectAndMatch(inputData, matchingIndexes);
193
208
  if (matchedTargetIndex !== -1) {
194
209
  this.trackingStates[matchedTargetIndex].isTracking = true;
195
210
  this.trackingStates[matchedTargetIndex].currentModelViewTransform = modelViewTransform;
@@ -199,7 +214,7 @@ class Controller {
199
214
  for (let i = 0; i < this.trackingStates.length; i++) {
200
215
  const trackingState = this.trackingStates[i];
201
216
  if (trackingState.isTracking) {
202
- let modelViewTransform = await this._trackAndUpdate(inputT, trackingState.currentModelViewTransform, i);
217
+ let modelViewTransform = await this._trackAndUpdate(inputData, trackingState.currentModelViewTransform, i);
203
218
  if (modelViewTransform === null) {
204
219
  trackingState.isTracking = false;
205
220
  }
@@ -251,9 +266,14 @@ class Controller {
251
266
  this.onUpdate({ type: "updateMatrix", targetIndex: i, worldMatrix: clone });
252
267
  }
253
268
  }
254
- inputT.dispose();
255
269
  this.onUpdate && this.onUpdate({ type: "processDone" });
256
- await tf.nextFrame();
270
+ // Use requestAnimationFrame if available, otherwise just wait briefly
271
+ if (typeof requestAnimationFrame !== "undefined") {
272
+ await new Promise(requestAnimationFrame);
273
+ }
274
+ else {
275
+ await new Promise(resolve => setTimeout(resolve, 16));
276
+ }
257
277
  }
258
278
  };
259
279
  startProcessing();
@@ -262,21 +282,19 @@ class Controller {
262
282
  this.processingVideo = false;
263
283
  }
264
284
  async detect(input) {
265
- const inputT = this.inputLoader.loadInput(input);
266
- const { featurePoints, debugExtra } = this.cropDetector.detect(inputT);
267
- inputT.dispose();
285
+ const inputData = this.inputLoader.loadInput(input);
286
+ const { featurePoints, debugExtra } = this.cropDetector.detect(inputData);
268
287
  return { featurePoints, debugExtra };
269
288
  }
270
289
  async match(featurePoints, targetIndex) {
271
- const { modelViewTransform, debugExtra } = await this._workerMatch(featurePoints, [
290
+ const { targetIndex: matchedTargetIndex, modelViewTransform, debugExtra } = await this._workerMatch(featurePoints, [
272
291
  targetIndex,
273
292
  ]);
274
- return { modelViewTransform, debugExtra };
293
+ return { targetIndex: matchedTargetIndex, modelViewTransform, debugExtra };
275
294
  }
276
295
  async track(input, modelViewTransform, targetIndex) {
277
- const inputT = this.inputLoader.loadInput(input);
278
- const result = this.tracker.track(inputT, modelViewTransform, targetIndex);
279
- inputT.dispose();
296
+ const inputData = this.inputLoader.loadInput(input);
297
+ const result = this.tracker.track(inputData, modelViewTransform, targetIndex);
280
298
  return result;
281
299
  }
282
300
  async trackUpdate(modelViewTransform, trackFeatures) {
@@ -294,7 +312,7 @@ class Controller {
294
312
  debugExtra: data.debugExtra,
295
313
  });
296
314
  };
297
- this.worker.postMessage({ type: "match", featurePoints: featurePoints, targetIndexes });
315
+ this.worker && this.worker.postMessage({ type: "match", featurePoints: featurePoints, targetIndexes });
298
316
  });
299
317
  }
300
318
  _workerTrackUpdate(modelViewTransform, trackingFeatures) {
@@ -303,7 +321,7 @@ class Controller {
303
321
  resolve(data.modelViewTransform);
304
322
  };
305
323
  const { worldCoords, screenCoords } = trackingFeatures;
306
- this.worker.postMessage({
324
+ this.worker && this.worker.postMessage({
307
325
  type: "trackUpdate",
308
326
  modelViewTransform,
309
327
  worldCoords,
@@ -313,41 +331,6 @@ class Controller {
313
331
  }
314
332
  _glModelViewMatrix(modelViewTransform, targetIndex) {
315
333
  const height = this.markerDimensions[targetIndex][1];
316
- // Question: can someone verify this interpreation is correct?
317
- // I'm not very convinced, but more like trial and error and works......
318
- //
319
- // First, opengl has y coordinate system go from bottom to top, while the marker corrdinate goes from top to bottom,
320
- // since the modelViewTransform is estimated in marker coordinate, we need to apply this transform before modelViewTransform
321
- // I can see why y = h - y*, but why z = z* ? should we intepret it as rotate 90 deg along x-axis and then translate y by h?
322
- //
323
- // [1 0 0 0]
324
- // [0 -1 0 h]
325
- // [0 0 -1 0]
326
- // [0 0 0 1]
327
- //
328
- // This is tested that if we reverse marker coordinate from bottom to top and estimate the modelViewTransform,
329
- // then the above matrix is not necessary.
330
- //
331
- // Second, in opengl, positive z is away from camera, so we rotate 90 deg along x-axis after transform to fix the axis mismatch
332
- // [1 1 0 0]
333
- // [0 -1 0 0]
334
- // [0 0 -1 0]
335
- // [0 0 0 1]
336
- //
337
- // all together, the combined matrix is
338
- //
339
- // [1 1 0 0] [m00, m01, m02, m03] [1 0 0 0]
340
- // [0 -1 0 0] [m10, m11, m12, m13] [0 -1 0 h]
341
- // [0 0 -1 0] [m20, m21, m22, m23] [0 0 -1 0]
342
- // [0 0 0 1] [ 0 0 0 1] [0 0 0 1]
343
- //
344
- // [ m00, -m01, -m02, (m01 * h + m03) ]
345
- // [-m10, m11, m12, -(m11 * h + m13) ]
346
- // = [-m20, m21, m22, -(m21 * h + m23) ]
347
- // [ 0, 0, 0, 1 ]
348
- //
349
- //
350
- // Finally, in threejs, matrix is represented in col by row, so we transpose it, and get below:
351
334
  const openGLWorldMatrix = [
352
335
  modelViewTransform[0][0],
353
336
  -modelViewTransform[1][0],
@@ -368,8 +351,6 @@ class Controller {
368
351
  ];
369
352
  return openGLWorldMatrix;
370
353
  }
371
- // build openGL projection matrix
372
- // ref: https://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
373
354
  _glProjectionMatrix({ projectionTransform, width, height, near, far }) {
374
355
  const proj = [
375
356
  [
@@ -4,62 +4,31 @@ export class CropDetector {
4
4
  width: any;
5
5
  height: any;
6
6
  cropSize: number;
7
- detector: Detector;
8
- kernelCaches: {};
7
+ detector: DetectorLite;
9
8
  lastRandomIndex: number;
10
- detect(inputImageT: any): {
11
- featurePoints: {
12
- maxima: boolean;
13
- x: number;
14
- y: number;
15
- scale: number;
16
- angle: any;
17
- descriptors: any[];
18
- }[];
9
+ detect(input: any): {
10
+ featurePoints: any[];
19
11
  debugExtra: {
20
- pyramidImages: any[][];
21
- dogPyramidImages: any[];
22
- extremasResults: any[];
23
- extremaAngles: any;
24
- prunedExtremas: number[][];
25
- localizedExtremas: any;
26
- } | null;
12
+ projectedImage: number[];
13
+ } | {
14
+ projectedImage?: undefined;
15
+ };
27
16
  };
28
- detectMoving(inputImageT: any): {
29
- featurePoints: {
30
- maxima: boolean;
31
- x: number;
32
- y: number;
33
- scale: number;
34
- angle: any;
35
- descriptors: any[];
36
- }[];
17
+ detectMoving(input: any): {
18
+ featurePoints: any[];
37
19
  debugExtra: {
38
- pyramidImages: any[][];
39
- dogPyramidImages: any[];
40
- extremasResults: any[];
41
- extremaAngles: any;
42
- prunedExtremas: number[][];
43
- localizedExtremas: any;
44
- } | null;
20
+ projectedImage: number[];
21
+ } | {
22
+ projectedImage?: undefined;
23
+ };
45
24
  };
46
- _detect(inputImageT: any, startX: any, startY: any): {
47
- featurePoints: {
48
- maxima: boolean;
49
- x: number;
50
- y: number;
51
- scale: number;
52
- angle: any;
53
- descriptors: any[];
54
- }[];
25
+ _detect(imageData: any, startX: any, startY: any): {
26
+ featurePoints: any[];
55
27
  debugExtra: {
56
- pyramidImages: any[][];
57
- dogPyramidImages: any[];
58
- extremasResults: any[];
59
- extremaAngles: any;
60
- prunedExtremas: number[][];
61
- localizedExtremas: any;
62
- } | null;
28
+ projectedImage: number[];
29
+ } | {
30
+ projectedImage?: undefined;
31
+ };
63
32
  };
64
33
  }
65
- import { Detector } from "./detector.js";
34
+ import { DetectorLite } from "./detector-lite.js";
@@ -1,4 +1,4 @@
1
- import { Detector } from "./detector.js";
1
+ import { DetectorLite } from "./detector-lite.js";
2
2
  class CropDetector {
3
3
  constructor(width, height, debugMode = false) {
4
4
  this.debugMode = debugMode;
@@ -8,21 +8,22 @@ class CropDetector {
8
8
  let minDimension = Math.min(width, height) / 2;
9
9
  let cropSize = Math.pow(2, Math.round(Math.log(minDimension) / Math.log(2)));
10
10
  this.cropSize = cropSize;
11
- this.detector = new Detector(cropSize, cropSize, debugMode);
12
- this.kernelCaches = {};
11
+ this.detector = new DetectorLite(cropSize, cropSize);
13
12
  this.lastRandomIndex = 4;
14
13
  }
15
- detect(inputImageT) {
14
+ detect(input) {
15
+ const imageData = input;
16
16
  // crop center
17
17
  const startY = Math.floor(this.height / 2 - this.cropSize / 2);
18
18
  const startX = Math.floor(this.width / 2 - this.cropSize / 2);
19
- const result = this._detect(inputImageT, startX, startY);
19
+ const result = this._detect(imageData, startX, startY);
20
20
  if (this.debugMode) {
21
21
  result.debugExtra.crop = { startX, startY, cropSize: this.cropSize };
22
22
  }
23
23
  return result;
24
24
  }
25
- detectMoving(inputImageT) {
25
+ detectMoving(input) {
26
+ const imageData = input;
26
27
  // loop a few locations around center
27
28
  const dx = this.lastRandomIndex % 3;
28
29
  const dy = Math.floor(this.lastRandomIndex / 3);
@@ -37,21 +38,26 @@ class CropDetector {
37
38
  if (startY >= this.height - this.cropSize)
38
39
  startY = this.height - this.cropSize - 1;
39
40
  this.lastRandomIndex = (this.lastRandomIndex + 1) % 9;
40
- const result = this._detect(inputImageT, startX, startY);
41
+ const result = this._detect(imageData, startX, startY);
41
42
  return result;
42
43
  }
43
- _detect(inputImageT, startX, startY) {
44
- const cropInputImageT = inputImageT.slice([startY, startX], [this.cropSize, this.cropSize]);
45
- const { featurePoints, debugExtra } = this.detector.detect(cropInputImageT);
44
+ _detect(imageData, startX, startY) {
45
+ // Crop manually since imageData is now a flat array (width * height)
46
+ const croppedData = new Float32Array(this.cropSize * this.cropSize);
47
+ for (let y = 0; y < this.cropSize; y++) {
48
+ for (let x = 0; x < this.cropSize; x++) {
49
+ croppedData[y * this.cropSize + x] = imageData[(startY + y) * this.width + (startX + x)];
50
+ }
51
+ }
52
+ const { featurePoints } = this.detector.detect(croppedData);
46
53
  featurePoints.forEach((p) => {
47
54
  p.x += startX;
48
55
  p.y += startY;
49
56
  });
50
- if (this.debugMode) {
51
- debugExtra.projectedImage = cropInputImageT.arraySync();
52
- }
53
- cropInputImageT.dispose();
54
- return { featurePoints: featurePoints, debugExtra };
57
+ return {
58
+ featurePoints,
59
+ debugExtra: this.debugMode ? { projectedImage: Array.from(croppedData) } : {}
60
+ };
55
61
  }
56
62
  }
57
63
  export { CropDetector };
@@ -1,22 +1,20 @@
1
+ /**
2
+ * InputLoader - Maneja la carga de imágenes y video sin TensorFlow
3
+ */
1
4
  export class InputLoader {
2
5
  constructor(width: any, height: any);
3
6
  width: any;
4
7
  height: any;
5
- texShape: any[];
6
- context: CanvasRenderingContext2D | null;
7
- program: {
8
- variableNames: string[];
9
- outputShape: any[];
10
- userCode: string;
11
- };
12
- tempPixelHandle: any;
13
- _loadInput(input: any): any;
14
- loadInput(input: any): any;
15
- buildProgram(width: any, height: any): {
16
- variableNames: string[];
17
- outputShape: any[];
18
- userCode: string;
19
- };
20
- _compileAndRun(program: any, inputs: any): any;
21
- _runWebGLProgram(program: any, inputs: any, outputType: any): any;
8
+ grayscaleBuffer: Uint8Array<ArrayBuffer>;
9
+ context: CanvasRenderingContext2D | null | undefined;
10
+ /**
11
+ * Carga una imagen o video y devuelve los datos en escala de grises
12
+ * @param {HTMLVideoElement|HTMLImageElement|ImageData|Uint8Array} input - La fuente de entrada
13
+ * @returns {Uint8Array} Datos de imagen en escala de grises (width * height)
14
+ */
15
+ loadInput(input: HTMLVideoElement | HTMLImageElement | ImageData | Uint8Array): Uint8Array;
16
+ /**
17
+ * Convierte datos RGBA a escala de grises optimizada (reutilizando buffer)
18
+ */
19
+ _convertToGrayscale(rgbaData: any, width: any, height: any): void;
22
20
  }