@srsergio/taptapp-ar 1.0.91 → 1.0.92
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/dist/compiler/offline-compiler.js +2 -10
- package/dist/core/constants.d.ts +29 -0
- package/dist/core/constants.js +35 -0
- package/dist/core/detector/detector-lite.js +1 -12
- package/dist/core/image-list.js +5 -4
- package/dist/core/matching/matching.js +7 -6
- package/dist/core/tracker/tracker.js +4 -3
- package/dist/runtime/controller.js +10 -9
- package/package.json +1 -1
- package/src/compiler/offline-compiler.ts +3 -11
- package/src/core/constants.ts +41 -0
- package/src/core/detector/detector-lite.js +2 -12
- package/src/core/image-list.js +5 -4
- package/src/core/matching/matching.js +8 -7
- package/src/core/tracker/tracker.js +4 -3
- package/src/runtime/controller.ts +10 -9
- package/dist/compiler/offline-compiler-browsertest.d.ts +0 -2
- package/dist/compiler/offline-compiler-browsertest.js +0 -8
- package/src/compiler/offline-compiler-browsertest.js +0 -11
|
@@ -11,7 +11,7 @@ import { DetectorLite } from "../core/detector/detector-lite.js";
|
|
|
11
11
|
import { build as hierarchicalClusteringBuild } from "../core/matching/hierarchical-clustering.js";
|
|
12
12
|
import * as protocol from "../core/protocol.js";
|
|
13
13
|
import { triangulate, getEdges } from "../core/utils/delaunay.js";
|
|
14
|
-
import {
|
|
14
|
+
import { AR_CONFIG } from "../core/constants.js";
|
|
15
15
|
// Detect environment
|
|
16
16
|
const isNode = typeof process !== "undefined" &&
|
|
17
17
|
process.versions != null &&
|
|
@@ -79,16 +79,8 @@ export class OfflineCompiler {
|
|
|
79
79
|
const percentPerImageScale = percentPerImage / imageList.length;
|
|
80
80
|
const keyframes = [];
|
|
81
81
|
for (const image of imageList) {
|
|
82
|
-
const detector = new DetectorLite(image.width, image.height, { useLSH:
|
|
82
|
+
const detector = new DetectorLite(image.width, image.height, { useLSH: AR_CONFIG.USE_LSH, maxFeaturesPerBucket: AR_CONFIG.MAX_FEATURES_PER_BUCKET });
|
|
83
83
|
const { featurePoints: ps } = detector.detect(image.data);
|
|
84
|
-
// HDC Pre-calculation
|
|
85
|
-
const hdcBasis = generateBasis(protocol.HDC_SEED, 1024);
|
|
86
|
-
for (const p of ps) {
|
|
87
|
-
if (p.descriptors) {
|
|
88
|
-
const hv = projectDescriptor(p.descriptors, hdcBasis);
|
|
89
|
-
p.hdcSignature = compressToSignature(hv);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
84
|
const maximaPoints = ps.filter((p) => p.maxima);
|
|
93
85
|
const minimaPoints = ps.filter((p) => !p.maxima);
|
|
94
86
|
const maximaPointsCluster = hierarchicalClusteringBuild({ points: maximaPoints });
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized constants for the AR Engine
|
|
3
|
+
*/
|
|
4
|
+
export declare const AR_CONFIG: {
|
|
5
|
+
VIEWPORT_WIDTH: number;
|
|
6
|
+
VIEWPORT_HEIGHT: number;
|
|
7
|
+
DEFAULT_FOVY: number;
|
|
8
|
+
DEFAULT_NEAR: number;
|
|
9
|
+
DEFAULT_FAR: number;
|
|
10
|
+
MAX_FEATURES_PER_BUCKET: number;
|
|
11
|
+
USE_LSH: boolean;
|
|
12
|
+
HAMMING_THRESHOLD: number;
|
|
13
|
+
HDC_RATIO_THRESHOLD: number;
|
|
14
|
+
INLIER_THRESHOLD: number;
|
|
15
|
+
MIN_NUM_INLIERS: number;
|
|
16
|
+
MAX_MATCH_QUERY_POINTS: number;
|
|
17
|
+
CLUSTER_MAX_POP: number;
|
|
18
|
+
TRACKER_TEMPLATE_SIZE: number;
|
|
19
|
+
TRACKER_SEARCH_SIZE: number;
|
|
20
|
+
TRACKER_SIMILARITY_THRESHOLD: number;
|
|
21
|
+
MIN_IMAGE_PIXEL_SIZE: number;
|
|
22
|
+
SCALE_STEP_EXPONENT: number;
|
|
23
|
+
TRACKING_DOWNSCALE_LEVEL_1: number;
|
|
24
|
+
TRACKING_DOWNSCALE_LEVEL_2: number;
|
|
25
|
+
WARMUP_TOLERANCE: number;
|
|
26
|
+
MISS_TOLERANCE: number;
|
|
27
|
+
ONE_EURO_FILTER_CUTOFF: number;
|
|
28
|
+
ONE_EURO_FILTER_BETA: number;
|
|
29
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized constants for the AR Engine
|
|
3
|
+
*/
|
|
4
|
+
export const AR_CONFIG = {
|
|
5
|
+
// Camera settings
|
|
6
|
+
VIEWPORT_WIDTH: 640,
|
|
7
|
+
VIEWPORT_HEIGHT: 480,
|
|
8
|
+
DEFAULT_FOVY: 60.0,
|
|
9
|
+
DEFAULT_NEAR: 1.0,
|
|
10
|
+
DEFAULT_FAR: 10000.0,
|
|
11
|
+
// Detection settings
|
|
12
|
+
MAX_FEATURES_PER_BUCKET: 24,
|
|
13
|
+
USE_LSH: true,
|
|
14
|
+
// Matching settings
|
|
15
|
+
HAMMING_THRESHOLD: 0.85,
|
|
16
|
+
HDC_RATIO_THRESHOLD: 0.85,
|
|
17
|
+
INLIER_THRESHOLD: 15.0,
|
|
18
|
+
MIN_NUM_INLIERS: 6,
|
|
19
|
+
MAX_MATCH_QUERY_POINTS: 800,
|
|
20
|
+
CLUSTER_MAX_POP: 25,
|
|
21
|
+
// Tracker / NCC settings
|
|
22
|
+
TRACKER_TEMPLATE_SIZE: 6,
|
|
23
|
+
TRACKER_SEARCH_SIZE: 12,
|
|
24
|
+
TRACKER_SIMILARITY_THRESHOLD: 0.65,
|
|
25
|
+
// Image processing / Scale list
|
|
26
|
+
MIN_IMAGE_PIXEL_SIZE: 32,
|
|
27
|
+
SCALE_STEP_EXPONENT: 0.6,
|
|
28
|
+
TRACKING_DOWNSCALE_LEVEL_1: 256.0,
|
|
29
|
+
TRACKING_DOWNSCALE_LEVEL_2: 128.0,
|
|
30
|
+
// Tracker settings
|
|
31
|
+
WARMUP_TOLERANCE: 2,
|
|
32
|
+
MISS_TOLERANCE: 1,
|
|
33
|
+
ONE_EURO_FILTER_CUTOFF: 0.5,
|
|
34
|
+
ONE_EURO_FILTER_BETA: 0.1,
|
|
35
|
+
};
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
import { FREAKPOINTS } from "./freak.js";
|
|
13
13
|
import { gpuCompute } from "../utils/gpu-compute.js";
|
|
14
14
|
import { computeLSH64, computeFullFREAK, packLSHIntoDescriptor } from "../utils/lsh-direct.js";
|
|
15
|
-
import { generateBasis, projectDescriptor, compressToSignature } from "../matching/hdc.js";
|
|
16
15
|
import { HDC_SEED } from "../protocol.js";
|
|
17
16
|
const PYRAMID_MIN_SIZE = 4; // Restored to 4 for better small-scale detection
|
|
18
17
|
// PYRAMID_MAX_OCTAVE ya no es necesario, el límite lo da PYRAMID_MIN_SIZE
|
|
@@ -82,16 +81,6 @@ export class DetectorLite {
|
|
|
82
81
|
this._computeOrientations(prunedExtremas, pyramidImages);
|
|
83
82
|
// 6. Calcular descriptores FREAK
|
|
84
83
|
this._computeFreakDescriptors(prunedExtremas, pyramidImages);
|
|
85
|
-
// 7. 🚀 MOONSHOT: HDC Hyper-projection
|
|
86
|
-
if (this.useHDC) {
|
|
87
|
-
const hdcBasis = generateBasis(HDC_SEED, 1024);
|
|
88
|
-
for (const ext of prunedExtremas) {
|
|
89
|
-
if (ext.lsh) {
|
|
90
|
-
const hv = projectDescriptor(ext.lsh, hdcBasis);
|
|
91
|
-
ext.hdcSignature = compressToSignature(hv);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
84
|
// Convertir a formato de salida
|
|
96
85
|
const featurePoints = prunedExtremas.map(ext => {
|
|
97
86
|
const scale = Math.pow(2, ext.octave);
|
|
@@ -101,8 +90,8 @@ export class DetectorLite {
|
|
|
101
90
|
y: ext.y * scale + scale * 0.5 - 0.5,
|
|
102
91
|
scale: scale,
|
|
103
92
|
angle: ext.angle || 0,
|
|
93
|
+
score: ext.absScore, // Pass through score for sorting in Matcher
|
|
104
94
|
descriptors: (this.useLSH && ext.lsh) ? ext.lsh : (ext.descriptors || []),
|
|
105
|
-
hdcSignature: ext.hdcSignature || 0,
|
|
106
95
|
imageData: data // Pass source image for refinement
|
|
107
96
|
};
|
|
108
97
|
});
|
package/dist/core/image-list.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { resize } from "./utils/images.js";
|
|
2
|
+
import { AR_CONFIG } from "./constants.js";
|
|
2
3
|
/**
|
|
3
4
|
* Tamaño mínimo de píxeles para el procesamiento de imágenes
|
|
4
5
|
* Un valor más bajo permite detectar imágenes más pequeñas pero aumenta el tiempo de procesamiento
|
|
5
6
|
* @constant {number}
|
|
6
7
|
*/
|
|
7
|
-
const MIN_IMAGE_PIXEL_SIZE =
|
|
8
|
+
const MIN_IMAGE_PIXEL_SIZE = AR_CONFIG.MIN_IMAGE_PIXEL_SIZE;
|
|
8
9
|
/**
|
|
9
10
|
* Construye una lista de imágenes con diferentes escalas para detección de características
|
|
10
11
|
* @param {Object} inputImage - Imagen de entrada con propiedades width, height y data
|
|
@@ -18,7 +19,7 @@ const buildImageList = (inputImage) => {
|
|
|
18
19
|
scaleList.push(c);
|
|
19
20
|
// Optimization: Paso balanceado (aprox 1.5)
|
|
20
21
|
// Mejor cobertura que 2.0, pero mucho más ligero que 1.41 o 1.26
|
|
21
|
-
c *= Math.pow(2.0,
|
|
22
|
+
c *= Math.pow(2.0, AR_CONFIG.SCALE_STEP_EXPONENT);
|
|
22
23
|
if (c >= 0.95) {
|
|
23
24
|
c = 1;
|
|
24
25
|
break;
|
|
@@ -43,8 +44,8 @@ const buildTrackingImageList = (inputImage) => {
|
|
|
43
44
|
const scaleList = [];
|
|
44
45
|
const imageList = [];
|
|
45
46
|
// Generamos versiones de 256px y 128px para tracking robusto a diferentes distancias
|
|
46
|
-
scaleList.push(
|
|
47
|
-
scaleList.push(
|
|
47
|
+
scaleList.push(AR_CONFIG.TRACKING_DOWNSCALE_LEVEL_1 / minDimension);
|
|
48
|
+
scaleList.push(AR_CONFIG.TRACKING_DOWNSCALE_LEVEL_2 / minDimension);
|
|
48
49
|
for (let i = 0; i < scaleList.length; i++) {
|
|
49
50
|
imageList.push(Object.assign(resize({ image: inputImage, ratio: scaleList[i] }), { scale: scaleList[i] }));
|
|
50
51
|
}
|
|
@@ -5,12 +5,13 @@ import { computeHomography } from "./ransacHomography.js";
|
|
|
5
5
|
import { multiplyPointHomographyInhomogenous, matrixInverse33 } from "../utils/geometry.js";
|
|
6
6
|
import { refineWithMorphology } from "../estimation/morph-refinement.js";
|
|
7
7
|
import { popcount32 } from "./hierarchical-clustering.js";
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
8
|
+
import { AR_CONFIG } from "../constants.js";
|
|
9
|
+
const INLIER_THRESHOLD = AR_CONFIG.INLIER_THRESHOLD;
|
|
10
|
+
const MIN_NUM_INLIERS = AR_CONFIG.MIN_NUM_INLIERS;
|
|
11
|
+
const CLUSTER_MAX_POP = AR_CONFIG.CLUSTER_MAX_POP;
|
|
12
|
+
const HAMMING_THRESHOLD = AR_CONFIG.HAMMING_THRESHOLD;
|
|
13
|
+
const HDC_RATIO_THRESHOLD = AR_CONFIG.HDC_RATIO_THRESHOLD;
|
|
14
|
+
const MAX_MATCH_QUERY_POINTS = AR_CONFIG.MAX_MATCH_QUERY_POINTS;
|
|
14
15
|
// match list of querpoints against pre-built list of keyframes
|
|
15
16
|
const match = ({ keyframe, querypoints: rawQuerypoints, querywidth, queryheight, debugMode }) => {
|
|
16
17
|
let debugExtra = {};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../estimation/utils.js";
|
|
2
2
|
import { refineNonRigid, projectMesh } from "../estimation/non-rigid-refine.js";
|
|
3
|
-
|
|
3
|
+
import { AR_CONFIG } from "../constants.js";
|
|
4
|
+
const AR2_DEFAULT_TS = AR_CONFIG.TRACKER_TEMPLATE_SIZE;
|
|
4
5
|
const AR2_DEFAULT_TS_GAP = 1;
|
|
5
|
-
const AR2_SEARCH_SIZE =
|
|
6
|
+
const AR2_SEARCH_SIZE = AR_CONFIG.TRACKER_SEARCH_SIZE;
|
|
6
7
|
const AR2_SEARCH_GAP = 1;
|
|
7
|
-
const AR2_SIM_THRESH =
|
|
8
|
+
const AR2_SIM_THRESH = AR_CONFIG.TRACKER_SIMILARITY_THRESHOLD;
|
|
8
9
|
const TRACKING_KEYFRAME = 0; // 0: 128px (optimized)
|
|
9
10
|
class Tracker {
|
|
10
11
|
constructor(markerDimensions, trackingDataList, projectionTransform, inputWidth, inputHeight, debugMode = false) {
|
|
@@ -6,6 +6,7 @@ import { TemporalFilterFeature } from "../core/features/temporal-filter-feature.
|
|
|
6
6
|
import { AutoRotationFeature } from "../core/features/auto-rotation-feature.js";
|
|
7
7
|
import { DetectorLite } from "../core/detector/detector-lite.js";
|
|
8
8
|
import * as protocol from "../core/protocol.js";
|
|
9
|
+
import { AR_CONFIG } from "../core/constants.js";
|
|
9
10
|
let ControllerWorker;
|
|
10
11
|
// Conditional import for worker to avoid crash in non-vite environments
|
|
11
12
|
const getControllerWorker = async () => {
|
|
@@ -21,10 +22,10 @@ const getControllerWorker = async () => {
|
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
24
|
ControllerWorker = await getControllerWorker();
|
|
24
|
-
const DEFAULT_FILTER_CUTOFF =
|
|
25
|
-
const DEFAULT_FILTER_BETA =
|
|
26
|
-
const DEFAULT_WARMUP_TOLERANCE =
|
|
27
|
-
const DEFAULT_MISS_TOLERANCE =
|
|
25
|
+
const DEFAULT_FILTER_CUTOFF = AR_CONFIG.ONE_EURO_FILTER_CUTOFF;
|
|
26
|
+
const DEFAULT_FILTER_BETA = AR_CONFIG.ONE_EURO_FILTER_BETA;
|
|
27
|
+
const DEFAULT_WARMUP_TOLERANCE = AR_CONFIG.WARMUP_TOLERANCE;
|
|
28
|
+
const DEFAULT_MISS_TOLERANCE = AR_CONFIG.MISS_TOLERANCE;
|
|
28
29
|
const WORKER_TIMEOUT_MS = 1000; // Prevent worker hangs from killing the loop
|
|
29
30
|
let loopIdCounter = 0;
|
|
30
31
|
class Controller {
|
|
@@ -67,8 +68,8 @@ class Controller {
|
|
|
67
68
|
this._setupWorkerListener();
|
|
68
69
|
// Moonshot: Full frame detector for better sensitivity
|
|
69
70
|
this.fullDetector = new DetectorLite(this.inputWidth, this.inputHeight, {
|
|
70
|
-
useLSH:
|
|
71
|
-
maxFeaturesPerBucket:
|
|
71
|
+
useLSH: AR_CONFIG.USE_LSH,
|
|
72
|
+
maxFeaturesPerBucket: AR_CONFIG.MAX_FEATURES_PER_BUCKET
|
|
72
73
|
});
|
|
73
74
|
this.featureManager.init({
|
|
74
75
|
inputWidth: this.inputWidth,
|
|
@@ -76,9 +77,9 @@ class Controller {
|
|
|
76
77
|
projectionTransform: [], // Will be set below
|
|
77
78
|
debugMode: this.debugMode
|
|
78
79
|
});
|
|
79
|
-
const near =
|
|
80
|
-
const far =
|
|
81
|
-
const fovy = (
|
|
80
|
+
const near = AR_CONFIG.DEFAULT_NEAR;
|
|
81
|
+
const far = AR_CONFIG.DEFAULT_FAR;
|
|
82
|
+
const fovy = (AR_CONFIG.DEFAULT_FOVY * Math.PI) / 180;
|
|
82
83
|
const f = this.inputHeight / 2 / Math.tan(fovy / 2);
|
|
83
84
|
this.projectionTransform = [
|
|
84
85
|
[f, 0, this.inputWidth / 2],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@srsergio/taptapp-ar",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.92",
|
|
4
4
|
"description": "Ultra-fast Augmented Reality (AR) SDK for Node.js and Browser. Image tracking with 100% pure JavaScript, zero-dependencies, and high-performance compilation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augmented reality",
|
|
@@ -12,7 +12,8 @@ import { DetectorLite } from "../core/detector/detector-lite.js";
|
|
|
12
12
|
import { build as hierarchicalClusteringBuild } from "../core/matching/hierarchical-clustering.js";
|
|
13
13
|
import * as protocol from "../core/protocol.js";
|
|
14
14
|
import { triangulate, getEdges } from "../core/utils/delaunay.js";
|
|
15
|
-
import {
|
|
15
|
+
import { AR_CONFIG } from "../core/constants.js";
|
|
16
|
+
|
|
16
17
|
|
|
17
18
|
// Detect environment
|
|
18
19
|
const isNode = typeof process !== "undefined" &&
|
|
@@ -101,18 +102,9 @@ export class OfflineCompiler {
|
|
|
101
102
|
const keyframes = [];
|
|
102
103
|
|
|
103
104
|
for (const image of imageList as any[]) {
|
|
104
|
-
const detector = new DetectorLite(image.width, image.height, { useLSH:
|
|
105
|
+
const detector = new DetectorLite(image.width, image.height, { useLSH: AR_CONFIG.USE_LSH, maxFeaturesPerBucket: AR_CONFIG.MAX_FEATURES_PER_BUCKET });
|
|
105
106
|
const { featurePoints: ps } = detector.detect(image.data);
|
|
106
107
|
|
|
107
|
-
// HDC Pre-calculation
|
|
108
|
-
const hdcBasis = generateBasis(protocol.HDC_SEED, 1024);
|
|
109
|
-
for (const p of ps) {
|
|
110
|
-
if (p.descriptors) {
|
|
111
|
-
const hv = projectDescriptor(p.descriptors, hdcBasis);
|
|
112
|
-
p.hdcSignature = compressToSignature(hv);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
108
|
const maximaPoints = ps.filter((p: any) => p.maxima);
|
|
117
109
|
const minimaPoints = ps.filter((p: any) => !p.maxima);
|
|
118
110
|
const maximaPointsCluster = hierarchicalClusteringBuild({ points: maximaPoints });
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized constants for the AR Engine
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const AR_CONFIG = {
|
|
6
|
+
// Camera settings
|
|
7
|
+
VIEWPORT_WIDTH: 640,
|
|
8
|
+
VIEWPORT_HEIGHT: 480,
|
|
9
|
+
DEFAULT_FOVY: 60.0,
|
|
10
|
+
DEFAULT_NEAR: 1.0,
|
|
11
|
+
DEFAULT_FAR: 10000.0,
|
|
12
|
+
|
|
13
|
+
// Detection settings
|
|
14
|
+
MAX_FEATURES_PER_BUCKET: 24,
|
|
15
|
+
USE_LSH: true,
|
|
16
|
+
|
|
17
|
+
// Matching settings
|
|
18
|
+
HAMMING_THRESHOLD: 0.85,
|
|
19
|
+
HDC_RATIO_THRESHOLD: 0.85,
|
|
20
|
+
INLIER_THRESHOLD: 15.0,
|
|
21
|
+
MIN_NUM_INLIERS: 6,
|
|
22
|
+
MAX_MATCH_QUERY_POINTS: 800,
|
|
23
|
+
CLUSTER_MAX_POP: 25,
|
|
24
|
+
|
|
25
|
+
// Tracker / NCC settings
|
|
26
|
+
TRACKER_TEMPLATE_SIZE: 6,
|
|
27
|
+
TRACKER_SEARCH_SIZE: 12,
|
|
28
|
+
TRACKER_SIMILARITY_THRESHOLD: 0.65,
|
|
29
|
+
|
|
30
|
+
// Image processing / Scale list
|
|
31
|
+
MIN_IMAGE_PIXEL_SIZE: 32,
|
|
32
|
+
SCALE_STEP_EXPONENT: 0.6,
|
|
33
|
+
TRACKING_DOWNSCALE_LEVEL_1: 256.0,
|
|
34
|
+
TRACKING_DOWNSCALE_LEVEL_2: 128.0,
|
|
35
|
+
|
|
36
|
+
// Tracker settings
|
|
37
|
+
WARMUP_TOLERANCE: 2,
|
|
38
|
+
MISS_TOLERANCE: 1,
|
|
39
|
+
ONE_EURO_FILTER_CUTOFF: 0.5,
|
|
40
|
+
ONE_EURO_FILTER_BETA: 0.1,
|
|
41
|
+
};
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
import { FREAKPOINTS } from "./freak.js";
|
|
14
14
|
import { gpuCompute } from "../utils/gpu-compute.js";
|
|
15
15
|
import { computeLSH64, computeFullFREAK, packLSHIntoDescriptor } from "../utils/lsh-direct.js";
|
|
16
|
-
import { generateBasis, projectDescriptor, compressToSignature } from "../matching/hdc.js";
|
|
17
16
|
import { HDC_SEED } from "../protocol.js";
|
|
18
17
|
|
|
19
18
|
const PYRAMID_MIN_SIZE = 4; // Restored to 4 for better small-scale detection
|
|
@@ -99,16 +98,7 @@ export class DetectorLite {
|
|
|
99
98
|
// 6. Calcular descriptores FREAK
|
|
100
99
|
this._computeFreakDescriptors(prunedExtremas, pyramidImages);
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
if (this.useHDC) {
|
|
104
|
-
const hdcBasis = generateBasis(HDC_SEED, 1024);
|
|
105
|
-
for (const ext of prunedExtremas) {
|
|
106
|
-
if (ext.lsh) {
|
|
107
|
-
const hv = projectDescriptor(ext.lsh, hdcBasis);
|
|
108
|
-
ext.hdcSignature = compressToSignature(hv);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
101
|
+
|
|
112
102
|
|
|
113
103
|
// Convertir a formato de salida
|
|
114
104
|
const featurePoints = prunedExtremas.map(ext => {
|
|
@@ -119,8 +109,8 @@ export class DetectorLite {
|
|
|
119
109
|
y: ext.y * scale + scale * 0.5 - 0.5,
|
|
120
110
|
scale: scale,
|
|
121
111
|
angle: ext.angle || 0,
|
|
112
|
+
score: ext.absScore, // Pass through score for sorting in Matcher
|
|
122
113
|
descriptors: (this.useLSH && ext.lsh) ? ext.lsh : (ext.descriptors || []),
|
|
123
|
-
hdcSignature: ext.hdcSignature || 0,
|
|
124
114
|
imageData: data // Pass source image for refinement
|
|
125
115
|
};
|
|
126
116
|
});
|
package/src/core/image-list.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { resize } from "./utils/images.js";
|
|
2
|
+
import { AR_CONFIG } from "./constants.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Tamaño mínimo de píxeles para el procesamiento de imágenes
|
|
5
6
|
* Un valor más bajo permite detectar imágenes más pequeñas pero aumenta el tiempo de procesamiento
|
|
6
7
|
* @constant {number}
|
|
7
8
|
*/
|
|
8
|
-
const MIN_IMAGE_PIXEL_SIZE =
|
|
9
|
+
const MIN_IMAGE_PIXEL_SIZE = AR_CONFIG.MIN_IMAGE_PIXEL_SIZE;
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
@@ -23,7 +24,7 @@ const buildImageList = (inputImage) => {
|
|
|
23
24
|
scaleList.push(c);
|
|
24
25
|
// Optimization: Paso balanceado (aprox 1.5)
|
|
25
26
|
// Mejor cobertura que 2.0, pero mucho más ligero que 1.41 o 1.26
|
|
26
|
-
c *= Math.pow(2.0,
|
|
27
|
+
c *= Math.pow(2.0, AR_CONFIG.SCALE_STEP_EXPONENT);
|
|
27
28
|
if (c >= 0.95) {
|
|
28
29
|
c = 1;
|
|
29
30
|
break;
|
|
@@ -52,8 +53,8 @@ const buildTrackingImageList = (inputImage) => {
|
|
|
52
53
|
const scaleList = [];
|
|
53
54
|
const imageList = [];
|
|
54
55
|
// Generamos versiones de 256px y 128px para tracking robusto a diferentes distancias
|
|
55
|
-
scaleList.push(
|
|
56
|
-
scaleList.push(
|
|
56
|
+
scaleList.push(AR_CONFIG.TRACKING_DOWNSCALE_LEVEL_1 / minDimension);
|
|
57
|
+
scaleList.push(AR_CONFIG.TRACKING_DOWNSCALE_LEVEL_2 / minDimension);
|
|
57
58
|
for (let i = 0; i < scaleList.length; i++) {
|
|
58
59
|
imageList.push(
|
|
59
60
|
Object.assign(resize({ image: inputImage, ratio: scaleList[i] }), { scale: scaleList[i] }),
|
|
@@ -5,13 +5,14 @@ import { computeHomography } from "./ransacHomography.js";
|
|
|
5
5
|
import { multiplyPointHomographyInhomogenous, matrixInverse33 } from "../utils/geometry.js";
|
|
6
6
|
import { refineWithMorphology } from "../estimation/morph-refinement.js";
|
|
7
7
|
import { popcount32 } from "./hierarchical-clustering.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
8
|
+
import { AR_CONFIG } from "../constants.js";
|
|
9
|
+
|
|
10
|
+
const INLIER_THRESHOLD = AR_CONFIG.INLIER_THRESHOLD;
|
|
11
|
+
const MIN_NUM_INLIERS = AR_CONFIG.MIN_NUM_INLIERS;
|
|
12
|
+
const CLUSTER_MAX_POP = AR_CONFIG.CLUSTER_MAX_POP;
|
|
13
|
+
const HAMMING_THRESHOLD = AR_CONFIG.HAMMING_THRESHOLD;
|
|
14
|
+
const HDC_RATIO_THRESHOLD = AR_CONFIG.HDC_RATIO_THRESHOLD;
|
|
15
|
+
const MAX_MATCH_QUERY_POINTS = AR_CONFIG.MAX_MATCH_QUERY_POINTS;
|
|
15
16
|
|
|
16
17
|
// match list of querpoints against pre-built list of keyframes
|
|
17
18
|
const match = ({ keyframe, querypoints: rawQuerypoints, querywidth, queryheight, debugMode }) => {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../estimation/utils.js";
|
|
2
2
|
import { refineNonRigid, projectMesh } from "../estimation/non-rigid-refine.js";
|
|
3
|
+
import { AR_CONFIG } from "../constants.js";
|
|
3
4
|
|
|
4
|
-
const AR2_DEFAULT_TS =
|
|
5
|
+
const AR2_DEFAULT_TS = AR_CONFIG.TRACKER_TEMPLATE_SIZE;
|
|
5
6
|
const AR2_DEFAULT_TS_GAP = 1;
|
|
6
|
-
const AR2_SEARCH_SIZE =
|
|
7
|
+
const AR2_SEARCH_SIZE = AR_CONFIG.TRACKER_SEARCH_SIZE;
|
|
7
8
|
const AR2_SEARCH_GAP = 1;
|
|
8
|
-
const AR2_SIM_THRESH =
|
|
9
|
+
const AR2_SIM_THRESH = AR_CONFIG.TRACKER_SIMILARITY_THRESHOLD;
|
|
9
10
|
|
|
10
11
|
const TRACKING_KEYFRAME = 0; // 0: 128px (optimized)
|
|
11
12
|
|
|
@@ -6,6 +6,7 @@ import { TemporalFilterFeature } from "../core/features/temporal-filter-feature.
|
|
|
6
6
|
import { AutoRotationFeature } from "../core/features/auto-rotation-feature.js";
|
|
7
7
|
import { DetectorLite } from "../core/detector/detector-lite.js";
|
|
8
8
|
import * as protocol from "../core/protocol.js";
|
|
9
|
+
import { AR_CONFIG } from "../core/constants.js";
|
|
9
10
|
|
|
10
11
|
let ControllerWorker: any;
|
|
11
12
|
|
|
@@ -22,10 +23,10 @@ const getControllerWorker = async () => {
|
|
|
22
23
|
};
|
|
23
24
|
ControllerWorker = await getControllerWorker();
|
|
24
25
|
|
|
25
|
-
const DEFAULT_FILTER_CUTOFF =
|
|
26
|
-
const DEFAULT_FILTER_BETA =
|
|
27
|
-
const DEFAULT_WARMUP_TOLERANCE =
|
|
28
|
-
const DEFAULT_MISS_TOLERANCE =
|
|
26
|
+
const DEFAULT_FILTER_CUTOFF = AR_CONFIG.ONE_EURO_FILTER_CUTOFF;
|
|
27
|
+
const DEFAULT_FILTER_BETA = AR_CONFIG.ONE_EURO_FILTER_BETA;
|
|
28
|
+
const DEFAULT_WARMUP_TOLERANCE = AR_CONFIG.WARMUP_TOLERANCE;
|
|
29
|
+
const DEFAULT_MISS_TOLERANCE = AR_CONFIG.MISS_TOLERANCE;
|
|
29
30
|
const WORKER_TIMEOUT_MS = 1000; // Prevent worker hangs from killing the loop
|
|
30
31
|
|
|
31
32
|
let loopIdCounter = 0;
|
|
@@ -103,8 +104,8 @@ class Controller {
|
|
|
103
104
|
|
|
104
105
|
// Moonshot: Full frame detector for better sensitivity
|
|
105
106
|
this.fullDetector = new DetectorLite(this.inputWidth, this.inputHeight, {
|
|
106
|
-
useLSH:
|
|
107
|
-
maxFeaturesPerBucket:
|
|
107
|
+
useLSH: AR_CONFIG.USE_LSH,
|
|
108
|
+
maxFeaturesPerBucket: AR_CONFIG.MAX_FEATURES_PER_BUCKET
|
|
108
109
|
});
|
|
109
110
|
|
|
110
111
|
this.featureManager.init({
|
|
@@ -114,9 +115,9 @@ class Controller {
|
|
|
114
115
|
debugMode: this.debugMode
|
|
115
116
|
});
|
|
116
117
|
|
|
117
|
-
const near =
|
|
118
|
-
const far =
|
|
119
|
-
const fovy = (
|
|
118
|
+
const near = AR_CONFIG.DEFAULT_NEAR;
|
|
119
|
+
const far = AR_CONFIG.DEFAULT_FAR;
|
|
120
|
+
const fovy = (AR_CONFIG.DEFAULT_FOVY * Math.PI) / 180;
|
|
120
121
|
const f = this.inputHeight / 2 / Math.tan(fovy / 2);
|
|
121
122
|
|
|
122
123
|
this.projectionTransform = [
|