@srsergio/taptapp-ar 1.0.2 → 1.0.3
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 +47 -45
- package/dist/compiler/aframe.js +0 -3
- package/dist/compiler/compiler-base.d.ts +3 -7
- package/dist/compiler/compiler-base.js +28 -14
- package/dist/compiler/compiler.js +1 -1
- package/dist/compiler/compiler.worker.js +1 -1
- package/dist/compiler/controller.js +4 -5
- package/dist/compiler/controller.worker.js +0 -2
- package/dist/compiler/detector/crop-detector.js +0 -2
- package/dist/compiler/detector/detector-lite.d.ts +73 -0
- package/dist/compiler/detector/detector-lite.js +430 -0
- package/dist/compiler/detector/detector.js +236 -243
- package/dist/compiler/detector/kernels/cpu/binomialFilter.js +0 -1
- package/dist/compiler/detector/kernels/cpu/computeLocalization.js +0 -4
- package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -18
- package/dist/compiler/detector/kernels/cpu/fakeShader.js +1 -1
- package/dist/compiler/detector/kernels/cpu/prune.d.ts +7 -1
- package/dist/compiler/detector/kernels/cpu/prune.js +1 -42
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.js +2 -2
- package/dist/compiler/estimation/refine-estimate.js +0 -1
- package/dist/compiler/estimation/utils.d.ts +1 -1
- package/dist/compiler/estimation/utils.js +1 -14
- package/dist/compiler/image-list.js +4 -4
- package/dist/compiler/input-loader.js +2 -2
- package/dist/compiler/matching/hamming-distance.js +13 -13
- package/dist/compiler/matching/hierarchical-clustering.js +1 -1
- package/dist/compiler/matching/matching.d.ts +20 -4
- package/dist/compiler/matching/matching.js +67 -41
- package/dist/compiler/matching/ransacHomography.js +1 -2
- package/dist/compiler/node-worker.d.ts +1 -0
- package/dist/compiler/node-worker.js +84 -0
- package/dist/compiler/offline-compiler.d.ts +171 -6
- package/dist/compiler/offline-compiler.js +303 -421
- package/dist/compiler/tensorflow-setup.js +27 -1
- package/dist/compiler/three.js +3 -5
- package/dist/compiler/tracker/extract.d.ts +1 -0
- package/dist/compiler/tracker/extract.js +200 -244
- package/dist/compiler/tracker/tracker.d.ts +1 -1
- package/dist/compiler/tracker/tracker.js +13 -18
- package/dist/compiler/utils/cumsum.d.ts +4 -2
- package/dist/compiler/utils/cumsum.js +17 -19
- package/dist/compiler/utils/gpu-compute.d.ts +57 -0
- package/dist/compiler/utils/gpu-compute.js +262 -0
- package/dist/compiler/utils/images.d.ts +4 -4
- package/dist/compiler/utils/images.js +67 -53
- package/dist/compiler/utils/worker-pool.d.ts +14 -0
- package/dist/compiler/utils/worker-pool.js +84 -0
- package/package.json +11 -13
- package/src/compiler/aframe.js +2 -4
- package/src/compiler/compiler-base.js +29 -14
- package/src/compiler/compiler.js +1 -1
- package/src/compiler/compiler.worker.js +1 -1
- package/src/compiler/controller.js +4 -5
- package/src/compiler/controller.worker.js +0 -2
- package/src/compiler/detector/crop-detector.js +0 -2
- package/src/compiler/detector/detector-lite.js +494 -0
- package/src/compiler/detector/detector.js +1052 -1063
- package/src/compiler/detector/kernels/cpu/binomialFilter.js +0 -1
- package/src/compiler/detector/kernels/cpu/computeLocalization.js +0 -4
- package/src/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -17
- package/src/compiler/detector/kernels/cpu/fakeShader.js +1 -1
- package/src/compiler/detector/kernels/cpu/prune.js +1 -37
- package/src/compiler/detector/kernels/webgl/upsampleBilinear.js +2 -2
- package/src/compiler/estimation/refine-estimate.js +0 -1
- package/src/compiler/estimation/utils.js +9 -24
- package/src/compiler/image-list.js +4 -4
- package/src/compiler/input-loader.js +2 -2
- package/src/compiler/matching/hamming-distance.js +11 -15
- package/src/compiler/matching/hierarchical-clustering.js +1 -1
- package/src/compiler/matching/matching.js +72 -42
- package/src/compiler/matching/ransacHomography.js +0 -2
- package/src/compiler/node-worker.js +93 -0
- package/src/compiler/offline-compiler.js +339 -504
- package/src/compiler/tensorflow-setup.js +29 -1
- package/src/compiler/three.js +3 -5
- package/src/compiler/tracker/extract.js +211 -267
- package/src/compiler/tracker/tracker.js +13 -22
- package/src/compiler/utils/cumsum.js +17 -19
- package/src/compiler/utils/gpu-compute.js +303 -0
- package/src/compiler/utils/images.js +84 -53
- package/src/compiler/utils/worker-pool.js +89 -0
- package/src/compiler/estimation/esimate-experiment.js +0 -316
- package/src/compiler/estimation/refine-estimate-experiment.js +0 -512
package/README.md
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
🚀 **TapTapp AR** is a high-performance Augmented Reality (AR) toolkit specifically designed for **Astro** and **Node.js** environments. It provides a seamless way to integrate image tracking, video overlays, and an offline compiler for image targets.
|
|
4
4
|
|
|
5
|
-
Built on top of **MindAR
|
|
5
|
+
Built on top of **MindAR** and **A-Frame**, this package features a **pure JavaScript offline compiler** that requires **no TensorFlow** for backend compilation, while still supporting TensorFlow.js for real-time tracking in the browser.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 🌟 Key Features
|
|
10
10
|
|
|
11
11
|
- 🚀 **Astro Native**: Optimized components for Astro's Islands architecture.
|
|
12
|
-
- 🖼️ **Offline Compiler**:
|
|
13
|
-
- ⚡ **
|
|
14
|
-
-
|
|
12
|
+
- 🖼️ **Ultra-Fast Offline Compiler**: Pure JavaScript compiler that generates `.mind` target files in **~1.3s per image**.
|
|
13
|
+
- ⚡ **Zero TensorFlow for Compilation**: The offline compiler uses optimized pure JS algorithms - no TensorFlow installation required.
|
|
14
|
+
- 🧵 **Multi-threaded Engine**: Truly parallel processing using Node.js `worker_threads` for bulk image compilation.
|
|
15
|
+
- 🚀 **Serverless Ready**: Lightweight compiler with minimal dependencies, perfect for Vercel, AWS Lambda, and Netlify.
|
|
15
16
|
|
|
16
17
|
---
|
|
17
18
|
|
|
@@ -21,15 +22,11 @@ Built on top of **MindAR**, **A-Frame**, and **TensorFlow.js**, this package is
|
|
|
21
22
|
npm install @srsergio/taptapp-ar
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
### 📦
|
|
25
|
+
### 📦 Optional Dependencies
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
> **Note:** TensorFlow is **NOT required** for the offline compiler. It only uses pure JavaScript.
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
npm install three aframe astro
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Note: If you are using the `OfflineCompiler` in a Node.js environment, ensure you have the necessary TensorFlow.js backends installed.
|
|
29
|
+
For real-time AR tracking in the browser, TensorFlow.js is loaded automatically via CDN.
|
|
33
30
|
|
|
34
31
|
---
|
|
35
32
|
|
|
@@ -57,53 +54,58 @@ const config = {
|
|
|
57
54
|
<ARVideoTrigger config={config} />
|
|
58
55
|
```
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
---
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
| :--- | :--- | :--- |
|
|
64
|
-
| `cardId` | `string` | Unique identifier for tracking/session. |
|
|
65
|
-
| `targetImageSrc` | `string` | URL of the image being tracked. |
|
|
66
|
-
| `targetMindSrc` | `string` | URL of the compiled `.mind` target file. |
|
|
67
|
-
| `videoSrc` | `string` | URL of the video to overlay on the target. |
|
|
68
|
-
| `videoWidth` | `number` | Original width of the video. |
|
|
69
|
-
| `videoHeight` | `number` | Original height of the video. |
|
|
70
|
-
| `scale` | `number` | Scaling factor for the video overlay (Default: `1`). |
|
|
59
|
+
## 🖼️ High-Performance Compiler (Protocol V3)
|
|
71
60
|
|
|
72
|
-
|
|
61
|
+
TaptApp AR features the industry's most advanced **pure JavaScript** offline compiler. With the introduction of **Protocol V3 (Columnar Binary Format)**, it sets a new standard for AR asset management.
|
|
62
|
+
|
|
63
|
+
### ⚡ Industry-Leading Benchmarks
|
|
73
64
|
|
|
74
|
-
|
|
65
|
+
| Metric | Official MindAR | TapTapp AR (v3) | Improvement |
|
|
66
|
+
| :--- | :--- | :--- | :--- |
|
|
67
|
+
| **Compilation Time** | ~23.50s | **~1.71s** | 🚀 **13.7x Faster** |
|
|
68
|
+
| **Output Size (.mind)** | ~770 KB | **~127 KB** | 📉 **83.5% Smaller** |
|
|
69
|
+
| **Loading Latency** | >100ms | **2.6ms** | ⚡ **Zero-Copy** |
|
|
70
|
+
| **Memory Footprint** | Heavy (JSON Objects) | **Minimal (Binary)** | 🧠 **CPU-Aligned** |
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
> *Tested on 1024x1024 high-detail image target.*
|
|
77
73
|
|
|
78
|
-
###
|
|
79
|
-
Standard MindAR tools require a browser canvas to compile images. This compiler uses **TensorFlow.js** backends (CPU/WebGL/Node) to perform the computation as a background task.
|
|
74
|
+
### 🚀 Key Technical Breakthroughs
|
|
80
75
|
|
|
81
|
-
|
|
76
|
+
- **Protocol V3 (Columnar Binary)**: Uses TypedArrays to store coordinates, angles, and descriptors in a cache-aligned layout. No more thousands of slow JavaScript objects.
|
|
77
|
+
- **Zero-Copy Loading**: The runtime reads directly from the binary buffer. Initialization is now virtualy instant.
|
|
78
|
+
- **Aggressive Matching Optimization**: Tree-based hierarchical clustering compacted into a flattened binary format.
|
|
79
|
+
- **No Dependencies**: Works in Node.js and Browser with zero external requirements for the compilation core.
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
### 🖥️ Usage (Node.js & Serverless)
|
|
82
|
+
|
|
83
|
+
Optimized for server-side compilation with multi-core parallelism:
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
import { OfflineCompiler } from '@srsergio/taptapp-ar/compiler/offline-compiler.js';
|
|
85
87
|
|
|
86
88
|
const compiler = new OfflineCompiler();
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
// result is the compiled target data
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
90
|
+
// Compile target image
|
|
91
|
+
const compiledData = await compiler.compileImageTargets(
|
|
92
|
+
[{ width, height, data: grayscaleUint8Array }],
|
|
93
|
+
(progress) => console.log(`Compiling: ${progress}%`)
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Export to Protocol V3 binary format
|
|
97
|
+
const binaryBuffer = compiler.exportData(); // Yields a much smaller .mind file
|
|
99
98
|
```
|
|
100
99
|
|
|
101
|
-
###
|
|
102
|
-
The compiler is optimized for environments like Vercel Functions:
|
|
103
|
-
- **Early Initialization**: TensorFlow is pre-warmed on module import.
|
|
104
|
-
- **Memory Management**: Aggressive garbage collection (`tf.dispose()`) and tensor cleanup.
|
|
105
|
-
- **Batch Processing**: Automatically splits work to avoid memory spikes.
|
|
100
|
+
### 🌐 Frontend (Zero-Latency Loading)
|
|
106
101
|
|
|
102
|
+
```javascript
|
|
103
|
+
import { OfflineCompiler } from '@srsergio/taptapp-ar/compiler/offline-compiler.js';
|
|
104
|
+
|
|
105
|
+
const compiler = new OfflineCompiler();
|
|
106
|
+
// Loading 127KB instead of 800KB saves bandwidth and CPU parsing time
|
|
107
|
+
compiler.importData(binaryBuffer);
|
|
108
|
+
```
|
|
107
109
|
---
|
|
108
110
|
|
|
109
111
|
## ❓ Troubleshooting
|
package/dist/compiler/aframe.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Controller, UI } from "./index.js";
|
|
2
|
-
const needsDOMRefresh = document.readyState === "complete" || document.readyState == "interactive";
|
|
3
2
|
AFRAME.registerSystem("mindar-image-system", {
|
|
4
3
|
container: null,
|
|
5
4
|
video: null,
|
|
@@ -93,7 +92,6 @@ AFRAME.registerSystem("mindar-image-system", {
|
|
|
93
92
|
},
|
|
94
93
|
_startAR: async function () {
|
|
95
94
|
const video = this.video;
|
|
96
|
-
const container = this.container;
|
|
97
95
|
this.controller = new Controller({
|
|
98
96
|
inputWidth: video.videoWidth,
|
|
99
97
|
inputHeight: video.videoHeight,
|
|
@@ -159,7 +157,6 @@ AFRAME.registerSystem("mindar-image-system", {
|
|
|
159
157
|
const fov = (2 * Math.atan((1 / proj[5] / vh) * container.clientHeight) * 180) / Math.PI; // vertical fov
|
|
160
158
|
const near = proj[14] / (proj[10] - 1.0);
|
|
161
159
|
const far = proj[14] / (proj[10] + 1.0);
|
|
162
|
-
const ratio = proj[5] / proj[0]; // (r-l) / (t-b)
|
|
163
160
|
//console.log("loaded proj: ", proj, ". fov: ", fov, ". near: ", near, ". far: ", far, ". ratio: ", ratio);
|
|
164
161
|
const newAspect = container.clientWidth / container.clientHeight;
|
|
165
162
|
const cameraEle = container.getElementsByTagName("a-camera")[0];
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
export class CompilerBase {
|
|
2
2
|
data: any[] | null;
|
|
3
3
|
compileImageTargets(images: any, progressCallback: any): Promise<any>;
|
|
4
|
-
exportData(): Uint8Array<
|
|
4
|
+
exportData(): Uint8Array<ArrayBuffer>;
|
|
5
5
|
importData(buffer: any): any[];
|
|
6
|
-
createProcessCanvas(
|
|
7
|
-
compileTrack(
|
|
8
|
-
progressCallback: any;
|
|
9
|
-
targetImages: any;
|
|
10
|
-
basePercent: any;
|
|
11
|
-
}): void;
|
|
6
|
+
createProcessCanvas(): void;
|
|
7
|
+
compileTrack(): Promise<never[]>;
|
|
12
8
|
}
|
|
@@ -47,21 +47,34 @@ class CompilerBase {
|
|
|
47
47
|
targetImages.push(targetImage);
|
|
48
48
|
}
|
|
49
49
|
// compute matching data: 50% progress
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
let matchingDataList;
|
|
51
|
+
if (this.compileMatch) {
|
|
52
|
+
matchingDataList = await this.compileMatch({
|
|
53
|
+
progressCallback,
|
|
54
|
+
targetImages,
|
|
55
|
+
basePercent: 0,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const percentPerImage = 50.0 / targetImages.length;
|
|
60
|
+
let percent = 0.0;
|
|
61
|
+
const matchingPromises = targetImages.map(async (targetImage, i) => {
|
|
62
|
+
const imageList = buildImageList(targetImage);
|
|
63
|
+
const percentPerAction = percentPerImage / imageList.length;
|
|
64
|
+
const matchingData = await _extractMatchingFeatures(imageList, () => {
|
|
65
|
+
percent += percentPerAction;
|
|
66
|
+
progressCallback(percent);
|
|
67
|
+
});
|
|
68
|
+
return matchingData;
|
|
69
|
+
});
|
|
70
|
+
matchingDataList = await Promise.all(matchingPromises);
|
|
71
|
+
}
|
|
52
72
|
this.data = [];
|
|
53
73
|
for (let i = 0; i < targetImages.length; i++) {
|
|
54
|
-
const targetImage = targetImages[i];
|
|
55
|
-
const imageList = buildImageList(targetImage);
|
|
56
|
-
const percentPerAction = percentPerImage / imageList.length;
|
|
57
|
-
const matchingData = await _extractMatchingFeatures(imageList, () => {
|
|
58
|
-
percent += percentPerAction;
|
|
59
|
-
progressCallback(percent);
|
|
60
|
-
});
|
|
61
74
|
this.data.push({
|
|
62
|
-
targetImage:
|
|
63
|
-
imageList:
|
|
64
|
-
matchingData:
|
|
75
|
+
targetImage: targetImages[i],
|
|
76
|
+
imageList: buildImageList(targetImages[i]),
|
|
77
|
+
matchingData: matchingDataList[i],
|
|
65
78
|
});
|
|
66
79
|
}
|
|
67
80
|
for (let i = 0; i < targetImages.length; i++) {
|
|
@@ -121,13 +134,14 @@ class CompilerBase {
|
|
|
121
134
|
}
|
|
122
135
|
return this.data;
|
|
123
136
|
}
|
|
124
|
-
createProcessCanvas(
|
|
137
|
+
createProcessCanvas() {
|
|
125
138
|
// sub-class implements
|
|
126
139
|
console.warn("missing createProcessCanvas implementation");
|
|
127
140
|
}
|
|
128
|
-
compileTrack(
|
|
141
|
+
compileTrack() {
|
|
129
142
|
// sub-class implements
|
|
130
143
|
console.warn("missing compileTrack implementation");
|
|
144
|
+
return Promise.resolve([]);
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
const _extractMatchingFeatures = async (imageList, doneCallback) => {
|
|
@@ -8,7 +8,7 @@ export class Compiler extends CompilerBase {
|
|
|
8
8
|
return processCanvas;
|
|
9
9
|
}
|
|
10
10
|
compileTrack({ progressCallback, targetImages, basePercent }) {
|
|
11
|
-
return new Promise((resolve
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
12
|
const worker = new CompilerWorker();
|
|
13
13
|
worker.onmessage = (e) => {
|
|
14
14
|
if (e.data.type === "progress") {
|
|
@@ -13,7 +13,7 @@ onmessage = (msg) => {
|
|
|
13
13
|
const imageList = buildTrackingImageList(targetImage);
|
|
14
14
|
const percentPerAction = percentPerImage / imageList.length;
|
|
15
15
|
//console.log("compiling tracking...", i);
|
|
16
|
-
const trackingData = extractTrackingFeatures(imageList, (
|
|
16
|
+
const trackingData = extractTrackingFeatures(imageList, () => {
|
|
17
17
|
//console.log("done tracking", i, index);
|
|
18
18
|
percent += percentPerAction;
|
|
19
19
|
postMessage({ type: "progress", percent });
|
|
@@ -63,7 +63,7 @@ class Controller {
|
|
|
63
63
|
console.table(tf.memory());
|
|
64
64
|
}
|
|
65
65
|
addImageTargets(fileURL) {
|
|
66
|
-
return new Promise(async (resolve
|
|
66
|
+
return new Promise(async (resolve) => {
|
|
67
67
|
const content = await fetch(fileURL);
|
|
68
68
|
const buffer = await content.arrayBuffer();
|
|
69
69
|
const result = this.addImageTargetsFromBuffer(buffer);
|
|
@@ -75,7 +75,6 @@ class Controller {
|
|
|
75
75
|
const dataList = compiler.importData(buffer);
|
|
76
76
|
const trackingDataList = [];
|
|
77
77
|
const matchingDataList = [];
|
|
78
|
-
const imageListList = [];
|
|
79
78
|
const dimensions = [];
|
|
80
79
|
for (let i = 0; i < dataList.length; i++) {
|
|
81
80
|
matchingDataList.push(dataList[i].matchingData);
|
|
@@ -264,7 +263,7 @@ class Controller {
|
|
|
264
263
|
}
|
|
265
264
|
async detect(input) {
|
|
266
265
|
const inputT = this.inputLoader.loadInput(input);
|
|
267
|
-
const { featurePoints, debugExtra } =
|
|
266
|
+
const { featurePoints, debugExtra } = this.cropDetector.detect(inputT);
|
|
268
267
|
inputT.dispose();
|
|
269
268
|
return { featurePoints, debugExtra };
|
|
270
269
|
}
|
|
@@ -287,7 +286,7 @@ class Controller {
|
|
|
287
286
|
return modelViewTransform2;
|
|
288
287
|
}
|
|
289
288
|
_workerMatch(featurePoints, targetIndexes) {
|
|
290
|
-
return new Promise(
|
|
289
|
+
return new Promise((resolve) => {
|
|
291
290
|
this.workerMatchDone = (data) => {
|
|
292
291
|
resolve({
|
|
293
292
|
targetIndex: data.targetIndex,
|
|
@@ -299,7 +298,7 @@ class Controller {
|
|
|
299
298
|
});
|
|
300
299
|
}
|
|
301
300
|
_workerTrackUpdate(modelViewTransform, trackingFeatures) {
|
|
302
|
-
return new Promise(
|
|
301
|
+
return new Promise((resolve) => {
|
|
303
302
|
this.workerTrackDone = (data) => {
|
|
304
303
|
resolve(data.modelViewTransform);
|
|
305
304
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Matcher } from "./matching/matcher.js";
|
|
2
2
|
import { Estimator } from "./estimation/estimator.js";
|
|
3
|
-
let projectionTransform = null;
|
|
4
3
|
let matchingDataList = null;
|
|
5
4
|
let debugMode = false;
|
|
6
5
|
let matcher = null;
|
|
@@ -9,7 +8,6 @@ onmessage = (msg) => {
|
|
|
9
8
|
const { data } = msg;
|
|
10
9
|
switch (data.type) {
|
|
11
10
|
case "setup":
|
|
12
|
-
projectionTransform = data.projectionTransform;
|
|
13
11
|
matchingDataList = data.matchingDataList;
|
|
14
12
|
debugMode = data.debugMode;
|
|
15
13
|
matcher = new Matcher(data.inputWidth, data.inputHeight, debugMode);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import * as tf from "@tensorflow/tfjs";
|
|
2
1
|
import { Detector } from "./detector.js";
|
|
3
|
-
import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../estimation/utils.js";
|
|
4
2
|
class CropDetector {
|
|
5
3
|
constructor(width, height, debugMode = false) {
|
|
6
4
|
this.debugMode = debugMode;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export function setDetectorGPUMode(enabled: boolean): void;
|
|
2
|
+
/**
|
|
3
|
+
* Detector de características sin TensorFlow
|
|
4
|
+
*/
|
|
5
|
+
export class DetectorLite {
|
|
6
|
+
constructor(width: any, height: any, options?: {});
|
|
7
|
+
width: any;
|
|
8
|
+
height: any;
|
|
9
|
+
useGPU: any;
|
|
10
|
+
numOctaves: number;
|
|
11
|
+
/**
|
|
12
|
+
* Detecta características en una imagen en escala de grises
|
|
13
|
+
* @param {Float32Array|Uint8Array} imageData - Datos de imagen (width * height)
|
|
14
|
+
* @returns {{featurePoints: Array}} Puntos de características detectados
|
|
15
|
+
*/
|
|
16
|
+
detect(imageData: Float32Array | Uint8Array): {
|
|
17
|
+
featurePoints: any[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Construye una pirámide gaussiana
|
|
21
|
+
*/
|
|
22
|
+
_buildGaussianPyramid(data: any, width: any, height: any): {
|
|
23
|
+
data: Float32Array<ArrayBuffer>;
|
|
24
|
+
width: any;
|
|
25
|
+
height: any;
|
|
26
|
+
}[][];
|
|
27
|
+
/**
|
|
28
|
+
* Aplica un filtro gaussiano binomial [1,4,6,4,1] - Optimizado
|
|
29
|
+
*/
|
|
30
|
+
_applyGaussianFilter(data: any, width: any, height: any): {
|
|
31
|
+
data: Float32Array<ArrayBuffer>;
|
|
32
|
+
width: any;
|
|
33
|
+
height: any;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Downsample imagen por factor de 2
|
|
37
|
+
*/
|
|
38
|
+
_downsample(data: any, width: any, height: any): {
|
|
39
|
+
data: Float32Array<ArrayBuffer>;
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Construye pirámide de diferencia de gaussianas
|
|
45
|
+
*/
|
|
46
|
+
_buildDogPyramid(pyramidImages: any): {
|
|
47
|
+
data: Float32Array<ArrayBuffer>;
|
|
48
|
+
width: any;
|
|
49
|
+
height: any;
|
|
50
|
+
}[];
|
|
51
|
+
/**
|
|
52
|
+
* Encuentra extremos locales en la pirámide DoG
|
|
53
|
+
*/
|
|
54
|
+
_findExtremas(dogPyramid: any, pyramidImages: any): {
|
|
55
|
+
score: number;
|
|
56
|
+
octave: number;
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
absScore: number;
|
|
60
|
+
}[];
|
|
61
|
+
/**
|
|
62
|
+
* Aplica pruning para mantener solo los mejores features por bucket
|
|
63
|
+
*/
|
|
64
|
+
_applyPrune(extremas: any): any[];
|
|
65
|
+
/**
|
|
66
|
+
* Calcula la orientación de cada feature
|
|
67
|
+
*/
|
|
68
|
+
_computeOrientations(extremas: any, pyramidImages: any): void;
|
|
69
|
+
/**
|
|
70
|
+
* Calcula descriptores FREAK
|
|
71
|
+
*/
|
|
72
|
+
_computeFreakDescriptors(extremas: any, pyramidImages: any): void;
|
|
73
|
+
}
|