@srsergio/taptapp-ar 1.0.92 → 1.0.94
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 +16 -14
- package/dist/compiler/offline-compiler.d.ts +3 -3
- package/dist/compiler/offline-compiler.js +50 -33
- package/dist/core/constants.d.ts +2 -0
- package/dist/core/constants.js +4 -1
- package/dist/core/detector/detector-lite.d.ts +6 -5
- package/dist/core/detector/detector-lite.js +46 -16
- package/dist/core/image-list.d.ts +24 -6
- package/dist/core/image-list.js +4 -4
- package/dist/core/matching/matcher.d.ts +1 -1
- package/dist/core/matching/matcher.js +7 -4
- package/dist/core/matching/matching.d.ts +2 -1
- package/dist/core/matching/matching.js +43 -11
- package/dist/core/perception/bio-inspired-engine.d.ts +130 -0
- package/dist/core/perception/bio-inspired-engine.js +232 -0
- package/dist/core/perception/foveal-attention.d.ts +142 -0
- package/dist/core/perception/foveal-attention.js +280 -0
- package/dist/core/perception/index.d.ts +6 -0
- package/dist/core/perception/index.js +17 -0
- package/dist/core/perception/predictive-coding.d.ts +92 -0
- package/dist/core/perception/predictive-coding.js +278 -0
- package/dist/core/perception/saccadic-controller.d.ts +126 -0
- package/dist/core/perception/saccadic-controller.js +269 -0
- package/dist/core/perception/saliency-map.d.ts +74 -0
- package/dist/core/perception/saliency-map.js +254 -0
- package/dist/core/perception/scale-orchestrator.d.ts +28 -0
- package/dist/core/perception/scale-orchestrator.js +68 -0
- package/dist/core/protocol.d.ts +14 -1
- package/dist/core/protocol.js +33 -1
- package/dist/runtime/bio-inspired-controller.d.ts +135 -0
- package/dist/runtime/bio-inspired-controller.js +358 -0
- package/dist/runtime/controller.d.ts +11 -2
- package/dist/runtime/controller.js +20 -8
- package/dist/runtime/controller.worker.js +2 -2
- package/package.json +1 -1
- package/src/compiler/offline-compiler.ts +56 -36
- package/src/core/constants.ts +5 -1
- package/src/core/detector/detector-lite.js +46 -16
- package/src/core/image-list.js +4 -4
- package/src/core/matching/matcher.js +8 -4
- package/src/core/matching/matching.js +51 -12
- package/src/core/perception/bio-inspired-engine.js +275 -0
- package/src/core/perception/foveal-attention.js +306 -0
- package/src/core/perception/index.js +18 -0
- package/src/core/perception/predictive-coding.js +327 -0
- package/src/core/perception/saccadic-controller.js +303 -0
- package/src/core/perception/saliency-map.js +296 -0
- package/src/core/perception/scale-orchestrator.js +80 -0
- package/src/core/protocol.ts +38 -1
- package/src/runtime/bio-inspired-controller.ts +448 -0
- package/src/runtime/controller.ts +22 -7
- package/src/runtime/controller.worker.js +2 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A saccade target representing where attention should be directed
|
|
3
|
+
*/
|
|
4
|
+
export type SaccadeTarget = {
|
|
5
|
+
/**
|
|
6
|
+
* - X coordinate
|
|
7
|
+
*/
|
|
8
|
+
x: number;
|
|
9
|
+
/**
|
|
10
|
+
* - Y coordinate
|
|
11
|
+
*/
|
|
12
|
+
y: number;
|
|
13
|
+
/**
|
|
14
|
+
* - Priority (0 = highest)
|
|
15
|
+
*/
|
|
16
|
+
priority: number;
|
|
17
|
+
/**
|
|
18
|
+
* - Why this target was selected
|
|
19
|
+
*/
|
|
20
|
+
reason: string;
|
|
21
|
+
/**
|
|
22
|
+
* - Saliency score at this location
|
|
23
|
+
*/
|
|
24
|
+
saliency: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Saccadic Controller
|
|
28
|
+
*
|
|
29
|
+
* Mimics human eye saccades - rapid movements that redirect foveal attention
|
|
30
|
+
* to areas of interest. The human eye makes 3-4 saccades per second to
|
|
31
|
+
* build a complete picture of the visual scene.
|
|
32
|
+
*
|
|
33
|
+
* Strategy:
|
|
34
|
+
* 1. Compute saliency map to find "interesting" regions
|
|
35
|
+
* 2. Use tracking state to predict where features should be
|
|
36
|
+
* 3. Generate priority-ordered list of "glance" targets
|
|
37
|
+
* 4. Limit saccades per frame to balance coverage vs. efficiency
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* A saccade target representing where attention should be directed
|
|
41
|
+
* @typedef {Object} SaccadeTarget
|
|
42
|
+
* @property {number} x - X coordinate
|
|
43
|
+
* @property {number} y - Y coordinate
|
|
44
|
+
* @property {number} priority - Priority (0 = highest)
|
|
45
|
+
* @property {string} reason - Why this target was selected
|
|
46
|
+
* @property {number} saliency - Saliency score at this location
|
|
47
|
+
*/
|
|
48
|
+
export class SaccadicController {
|
|
49
|
+
/**
|
|
50
|
+
* @param {number} width - Image width
|
|
51
|
+
* @param {number} height - Image height
|
|
52
|
+
* @param {Object} config - Configuration
|
|
53
|
+
*/
|
|
54
|
+
constructor(width: number, height: number, config: Object);
|
|
55
|
+
width: number;
|
|
56
|
+
height: number;
|
|
57
|
+
config: Object;
|
|
58
|
+
recentTargets: any[];
|
|
59
|
+
inhibitionRadius: number;
|
|
60
|
+
velocityHistory: any[];
|
|
61
|
+
lastCenter: {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
};
|
|
65
|
+
gridCells: {
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
index: number;
|
|
69
|
+
lastVisit: number;
|
|
70
|
+
}[];
|
|
71
|
+
lastVisitedCell: number;
|
|
72
|
+
lastSaccadeTime: number;
|
|
73
|
+
saccadeCount: number;
|
|
74
|
+
/**
|
|
75
|
+
* Build a grid for systematic coverage during tracking loss
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
private _buildCoverageGrid;
|
|
79
|
+
/**
|
|
80
|
+
* Compute saccade targets based on current state
|
|
81
|
+
*
|
|
82
|
+
* @param {Object} saliency - Saliency map result
|
|
83
|
+
* @param {Object} currentFovea - Current fovea center {x, y}
|
|
84
|
+
* @param {Object} trackingState - Current tracking state (optional)
|
|
85
|
+
* @returns {SaccadeTarget[]} Priority-ordered list of targets
|
|
86
|
+
*/
|
|
87
|
+
computeTargets(saliency: Object, currentFovea: Object, trackingState?: Object): SaccadeTarget[];
|
|
88
|
+
/**
|
|
89
|
+
* Predict center of tracking based on current state and velocity
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
private _predictTrackingCenter;
|
|
93
|
+
/**
|
|
94
|
+
* Compute average velocity from history
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
private _computeAverageVelocity;
|
|
98
|
+
/**
|
|
99
|
+
* Check if a location is inhibited (too close to recent targets)
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
private _isInhibited;
|
|
103
|
+
/**
|
|
104
|
+
* Get next grid cell for systematic search
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
private _getNextGridCell;
|
|
108
|
+
/**
|
|
109
|
+
* Update history with new targets
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
private _updateHistory;
|
|
113
|
+
/**
|
|
114
|
+
* Get the most likely location of interest based on history
|
|
115
|
+
* @returns {Object} {x, y} of predicted location
|
|
116
|
+
*/
|
|
117
|
+
getPredictedLocation(): Object;
|
|
118
|
+
/**
|
|
119
|
+
* Reset controller state
|
|
120
|
+
*/
|
|
121
|
+
reset(): void;
|
|
122
|
+
/**
|
|
123
|
+
* Update configuration
|
|
124
|
+
*/
|
|
125
|
+
configure(config: any): void;
|
|
126
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saccadic Controller
|
|
3
|
+
*
|
|
4
|
+
* Mimics human eye saccades - rapid movements that redirect foveal attention
|
|
5
|
+
* to areas of interest. The human eye makes 3-4 saccades per second to
|
|
6
|
+
* build a complete picture of the visual scene.
|
|
7
|
+
*
|
|
8
|
+
* Strategy:
|
|
9
|
+
* 1. Compute saliency map to find "interesting" regions
|
|
10
|
+
* 2. Use tracking state to predict where features should be
|
|
11
|
+
* 3. Generate priority-ordered list of "glance" targets
|
|
12
|
+
* 4. Limit saccades per frame to balance coverage vs. efficiency
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* A saccade target representing where attention should be directed
|
|
16
|
+
* @typedef {Object} SaccadeTarget
|
|
17
|
+
* @property {number} x - X coordinate
|
|
18
|
+
* @property {number} y - Y coordinate
|
|
19
|
+
* @property {number} priority - Priority (0 = highest)
|
|
20
|
+
* @property {string} reason - Why this target was selected
|
|
21
|
+
* @property {number} saliency - Saliency score at this location
|
|
22
|
+
*/
|
|
23
|
+
class SaccadicController {
|
|
24
|
+
/**
|
|
25
|
+
* @param {number} width - Image width
|
|
26
|
+
* @param {number} height - Image height
|
|
27
|
+
* @param {Object} config - Configuration
|
|
28
|
+
*/
|
|
29
|
+
constructor(width, height, config) {
|
|
30
|
+
this.width = width;
|
|
31
|
+
this.height = height;
|
|
32
|
+
this.config = config;
|
|
33
|
+
// Saccade history for inhibition of return
|
|
34
|
+
this.recentTargets = [];
|
|
35
|
+
this.inhibitionRadius = Math.min(width, height) * 0.1;
|
|
36
|
+
// Movement prediction
|
|
37
|
+
this.velocityHistory = [];
|
|
38
|
+
this.lastCenter = { x: width / 2, y: height / 2 };
|
|
39
|
+
// Grid for systematic coverage
|
|
40
|
+
this.gridCells = this._buildCoverageGrid(3, 3);
|
|
41
|
+
this.lastVisitedCell = 4; // Center
|
|
42
|
+
// State
|
|
43
|
+
this.lastSaccadeTime = 0;
|
|
44
|
+
this.saccadeCount = 0;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Build a grid for systematic coverage during tracking loss
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
_buildCoverageGrid(rows, cols) {
|
|
51
|
+
const cells = [];
|
|
52
|
+
const cellW = this.width / cols;
|
|
53
|
+
const cellH = this.height / rows;
|
|
54
|
+
for (let r = 0; r < rows; r++) {
|
|
55
|
+
for (let c = 0; c < cols; c++) {
|
|
56
|
+
cells.push({
|
|
57
|
+
x: cellW * (c + 0.5),
|
|
58
|
+
y: cellH * (r + 0.5),
|
|
59
|
+
index: r * cols + c,
|
|
60
|
+
lastVisit: 0,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return cells;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Compute saccade targets based on current state
|
|
68
|
+
*
|
|
69
|
+
* @param {Object} saliency - Saliency map result
|
|
70
|
+
* @param {Object} currentFovea - Current fovea center {x, y}
|
|
71
|
+
* @param {Object} trackingState - Current tracking state (optional)
|
|
72
|
+
* @returns {SaccadeTarget[]} Priority-ordered list of targets
|
|
73
|
+
*/
|
|
74
|
+
computeTargets(saliency, currentFovea, trackingState = null) {
|
|
75
|
+
const targets = [];
|
|
76
|
+
const maxTargets = this.config.MAX_SACCADES_PER_FRAME;
|
|
77
|
+
// Strategy 1: Follow tracking prediction (highest priority)
|
|
78
|
+
if (trackingState && trackingState.isTracking) {
|
|
79
|
+
const predicted = this._predictTrackingCenter(trackingState);
|
|
80
|
+
if (predicted) {
|
|
81
|
+
targets.push({
|
|
82
|
+
x: predicted.x,
|
|
83
|
+
y: predicted.y,
|
|
84
|
+
priority: 0,
|
|
85
|
+
reason: 'tracking_prediction',
|
|
86
|
+
saliency: 1.0,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Strategy 2: High saliency regions
|
|
91
|
+
if (saliency && saliency.peaks) {
|
|
92
|
+
for (const peak of saliency.peaks) {
|
|
93
|
+
if (targets.length >= maxTargets)
|
|
94
|
+
break;
|
|
95
|
+
// Skip if too close to existing targets (inhibition of return)
|
|
96
|
+
if (this._isInhibited(peak.x, peak.y, targets))
|
|
97
|
+
continue;
|
|
98
|
+
if (peak.value > this.config.SALIENCY_THRESHOLD) {
|
|
99
|
+
targets.push({
|
|
100
|
+
x: peak.x,
|
|
101
|
+
y: peak.y,
|
|
102
|
+
priority: targets.length,
|
|
103
|
+
reason: 'saliency_peak',
|
|
104
|
+
saliency: peak.value,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Strategy 3: Systematic grid search (when not tracking)
|
|
110
|
+
if (!trackingState?.isTracking && targets.length < maxTargets) {
|
|
111
|
+
const gridTarget = this._getNextGridCell();
|
|
112
|
+
if (gridTarget && !this._isInhibited(gridTarget.x, gridTarget.y, targets)) {
|
|
113
|
+
targets.push({
|
|
114
|
+
x: gridTarget.x,
|
|
115
|
+
y: gridTarget.y,
|
|
116
|
+
priority: targets.length,
|
|
117
|
+
reason: 'grid_search',
|
|
118
|
+
saliency: 0.5,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Strategy 4: Stay at current center if no better options
|
|
123
|
+
if (targets.length === 0) {
|
|
124
|
+
targets.push({
|
|
125
|
+
x: currentFovea.x,
|
|
126
|
+
y: currentFovea.y,
|
|
127
|
+
priority: 0,
|
|
128
|
+
reason: 'maintain_position',
|
|
129
|
+
saliency: 0.3,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
// Update history
|
|
133
|
+
this._updateHistory(targets);
|
|
134
|
+
return targets;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Predict center of tracking based on current state and velocity
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
_predictTrackingCenter(trackingState) {
|
|
141
|
+
if (!trackingState.worldMatrix)
|
|
142
|
+
return null;
|
|
143
|
+
// Extract center from world matrix
|
|
144
|
+
const matrix = trackingState.worldMatrix;
|
|
145
|
+
const cx = matrix[12] || this.width / 2;
|
|
146
|
+
const cy = matrix[13] || this.height / 2;
|
|
147
|
+
// Apply velocity-based prediction
|
|
148
|
+
if (this.velocityHistory.length >= 2) {
|
|
149
|
+
const vx = this._computeAverageVelocity('x');
|
|
150
|
+
const vy = this._computeAverageVelocity('y');
|
|
151
|
+
// Predict 1 frame ahead
|
|
152
|
+
return {
|
|
153
|
+
x: Math.max(0, Math.min(this.width - 1, cx + vx)),
|
|
154
|
+
y: Math.max(0, Math.min(this.height - 1, cy + vy)),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return { x: cx, y: cy };
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Compute average velocity from history
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
_computeAverageVelocity(axis) {
|
|
164
|
+
if (this.velocityHistory.length < 2)
|
|
165
|
+
return 0;
|
|
166
|
+
let sum = 0;
|
|
167
|
+
for (let i = 1; i < this.velocityHistory.length; i++) {
|
|
168
|
+
sum += this.velocityHistory[i][axis] - this.velocityHistory[i - 1][axis];
|
|
169
|
+
}
|
|
170
|
+
return sum / (this.velocityHistory.length - 1);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Check if a location is inhibited (too close to recent targets)
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
_isInhibited(x, y, currentTargets) {
|
|
177
|
+
const r2 = this.inhibitionRadius ** 2;
|
|
178
|
+
// Check against current frame targets
|
|
179
|
+
for (const t of currentTargets) {
|
|
180
|
+
const dx = x - t.x;
|
|
181
|
+
const dy = y - t.y;
|
|
182
|
+
if (dx * dx + dy * dy < r2)
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
// Check against recent history
|
|
186
|
+
for (const t of this.recentTargets) {
|
|
187
|
+
const dx = x - t.x;
|
|
188
|
+
const dy = y - t.y;
|
|
189
|
+
if (dx * dx + dy * dy < r2)
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Get next grid cell for systematic search
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
_getNextGridCell() {
|
|
199
|
+
// Find least recently visited cell
|
|
200
|
+
let oldest = this.gridCells[0];
|
|
201
|
+
let oldestTime = Infinity;
|
|
202
|
+
for (const cell of this.gridCells) {
|
|
203
|
+
if (cell.lastVisit < oldestTime) {
|
|
204
|
+
oldestTime = cell.lastVisit;
|
|
205
|
+
oldest = cell;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
oldest.lastVisit = Date.now();
|
|
209
|
+
return oldest;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Update history with new targets
|
|
213
|
+
* @private
|
|
214
|
+
*/
|
|
215
|
+
_updateHistory(targets) {
|
|
216
|
+
// Add to recent targets for inhibition of return
|
|
217
|
+
this.recentTargets.push(...targets);
|
|
218
|
+
// Keep only last N targets
|
|
219
|
+
const maxHistory = this.config.MOTION_HISTORY_FRAMES * this.config.MAX_SACCADES_PER_FRAME;
|
|
220
|
+
while (this.recentTargets.length > maxHistory) {
|
|
221
|
+
this.recentTargets.shift();
|
|
222
|
+
}
|
|
223
|
+
// Update velocity history
|
|
224
|
+
if (targets.length > 0) {
|
|
225
|
+
this.velocityHistory.push({ x: targets[0].x, y: targets[0].y });
|
|
226
|
+
while (this.velocityHistory.length > this.config.MOTION_HISTORY_FRAMES) {
|
|
227
|
+
this.velocityHistory.shift();
|
|
228
|
+
}
|
|
229
|
+
this.lastCenter = { x: targets[0].x, y: targets[0].y };
|
|
230
|
+
}
|
|
231
|
+
this.saccadeCount += targets.length;
|
|
232
|
+
this.lastSaccadeTime = Date.now();
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get the most likely location of interest based on history
|
|
236
|
+
* @returns {Object} {x, y} of predicted location
|
|
237
|
+
*/
|
|
238
|
+
getPredictedLocation() {
|
|
239
|
+
if (this.velocityHistory.length >= 2) {
|
|
240
|
+
const vx = this._computeAverageVelocity('x');
|
|
241
|
+
const vy = this._computeAverageVelocity('y');
|
|
242
|
+
return {
|
|
243
|
+
x: Math.max(0, Math.min(this.width - 1, this.lastCenter.x + vx)),
|
|
244
|
+
y: Math.max(0, Math.min(this.height - 1, this.lastCenter.y + vy)),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return this.lastCenter;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Reset controller state
|
|
251
|
+
*/
|
|
252
|
+
reset() {
|
|
253
|
+
this.recentTargets = [];
|
|
254
|
+
this.velocityHistory = [];
|
|
255
|
+
this.lastCenter = { x: this.width / 2, y: this.height / 2 };
|
|
256
|
+
this.saccadeCount = 0;
|
|
257
|
+
for (const cell of this.gridCells) {
|
|
258
|
+
cell.lastVisit = 0;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Update configuration
|
|
263
|
+
*/
|
|
264
|
+
configure(config) {
|
|
265
|
+
this.config = { ...this.config, ...config };
|
|
266
|
+
this.inhibitionRadius = Math.min(this.width, this.height) * 0.1;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
export { SaccadicController };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saliency Map Computation
|
|
3
|
+
*
|
|
4
|
+
* Computes visual saliency - regions that "pop out" and attract attention.
|
|
5
|
+
* Used to guide saccadic attention to visually important areas.
|
|
6
|
+
*
|
|
7
|
+
* Implements a simplified Itti-Koch saliency model:
|
|
8
|
+
* - Intensity contrast
|
|
9
|
+
* - Edge density
|
|
10
|
+
* - Local complexity
|
|
11
|
+
*
|
|
12
|
+
* For AR tracking, high-saliency regions often contain:
|
|
13
|
+
* - Corners and edges (good for feature detection)
|
|
14
|
+
* - High-contrast areas (robust to lighting changes)
|
|
15
|
+
* - Texture-rich regions (distinctive for matching)
|
|
16
|
+
*/
|
|
17
|
+
export class SaliencyMap {
|
|
18
|
+
/**
|
|
19
|
+
* @param {number} width - Image width
|
|
20
|
+
* @param {number} height - Image height
|
|
21
|
+
*/
|
|
22
|
+
constructor(width: number, height: number);
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
scale: number;
|
|
26
|
+
scaledW: number;
|
|
27
|
+
scaledH: number;
|
|
28
|
+
intensityMap: Float32Array<ArrayBuffer>;
|
|
29
|
+
contrastMap: Float32Array<ArrayBuffer>;
|
|
30
|
+
edgeMap: Float32Array<ArrayBuffer>;
|
|
31
|
+
saliencyBuffer: Float32Array<ArrayBuffer>;
|
|
32
|
+
maxPeaks: number;
|
|
33
|
+
suppressionRadius: number;
|
|
34
|
+
/**
|
|
35
|
+
* Compute saliency map for input image
|
|
36
|
+
*
|
|
37
|
+
* @param {Uint8Array} inputData - Grayscale input image
|
|
38
|
+
* @returns {Object} Saliency result with peaks
|
|
39
|
+
*/
|
|
40
|
+
compute(inputData: Uint8Array): Object;
|
|
41
|
+
/**
|
|
42
|
+
* Downsample input to working resolution
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
private _downsample;
|
|
46
|
+
/**
|
|
47
|
+
* Compute local contrast map
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
private _computeContrast;
|
|
51
|
+
/**
|
|
52
|
+
* Compute edge density map using Sobel-like operator
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
private _computeEdges;
|
|
56
|
+
/**
|
|
57
|
+
* Combine features into final saliency map
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
private _combineSaliency;
|
|
61
|
+
/**
|
|
62
|
+
* Find peaks in saliency map using non-maximum suppression
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
private _findPeaks;
|
|
66
|
+
/**
|
|
67
|
+
* Get saliency value at a specific location
|
|
68
|
+
*
|
|
69
|
+
* @param {number} x - X coordinate in original image
|
|
70
|
+
* @param {number} y - Y coordinate in original image
|
|
71
|
+
* @returns {number} Saliency value (0-1)
|
|
72
|
+
*/
|
|
73
|
+
getSaliencyAt(x: number, y: number): number;
|
|
74
|
+
}
|