@srsergio/taptapp-ar 1.0.73 → 1.0.74
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.
|
@@ -22,6 +22,19 @@ export class CropDetector {
|
|
|
22
22
|
projectedImage?: undefined;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Scans the ENTIRE frame by downsampling it to cropSize
|
|
27
|
+
*/
|
|
28
|
+
_detectGlobal(imageData: any): {
|
|
29
|
+
featurePoints: any[];
|
|
30
|
+
debugExtra: {
|
|
31
|
+
projectedImage: number[];
|
|
32
|
+
isGlobal: boolean;
|
|
33
|
+
} | {
|
|
34
|
+
projectedImage?: undefined;
|
|
35
|
+
isGlobal?: undefined;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
25
38
|
_detect(imageData: any, startX: any, startY: any): {
|
|
26
39
|
featurePoints: any[];
|
|
27
40
|
debugExtra: {
|
|
@@ -24,27 +24,51 @@ class CropDetector {
|
|
|
24
24
|
}
|
|
25
25
|
detectMoving(input) {
|
|
26
26
|
const imageData = input;
|
|
27
|
-
//
|
|
27
|
+
// 🚀 MOONSHOT: Alternate between local crops and GLOBAL scan
|
|
28
|
+
// This solves the "not reading the whole screen" issue.
|
|
29
|
+
// Every 3 frames, we do a full screen downsampled scan.
|
|
30
|
+
if (this.lastRandomIndex % 3 === 0) {
|
|
31
|
+
this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
|
|
32
|
+
return this._detectGlobal(imageData);
|
|
33
|
+
}
|
|
34
|
+
// Original moving crop logic for high-detail local detection
|
|
28
35
|
const gridSize = 5;
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
36
|
+
const idx = (this.lastRandomIndex - 1) % (gridSize * gridSize);
|
|
37
|
+
const dx = idx % gridSize;
|
|
38
|
+
const dy = Math.floor(idx / gridSize);
|
|
32
39
|
const stepX = this.cropSize / 3;
|
|
33
40
|
const stepY = this.cropSize / 3;
|
|
34
41
|
let startY = Math.floor(this.height / 2 - this.cropSize / 2 + (dy - 2) * stepY);
|
|
35
42
|
let startX = Math.floor(this.width / 2 - this.cropSize / 2 + (dx - 2) * stepX);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
43
|
+
startX = Math.max(0, Math.min(this.width - this.cropSize - 1, startX));
|
|
44
|
+
startY = Math.max(0, Math.min(this.height - this.cropSize - 1, startY));
|
|
45
|
+
this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
|
|
46
|
+
return this._detect(imageData, startX, startY);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Scans the ENTIRE frame by downsampling it to cropSize
|
|
50
|
+
*/
|
|
51
|
+
_detectGlobal(imageData) {
|
|
52
|
+
const croppedData = new Float32Array(this.cropSize * this.cropSize);
|
|
53
|
+
const scaleX = this.width / this.cropSize;
|
|
54
|
+
const scaleY = this.height / this.cropSize;
|
|
55
|
+
// Fast downsample (nearest neighbor is enough for initial feature detection)
|
|
56
|
+
for (let y = 0; y < this.cropSize; y++) {
|
|
57
|
+
const srcY = Math.floor(y * scaleY) * this.width;
|
|
58
|
+
const dstY = y * this.cropSize;
|
|
59
|
+
for (let x = 0; x < this.cropSize; x++) {
|
|
60
|
+
croppedData[dstY + x] = imageData[srcY + Math.floor(x * scaleX)];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const { featurePoints } = this.detector.detect(croppedData);
|
|
64
|
+
featurePoints.forEach((p) => {
|
|
65
|
+
p.x *= scaleX;
|
|
66
|
+
p.y *= scaleY;
|
|
67
|
+
});
|
|
68
|
+
return {
|
|
69
|
+
featurePoints,
|
|
70
|
+
debugExtra: this.debugMode ? { projectedImage: Array.from(croppedData), isGlobal: true } : {}
|
|
71
|
+
};
|
|
48
72
|
}
|
|
49
73
|
_detect(imageData, startX, startY) {
|
|
50
74
|
// Crop manually since imageData is now a flat array (width * height)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../estimation/utils.js";
|
|
2
2
|
const AR2_DEFAULT_TS = 6;
|
|
3
3
|
const AR2_DEFAULT_TS_GAP = 1;
|
|
4
|
-
const AR2_SEARCH_SIZE = 18
|
|
4
|
+
const AR2_SEARCH_SIZE = 34; // Increased from 18 to 34 for much better fast-motion tracking
|
|
5
5
|
const AR2_SEARCH_GAP = 1;
|
|
6
6
|
const AR2_SIM_THRESH = 0.6;
|
|
7
7
|
const TRACKING_KEYFRAME = 0; // 0: 128px (optimized)
|
package/package.json
CHANGED
|
@@ -33,28 +33,62 @@ class CropDetector {
|
|
|
33
33
|
detectMoving(input) {
|
|
34
34
|
const imageData = input;
|
|
35
35
|
|
|
36
|
-
//
|
|
36
|
+
// 🚀 MOONSHOT: Alternate between local crops and GLOBAL scan
|
|
37
|
+
// This solves the "not reading the whole screen" issue.
|
|
38
|
+
// Every 3 frames, we do a full screen downsampled scan.
|
|
39
|
+
if (this.lastRandomIndex % 3 === 0) {
|
|
40
|
+
this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
|
|
41
|
+
return this._detectGlobal(imageData);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Original moving crop logic for high-detail local detection
|
|
37
45
|
const gridSize = 5;
|
|
38
|
-
const
|
|
39
|
-
const
|
|
46
|
+
const idx = (this.lastRandomIndex - 1) % (gridSize * gridSize);
|
|
47
|
+
const dx = idx % gridSize;
|
|
48
|
+
const dy = Math.floor(idx / gridSize);
|
|
40
49
|
|
|
41
|
-
// Calculate offset from center, with overlap for better detection
|
|
42
50
|
const stepX = this.cropSize / 3;
|
|
43
51
|
const stepY = this.cropSize / 3;
|
|
44
52
|
|
|
45
53
|
let startY = Math.floor(this.height / 2 - this.cropSize / 2 + (dy - 2) * stepY);
|
|
46
54
|
let startX = Math.floor(this.width / 2 - this.cropSize / 2 + (dx - 2) * stepX);
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (startY < 0) startY = 0;
|
|
51
|
-
if (startX >= this.width - this.cropSize) startX = this.width - this.cropSize - 1;
|
|
52
|
-
if (startY >= this.height - this.cropSize) startY = this.height - this.cropSize - 1;
|
|
56
|
+
startX = Math.max(0, Math.min(this.width - this.cropSize - 1, startX));
|
|
57
|
+
startY = Math.max(0, Math.min(this.height - this.cropSize - 1, startY));
|
|
53
58
|
|
|
54
|
-
this.lastRandomIndex = (this.lastRandomIndex + 1) %
|
|
59
|
+
this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
return this._detect(imageData, startX, startY);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Scans the ENTIRE frame by downsampling it to cropSize
|
|
66
|
+
*/
|
|
67
|
+
_detectGlobal(imageData) {
|
|
68
|
+
const croppedData = new Float32Array(this.cropSize * this.cropSize);
|
|
69
|
+
const scaleX = this.width / this.cropSize;
|
|
70
|
+
const scaleY = this.height / this.cropSize;
|
|
71
|
+
|
|
72
|
+
// Fast downsample (nearest neighbor is enough for initial feature detection)
|
|
73
|
+
for (let y = 0; y < this.cropSize; y++) {
|
|
74
|
+
const srcY = Math.floor(y * scaleY) * this.width;
|
|
75
|
+
const dstY = y * this.cropSize;
|
|
76
|
+
for (let x = 0; x < this.cropSize; x++) {
|
|
77
|
+
croppedData[dstY + x] = imageData[srcY + Math.floor(x * scaleX)];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const { featurePoints } = this.detector.detect(croppedData);
|
|
82
|
+
|
|
83
|
+
featurePoints.forEach((p) => {
|
|
84
|
+
p.x *= scaleX;
|
|
85
|
+
p.y *= scaleY;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
featurePoints,
|
|
90
|
+
debugExtra: this.debugMode ? { projectedImage: Array.from(croppedData), isGlobal: true } : {}
|
|
91
|
+
};
|
|
58
92
|
}
|
|
59
93
|
|
|
60
94
|
_detect(imageData, startX, startY) {
|
|
@@ -2,7 +2,7 @@ import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../es
|
|
|
2
2
|
|
|
3
3
|
const AR2_DEFAULT_TS = 6;
|
|
4
4
|
const AR2_DEFAULT_TS_GAP = 1;
|
|
5
|
-
const AR2_SEARCH_SIZE = 18
|
|
5
|
+
const AR2_SEARCH_SIZE = 34; // Increased from 18 to 34 for much better fast-motion tracking
|
|
6
6
|
const AR2_SEARCH_GAP = 1;
|
|
7
7
|
const AR2_SIM_THRESH = 0.6;
|
|
8
8
|
|