@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
|
@@ -5,20 +5,12 @@ import { FREAKPOINTS } from "./freak.js";
|
|
|
5
5
|
import "./kernels/webgl/index.js";
|
|
6
6
|
const PYRAMID_MIN_SIZE = 8;
|
|
7
7
|
const PYRAMID_MAX_OCTAVE = 5;
|
|
8
|
-
const LAPLACIAN_THRESHOLD = 3.0;
|
|
9
|
-
const LAPLACIAN_SQR_THRESHOLD = LAPLACIAN_THRESHOLD * LAPLACIAN_THRESHOLD;
|
|
10
|
-
const EDGE_THRESHOLD = 4.0;
|
|
11
|
-
const EDGE_HESSIAN_THRESHOLD = ((EDGE_THRESHOLD + 1) * (EDGE_THRESHOLD + 1)) / EDGE_THRESHOLD;
|
|
12
8
|
const NUM_BUCKETS_PER_DIMENSION = 10;
|
|
13
9
|
const MAX_FEATURES_PER_BUCKET = 5;
|
|
14
|
-
|
|
15
|
-
// total max feature points = NUM_BUCKETS * MAX_FEATURES_PER_BUCKET
|
|
16
|
-
const ORIENTATION_NUM_BINS = 36;
|
|
17
|
-
const ORIENTATION_SMOOTHING_ITERATIONS = 5;
|
|
10
|
+
// total max feature points
|
|
18
11
|
const ORIENTATION_GAUSSIAN_EXPANSION_FACTOR = 3.0;
|
|
19
12
|
const ORIENTATION_REGION_EXPANSION_FACTOR = 1.5;
|
|
20
|
-
const
|
|
21
|
-
const FREAK_CONPARISON_COUNT = ((FREAKPOINTS.length - 1) * FREAKPOINTS.length) / 2; // 666
|
|
13
|
+
//const FREAK_CONPARISON_COUNT = ((FREAKPOINTS.length - 1) * FREAKPOINTS.length) / 2; // 666
|
|
22
14
|
class Detector {
|
|
23
15
|
constructor(width, height, debugMode = false) {
|
|
24
16
|
this.debugMode = debugMode;
|
|
@@ -175,37 +167,36 @@ class Detector {
|
|
|
175
167
|
const { positionT } = this.tensorCaches.computeFreakDescriptors;
|
|
176
168
|
// encode 8 bits into one number
|
|
177
169
|
// trying to encode 16 bits give wrong result in iOS. may integer precision issue
|
|
178
|
-
const descriptorCount = Math.ceil(FREAK_CONPARISON_COUNT / 8);
|
|
179
170
|
/*
|
|
180
171
|
if (!this.kernelCaches.computeFreakDescriptors) {
|
|
181
172
|
const kernel = {
|
|
182
173
|
variableNames: ['freak', 'p'],
|
|
183
174
|
outputShape: [extremaFreaks.shape[0], descriptorCount],
|
|
184
175
|
userCode: `
|
|
185
|
-
|
|
176
|
+
void main() {
|
|
186
177
|
ivec2 coords = getOutputCoords();
|
|
187
178
|
int featureIndex = coords[0];
|
|
188
179
|
int descIndex = coords[1] * 8;
|
|
189
180
|
|
|
190
181
|
int sum = 0;
|
|
191
|
-
|
|
192
|
-
|
|
182
|
+
for (int i = 0; i < 8; i++) {
|
|
183
|
+
if (descIndex + i >= ${ FREAK_CONPARISON_COUNT }) {
|
|
193
184
|
continue;
|
|
194
|
-
|
|
185
|
+
}
|
|
195
186
|
|
|
196
187
|
int p1 = int(getP(descIndex + i, 0));
|
|
197
188
|
int p2 = int(getP(descIndex + i, 1));
|
|
198
189
|
|
|
199
190
|
float v1 = getFreak(featureIndex, p1);
|
|
200
191
|
float v2 = getFreak(featureIndex, p2);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
192
|
+
|
|
193
|
+
if (v1 < v2 + 0.01) {
|
|
194
|
+
sum += int(pow(2.0, float(7 - i)));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
setOutput(float(sum));
|
|
198
|
+
}
|
|
199
|
+
`
|
|
209
200
|
}
|
|
210
201
|
this.kernelCaches.computeFreakDescriptors = [kernel];
|
|
211
202
|
}
|
|
@@ -237,22 +228,23 @@ class Detector {
|
|
|
237
228
|
imageVariableNames.push('image' + i);
|
|
238
229
|
}
|
|
239
230
|
|
|
240
|
-
let pixelsSubCodes = `float getPixel(int octave, int y, int x) {
|
|
231
|
+
let pixelsSubCodes = `float getPixel(int octave, int y, int x) {
|
|
232
|
+
`;
|
|
241
233
|
for (let i = 1; i < pyramidImagesT.length; i++) {
|
|
242
234
|
pixelsSubCodes += `
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
235
|
+
if (octave == ${ i }) {
|
|
236
|
+
return getImage${ i } (y, x);
|
|
237
|
+
}
|
|
238
|
+
`
|
|
247
239
|
}
|
|
248
|
-
pixelsSubCodes += `}`;
|
|
240
|
+
pixelsSubCodes += `} `;
|
|
249
241
|
|
|
250
242
|
const kernel = {
|
|
251
243
|
variableNames: [...imageVariableNames, 'extrema', 'angles', 'freakPoints'],
|
|
252
244
|
outputShape: [prunedExtremas.shape[0], FREAKPOINTS.length],
|
|
253
245
|
userCode: `
|
|
254
|
-
${pixelsSubCodes}
|
|
255
|
-
|
|
246
|
+
${ pixelsSubCodes }
|
|
247
|
+
void main() {
|
|
256
248
|
ivec2 coords = getOutputCoords();
|
|
257
249
|
int featureIndex = coords[0];
|
|
258
250
|
int freakIndex = coords[1];
|
|
@@ -265,8 +257,8 @@ class Detector {
|
|
|
265
257
|
float inputY = getExtrema(featureIndex, 2);
|
|
266
258
|
float inputX = getExtrema(featureIndex, 3);
|
|
267
259
|
float inputAngle = getAngles(featureIndex);
|
|
268
|
-
float cos = ${FREAK_EXPANSION_FACTOR}. * cos(inputAngle);
|
|
269
|
-
float sin = ${FREAK_EXPANSION_FACTOR}. * sin(inputAngle);
|
|
260
|
+
float cos = ${ FREAK_EXPANSION_FACTOR }. * cos(inputAngle);
|
|
261
|
+
float sin = ${ FREAK_EXPANSION_FACTOR }. * sin(inputAngle);
|
|
270
262
|
|
|
271
263
|
float yp = inputY + freakX * sin + freakY * cos;
|
|
272
264
|
float xp = inputX + freakX * cos + freakY * -sin;
|
|
@@ -285,16 +277,16 @@ class Detector {
|
|
|
285
277
|
float y1f = float(y1);
|
|
286
278
|
float x0f = float(x0);
|
|
287
279
|
float y0f = float(y0);
|
|
288
|
-
|
|
280
|
+
|
|
289
281
|
// ratio for interpolation between four neighbouring points
|
|
290
282
|
float value = (x1f - xp) * (y1f - yp) * f1
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
283
|
+
+ (xp - x0f) * (y1f - yp) * f2
|
|
284
|
+
+ (x1f - xp) * (yp - y0f) * f3
|
|
285
|
+
+ (xp - x0f) * (yp - y0f) * f4;
|
|
286
|
+
|
|
287
|
+
setOutput(value);
|
|
288
|
+
}
|
|
289
|
+
`
|
|
298
290
|
}
|
|
299
291
|
|
|
300
292
|
this.kernelCaches._computeExtremaFreak = [kernel];
|
|
@@ -323,56 +315,56 @@ class Detector {
|
|
|
323
315
|
variableNames: ['histogram'],
|
|
324
316
|
outputShape: [histograms.shape[0]],
|
|
325
317
|
userCode: `
|
|
326
|
-
|
|
318
|
+
void main() {
|
|
327
319
|
int featureIndex = getOutputCoords();
|
|
328
320
|
|
|
329
321
|
int maxIndex = 0;
|
|
330
|
-
|
|
331
|
-
|
|
322
|
+
for (int i = 1; i < ${ ORIENTATION_NUM_BINS }; i++) {
|
|
323
|
+
if (getHistogram(featureIndex, i) > getHistogram(featureIndex, maxIndex)) {
|
|
332
324
|
maxIndex = i;
|
|
333
|
-
|
|
334
|
-
|
|
325
|
+
}
|
|
326
|
+
}
|
|
335
327
|
|
|
336
|
-
int prev = imod(maxIndex - 1 + ${ORIENTATION_NUM_BINS}, ${ORIENTATION_NUM_BINS});
|
|
337
|
-
int next = imod(maxIndex + 1, ${ORIENTATION_NUM_BINS});
|
|
328
|
+
int prev = imod(maxIndex - 1 + ${ ORIENTATION_NUM_BINS }, ${ ORIENTATION_NUM_BINS });
|
|
329
|
+
int next = imod(maxIndex + 1, ${ ORIENTATION_NUM_BINS });
|
|
338
330
|
|
|
339
331
|
**
|
|
340
|
-
* Fit a quatratic to 3 points.
|
|
332
|
+
* Fit a quatratic to 3 points.The system of equations is:
|
|
341
333
|
*
|
|
342
|
-
* y0 = A*x0^2 + B*x0 + C
|
|
343
|
-
|
|
344
|
-
|
|
334
|
+
* y0 = A * x0 ^ 2 + B * x0 + C
|
|
335
|
+
* y1 = A * x1 ^ 2 + B * x1 + C
|
|
336
|
+
* y2 = A * x2 ^ 2 + B * x2 + C
|
|
337
|
+
*
|
|
338
|
+
* This system of equations is solved for A, B, C.
|
|
345
339
|
*
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
float p10 = float(maxIndex - 1);
|
|
349
|
-
float p11 = getHistogram(featureIndex, prev);
|
|
340
|
+
float p10 = float(maxIndex - 1);
|
|
341
|
+
float p11 = getHistogram(featureIndex, prev);
|
|
350
342
|
float p20 = float(maxIndex);
|
|
351
343
|
float p21 = getHistogram(featureIndex, maxIndex);
|
|
352
344
|
float p30 = float(maxIndex + 1);
|
|
353
345
|
float p31 = getHistogram(featureIndex, next);
|
|
354
346
|
|
|
355
|
-
float d1 = (p30-p20)*(p30-p10);
|
|
356
|
-
float d2 = (p10-p20)*(p30-p10);
|
|
357
|
-
float d3 = p10-p20;
|
|
358
|
-
|
|
347
|
+
float d1 = (p30 - p20) * (p30 - p10);
|
|
348
|
+
float d2 = (p10 - p20) * (p30 - p10);
|
|
349
|
+
float d3 = p10 - p20;
|
|
350
|
+
|
|
359
351
|
// If any of the denominators are zero then, just use maxIndex.
|
|
360
352
|
float fbin = float(maxIndex);
|
|
361
|
-
|
|
362
|
-
float a = p10*p10;
|
|
363
|
-
float b = p20*p20;
|
|
364
|
-
|
|
353
|
+
if (abs(d1) > 0.00001 && abs(d2) > 0.00001 && abs(d3) > 0.00001) {
|
|
354
|
+
float a = p10 * p10;
|
|
355
|
+
float b = p20 * p20;
|
|
356
|
+
|
|
365
357
|
// Solve for the coefficients A,B,C
|
|
366
|
-
float A = ((p31-p21)/d1)-((p11-p21)/d2);
|
|
367
|
-
float B = ((p11-p21)+(A*(b-a)))/d3;
|
|
368
|
-
float C = p11-(A*a)-(B*p10);
|
|
369
|
-
|
|
370
|
-
|
|
358
|
+
float A = ((p31 - p21) / d1) - ((p11 - p21) / d2);
|
|
359
|
+
float B = ((p11 - p21) + (A * (b - a))) / d3;
|
|
360
|
+
float C = p11 - (A * a) - (B * p10);
|
|
361
|
+
fbin = -B / (2. * A);
|
|
362
|
+
}
|
|
371
363
|
|
|
372
|
-
float an = 2.0
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
364
|
+
float an = 2.0 * ${ Math.PI } * (fbin + 0.5) / ${ ORIENTATION_NUM_BINS }.- ${ Math.PI };
|
|
365
|
+
setOutput(an);
|
|
366
|
+
}
|
|
367
|
+
`
|
|
376
368
|
}
|
|
377
369
|
this.kernelCaches.computeExtremaAngles = kernel;
|
|
378
370
|
} */
|
|
@@ -390,7 +382,6 @@ class Detector {
|
|
|
390
382
|
* @returns
|
|
391
383
|
*/
|
|
392
384
|
_computeOrientationHistograms(prunedExtremasT, pyramidImagesT) {
|
|
393
|
-
const oneOver2PI = 0.159154943091895;
|
|
394
385
|
const gaussianImagesT = [];
|
|
395
386
|
for (let i = 1; i < pyramidImagesT.length; i++) {
|
|
396
387
|
gaussianImagesT.push(pyramidImagesT[i][1]);
|
|
@@ -427,23 +418,24 @@ class Detector {
|
|
|
427
418
|
imageVariableNames.push('image' + i);
|
|
428
419
|
}
|
|
429
420
|
|
|
430
|
-
let kernel1SubCodes = `float getPixel(int octave, int y, int x) {
|
|
421
|
+
let kernel1SubCodes = `float getPixel(int octave, int y, int x) {
|
|
422
|
+
`;
|
|
431
423
|
for (let i = 1; i < pyramidImagesT.length; i++) {
|
|
432
424
|
kernel1SubCodes += `
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
425
|
+
if (octave == ${ i }) {
|
|
426
|
+
return getImage${ i } (y, x);
|
|
427
|
+
}
|
|
428
|
+
`
|
|
437
429
|
}
|
|
438
|
-
kernel1SubCodes += `}`;
|
|
430
|
+
kernel1SubCodes += `} `;
|
|
439
431
|
|
|
440
432
|
const kernel1 = {
|
|
441
433
|
variableNames: [...imageVariableNames, 'extrema', 'radial'],
|
|
442
434
|
outputShape: [prunedExtremasT.shape[0], radialPropertiesT.shape[0], 2], // last dimension: [fbin, magnitude]
|
|
443
435
|
userCode: `
|
|
444
|
-
${kernel1SubCodes}
|
|
445
|
-
|
|
446
|
-
|
|
436
|
+
${ kernel1SubCodes }
|
|
437
|
+
|
|
438
|
+
void main() {
|
|
447
439
|
ivec3 coords = getOutputCoords();
|
|
448
440
|
int featureIndex = coords[0];
|
|
449
441
|
int radialIndex = coords[1];
|
|
@@ -460,61 +452,61 @@ class Detector {
|
|
|
460
452
|
int xp = x + radialX;
|
|
461
453
|
int yp = y + radialY;
|
|
462
454
|
|
|
463
|
-
float dy = getPixel(octave, yp+1, xp) - getPixel(octave, yp-1, xp);
|
|
464
|
-
float dx = getPixel(octave, yp, xp+1) - getPixel(octave, yp, xp-1);
|
|
465
|
-
|
|
466
|
-
|
|
455
|
+
float dy = getPixel(octave, yp + 1, xp) - getPixel(octave, yp - 1, xp);
|
|
456
|
+
float dx = getPixel(octave, yp, xp + 1) - getPixel(octave, yp, xp - 1);
|
|
457
|
+
|
|
458
|
+
if (propertyIndex == 0) {
|
|
467
459
|
// be careful that atan(0, 0) gives 1.57 instead of 0 (different from js), but doesn't matter here, coz magnitude is 0
|
|
468
460
|
|
|
469
|
-
float angle = atan(dy, dx) + ${Math.PI};
|
|
470
|
-
float fbin = angle * ${ORIENTATION_NUM_BINS}. * ${oneOver2PI};
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
461
|
+
float angle = atan(dy, dx) + ${ Math.PI };
|
|
462
|
+
float fbin = angle * ${ ORIENTATION_NUM_BINS }. * ${ oneOver2PI };
|
|
463
|
+
setOutput(fbin);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (propertyIndex == 1) {
|
|
476
468
|
float mag = sqrt(dx * dx + dy * dy);
|
|
477
469
|
float magnitude = radialW * mag;
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
470
|
+
setOutput(magnitude);
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
`
|
|
484
476
|
}
|
|
485
477
|
|
|
486
478
|
const kernel2 = {
|
|
487
479
|
variableNames: ['fbinMag'],
|
|
488
480
|
outputShape: [prunedExtremasT.shape[0], ORIENTATION_NUM_BINS],
|
|
489
481
|
userCode: `
|
|
490
|
-
|
|
482
|
+
void main() {
|
|
491
483
|
ivec2 coords = getOutputCoords();
|
|
492
484
|
int featureIndex = coords[0];
|
|
493
485
|
int binIndex = coords[1];
|
|
494
486
|
|
|
495
487
|
float sum = 0.;
|
|
496
|
-
|
|
488
|
+
for (int i = 0; i < ${ radialPropertiesT.shape[0] }; i++) {
|
|
497
489
|
float fbin = getFbinMag(featureIndex, i, 0);
|
|
498
490
|
int bin = int(floor(fbin - 0.5));
|
|
499
|
-
int b1 = imod(bin + ${ORIENTATION_NUM_BINS}, ${ORIENTATION_NUM_BINS});
|
|
500
|
-
int b2 = imod(bin + 1 + ${ORIENTATION_NUM_BINS}, ${ORIENTATION_NUM_BINS});
|
|
501
|
-
|
|
502
|
-
|
|
491
|
+
int b1 = imod(bin + ${ ORIENTATION_NUM_BINS }, ${ ORIENTATION_NUM_BINS });
|
|
492
|
+
int b2 = imod(bin + 1 + ${ ORIENTATION_NUM_BINS }, ${ ORIENTATION_NUM_BINS });
|
|
493
|
+
|
|
494
|
+
if (b1 == binIndex || b2 == binIndex) {
|
|
503
495
|
float magnitude = getFbinMag(featureIndex, i, 1);
|
|
504
496
|
float w2 = fbin - float(bin) - 0.5;
|
|
505
497
|
float w1 = w2 * -1. + 1.;
|
|
506
|
-
|
|
498
|
+
|
|
507
499
|
if (b1 == binIndex) {
|
|
508
|
-
|
|
500
|
+
sum += w1 * magnitude;
|
|
509
501
|
}
|
|
510
502
|
if (b2 == binIndex) {
|
|
511
|
-
|
|
512
|
-
}
|
|
513
|
-
}
|
|
503
|
+
sum += w2 * magnitude;
|
|
514
504
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
setOutput(sum);
|
|
508
|
+
}
|
|
509
|
+
`
|
|
518
510
|
}
|
|
519
511
|
|
|
520
512
|
this.kernelCaches.computeOrientationHistograms = [kernel1, kernel2];
|
|
@@ -539,20 +531,20 @@ class Detector {
|
|
|
539
531
|
variableNames: ['histogram'],
|
|
540
532
|
outputShape: [histograms.shape[0], ORIENTATION_NUM_BINS],
|
|
541
533
|
userCode: `
|
|
542
|
-
|
|
534
|
+
void main() {
|
|
543
535
|
ivec2 coords = getOutputCoords();
|
|
544
536
|
|
|
545
537
|
int featureIndex = coords[0];
|
|
546
538
|
int binIndex = coords[1];
|
|
547
539
|
|
|
548
|
-
int prevBin = imod(binIndex - 1 + ${ORIENTATION_NUM_BINS}, ${ORIENTATION_NUM_BINS});
|
|
549
|
-
int nextBin = imod(binIndex + 1, ${ORIENTATION_NUM_BINS});
|
|
540
|
+
int prevBin = imod(binIndex - 1 + ${ ORIENTATION_NUM_BINS }, ${ ORIENTATION_NUM_BINS });
|
|
541
|
+
int nextBin = imod(binIndex + 1, ${ ORIENTATION_NUM_BINS });
|
|
550
542
|
|
|
551
543
|
float result = 0.274068619061197 * getHistogram(featureIndex, prevBin) + 0.451862761877606 * getHistogram(featureIndex, binIndex) + 0.274068619061197 * getHistogram(featureIndex, nextBin);
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
544
|
+
|
|
545
|
+
setOutput(result);
|
|
546
|
+
}
|
|
547
|
+
`
|
|
556
548
|
}
|
|
557
549
|
this.kernelCaches.smoothHistograms = kernel;
|
|
558
550
|
} */
|
|
@@ -575,39 +567,40 @@ class Detector {
|
|
|
575
567
|
/* if (!this.kernelCaches.computeLocalization) {
|
|
576
568
|
const dogVariableNames = [];
|
|
577
569
|
|
|
578
|
-
let dogSubCodes = `float getPixel(int octave, int y, int x) {
|
|
570
|
+
let dogSubCodes = `float getPixel(int octave, int y, int x) {
|
|
571
|
+
`;
|
|
579
572
|
for (let i = 1; i < dogPyramidImagesT.length; i++) { // extrema starts from second octave
|
|
580
573
|
dogVariableNames.push('image' + i);
|
|
581
574
|
dogSubCodes += `
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
575
|
+
if (octave == ${ i }) {
|
|
576
|
+
return getImage${ i } (y, x);
|
|
577
|
+
}
|
|
578
|
+
`;
|
|
586
579
|
}
|
|
587
|
-
dogSubCodes += `}`;
|
|
580
|
+
dogSubCodes += `} `;
|
|
588
581
|
|
|
589
582
|
const kernel = {
|
|
590
583
|
variableNames: [...dogVariableNames, 'extrema'],
|
|
591
584
|
outputShape: [prunedExtremasList.length, 3, 3], // 3x3 pixels around the extrema
|
|
592
585
|
userCode: `
|
|
593
|
-
${dogSubCodes}
|
|
594
|
-
|
|
595
|
-
|
|
586
|
+
${ dogSubCodes }
|
|
587
|
+
|
|
588
|
+
void main() {
|
|
596
589
|
ivec3 coords = getOutputCoords();
|
|
597
590
|
int featureIndex = coords[0];
|
|
598
591
|
float score = getExtrema(featureIndex, 0);
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
592
|
+
if (score == 0.0) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
602
595
|
|
|
603
|
-
int dy = coords[1]-1;
|
|
604
|
-
int dx = coords[2]-1;
|
|
596
|
+
int dy = coords[1] - 1;
|
|
597
|
+
int dx = coords[2] - 1;
|
|
605
598
|
int octave = int(getExtrema(featureIndex, 1));
|
|
606
599
|
int y = int(getExtrema(featureIndex, 2));
|
|
607
600
|
int x = int(getExtrema(featureIndex, 3));
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
601
|
+
setOutput(getPixel(octave, y + dy, x + dx));
|
|
602
|
+
}
|
|
603
|
+
`
|
|
611
604
|
}
|
|
612
605
|
|
|
613
606
|
this.kernelCaches.computeLocalization = [kernel];
|
|
@@ -684,34 +677,34 @@ class Detector {
|
|
|
684
677
|
variableNames: ['extrema'],
|
|
685
678
|
outputShape: [Math.floor(extremaHeight/2), Math.floor(extremaWidth/2)],
|
|
686
679
|
userCode: `
|
|
687
|
-
|
|
680
|
+
void main() {
|
|
688
681
|
ivec2 coords = getOutputCoords();
|
|
689
682
|
int y = coords[0] * 2;
|
|
690
683
|
int x = coords[1] * 2;
|
|
691
684
|
|
|
692
685
|
float location = 0.0;
|
|
693
686
|
float values = getExtrema(y, x);
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
687
|
+
|
|
688
|
+
if (getExtrema(y + 1, x) != 0.0) {
|
|
689
|
+
location = 1.0;
|
|
690
|
+
values = getExtrema(y + 1, x);
|
|
691
|
+
}
|
|
692
|
+
else if (getExtrema(y, x + 1) != 0.0) {
|
|
693
|
+
location = 2.0;
|
|
694
|
+
values = getExtrema(y, x + 1);
|
|
695
|
+
}
|
|
696
|
+
else if (getExtrema(y + 1, x + 1) != 0.0) {
|
|
697
|
+
location = 3.0;
|
|
698
|
+
values = getExtrema(y + 1, x + 1);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (values < 0.0) {
|
|
702
|
+
setOutput(location * -1000.0 + values);
|
|
703
|
+
} else {
|
|
704
|
+
setOutput(location * 1000.0 + values);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
`
|
|
715
708
|
}
|
|
716
709
|
reductionKernels.push(kernel);
|
|
717
710
|
}
|
|
@@ -803,71 +796,71 @@ class Detector {
|
|
|
803
796
|
variableNames: ['image0', 'image1', 'image2'],
|
|
804
797
|
outputShape: [imageHeight, imageWidth],
|
|
805
798
|
userCode: `
|
|
806
|
-
|
|
799
|
+
void main() {
|
|
807
800
|
ivec2 coords = getOutputCoords();
|
|
808
801
|
|
|
809
802
|
int y = coords[0];
|
|
810
803
|
int x = coords[1];
|
|
811
804
|
|
|
812
805
|
float value = getImage1(y, x);
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
806
|
+
|
|
807
|
+
// Step 1: find local maxima/minima
|
|
808
|
+
if (value * value < ${ LAPLACIAN_SQR_THRESHOLD }.) {
|
|
809
|
+
setOutput(0.);
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
if (y < ${ FREAK_EXPANSION_FACTOR } || y > ${ imageHeight - 1 - FREAK_EXPANSION_FACTOR }) {
|
|
813
|
+
setOutput(0.);
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
if (x < ${ FREAK_EXPANSION_FACTOR } || x > ${ imageWidth - 1 - FREAK_EXPANSION_FACTOR }) {
|
|
817
|
+
setOutput(0.);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
827
820
|
|
|
828
821
|
bool isMax = true;
|
|
829
822
|
bool isMin = true;
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
float value0 = getImage0(y+dy, x+dx);
|
|
833
|
-
float value1 = getImage1(y+dy, x+dx);
|
|
834
|
-
float value2 = getImage2(y+dy, x+dx);
|
|
835
|
-
|
|
823
|
+
for (int dy = -1; dy <= 1; dy++) {
|
|
824
|
+
for (int dx = -1; dx <= 1; dx++) {
|
|
825
|
+
float value0 = getImage0(y + dy, x + dx);
|
|
826
|
+
float value1 = getImage1(y + dy, x + dx);
|
|
827
|
+
float value2 = getImage2(y + dy, x + dx);
|
|
828
|
+
|
|
836
829
|
if (value < value0 || value < value1 || value < value2) {
|
|
837
|
-
|
|
830
|
+
isMax = false;
|
|
838
831
|
}
|
|
839
832
|
if (value > value0 || value > value1 || value > value2) {
|
|
840
|
-
|
|
833
|
+
isMin = false;
|
|
841
834
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if (!isMax && !isMin) {
|
|
839
|
+
setOutput(0.);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
|
|
850
843
|
// compute edge score and reject based on threshold
|
|
851
|
-
float dxx = getImage1(y, x+1) + getImage1(y, x-1) - 2. * getImage1(y, x);
|
|
852
|
-
float dyy = getImage1(y+1, x) + getImage1(y-1, x) - 2. * getImage1(y, x);
|
|
853
|
-
float dxy = 0.25 * (getImage1(y-1,x-1) + getImage1(y+1,x+1) - getImage1(y-1,x+1) - getImage1(y+1,x-1));
|
|
844
|
+
float dxx = getImage1(y, x + 1) + getImage1(y, x - 1) - 2. * getImage1(y, x);
|
|
845
|
+
float dyy = getImage1(y + 1, x) + getImage1(y - 1, x) - 2. * getImage1(y, x);
|
|
846
|
+
float dxy = 0.25 * (getImage1(y - 1, x - 1) + getImage1(y + 1, x + 1) - getImage1(y - 1, x + 1) - getImage1(y + 1, x - 1));
|
|
854
847
|
|
|
855
848
|
float det = (dxx * dyy) - (dxy * dxy);
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
849
|
+
|
|
850
|
+
if (abs(det) < 0.0001) { // determinant undefined. no solution
|
|
851
|
+
setOutput(0.);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
861
854
|
|
|
862
855
|
float edgeScore = (dxx + dyy) * (dxx + dyy) / det;
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
856
|
+
|
|
857
|
+
if (abs(edgeScore) >= ${ EDGE_HESSIAN_THRESHOLD } ) {
|
|
858
|
+
setOutput(0.);
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
setOutput(getImage1(y, x));
|
|
862
|
+
}
|
|
863
|
+
`
|
|
871
864
|
};
|
|
872
865
|
this.kernelCaches.buildExtremas[kernelKey] = kernel;
|
|
873
866
|
} */
|
|
@@ -906,35 +899,35 @@ class Detector {
|
|
|
906
899
|
variableNames: ['p'],
|
|
907
900
|
outputShape: [imageHeight, imageWidth],
|
|
908
901
|
userCode: `
|
|
909
|
-
|
|
902
|
+
void main() {
|
|
910
903
|
ivec2 coords = getOutputCoords();
|
|
911
904
|
|
|
912
|
-
float sum = getP(coords[0], coords[1]-2);
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
905
|
+
float sum = getP(coords[0], coords[1] - 2);
|
|
906
|
+
sum += getP(coords[0], coords[1] - 1) * 4.;
|
|
907
|
+
sum += getP(coords[0], coords[1]) * 6.;
|
|
908
|
+
sum += getP(coords[0], coords[1] + 1) * 4.;
|
|
909
|
+
sum += getP(coords[0], coords[1] + 2);
|
|
910
|
+
setOutput(sum);
|
|
911
|
+
}
|
|
912
|
+
`
|
|
920
913
|
};
|
|
921
914
|
|
|
922
915
|
const kernel2 = {
|
|
923
916
|
variableNames: ['p'],
|
|
924
917
|
outputShape: [imageHeight, imageWidth],
|
|
925
918
|
userCode: `
|
|
926
|
-
|
|
919
|
+
void main() {
|
|
927
920
|
ivec2 coords = getOutputCoords();
|
|
928
921
|
|
|
929
|
-
float sum = getP(coords[0]-2, coords[1]);
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
922
|
+
float sum = getP(coords[0] - 2, coords[1]);
|
|
923
|
+
sum += getP(coords[0] - 1, coords[1]) * 4.;
|
|
924
|
+
sum += getP(coords[0], coords[1]) * 6.;
|
|
925
|
+
sum += getP(coords[0] + 1, coords[1]) * 4.;
|
|
926
|
+
sum += getP(coords[0] + 2, coords[1]);
|
|
927
|
+
sum /= 256.;
|
|
928
|
+
setOutput(sum);
|
|
929
|
+
}
|
|
930
|
+
`
|
|
938
931
|
};
|
|
939
932
|
this.kernelCaches.applyFilter[kernelKey] = [kernel1, kernel2];
|
|
940
933
|
}
|
|
@@ -962,7 +955,7 @@ class Detector {
|
|
|
962
955
|
variableNames: ['p'],
|
|
963
956
|
outputShape: [targetImage.shape[0], targetImage.shape[1]],
|
|
964
957
|
userCode: `
|
|
965
|
-
|
|
958
|
+
void main() {
|
|
966
959
|
ivec2 coords = getOutputCoords();
|
|
967
960
|
int j = coords[0];
|
|
968
961
|
int i = coords[1];
|
|
@@ -981,13 +974,13 @@ class Detector {
|
|
|
981
974
|
int si1I = int(si1);
|
|
982
975
|
|
|
983
976
|
float sum = 0.0;
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
977
|
+
sum += getP(sj0I, si0I) * (si1 - si) * (sj1 - sj);
|
|
978
|
+
sum += getP(sj1I, si0I) * (si1 - si) * (sj - sj0);
|
|
979
|
+
sum += getP(sj0I, si1I) * (si - si0) * (sj1 - sj);
|
|
980
|
+
sum += getP(sj1I, si1I) * (si - si0) * (sj - sj0);
|
|
981
|
+
setOutput(sum);
|
|
982
|
+
}
|
|
983
|
+
`
|
|
991
984
|
};
|
|
992
985
|
this.kernelCaches.upsampleBilinear[kernelKey] = kernel;
|
|
993
986
|
}
|
|
@@ -1011,18 +1004,18 @@ class Detector {
|
|
|
1011
1004
|
variableNames: ['p'],
|
|
1012
1005
|
outputShape: [Math.floor(imageHeight / 2), Math.floor(imageWidth / 2)],
|
|
1013
1006
|
userCode: `
|
|
1014
|
-
|
|
1007
|
+
void main() {
|
|
1015
1008
|
ivec2 coords = getOutputCoords();
|
|
1016
1009
|
int y = coords[0] * 2;
|
|
1017
1010
|
int x = coords[1] * 2;
|
|
1018
1011
|
|
|
1019
1012
|
float sum = getP(y, x) * 0.25;
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1013
|
+
sum += getP(y + 1, x) * 0.25;
|
|
1014
|
+
sum += getP(y, x + 1) * 0.25;
|
|
1015
|
+
sum += getP(y + 1, x + 1) * 0.25;
|
|
1016
|
+
setOutput(sum);
|
|
1017
|
+
}
|
|
1018
|
+
`
|
|
1026
1019
|
};
|
|
1027
1020
|
this.kernelCaches.downsampleBilinear[kernelKey] = kernel;
|
|
1028
1021
|
} */
|
|
@@ -1039,11 +1032,11 @@ class Detector {
|
|
|
1039
1032
|
*/
|
|
1040
1033
|
_compileAndRun(program, inputs) {
|
|
1041
1034
|
const outInfo = tf.backend().compileAndRun(program, inputs);
|
|
1042
|
-
return tf.engine().
|
|
1035
|
+
return tf.engine().makeTensor(outInfo.dataId, outInfo.shape, outInfo.dtype);
|
|
1043
1036
|
}
|
|
1044
1037
|
_runWebGLProgram(program, inputs, outputType) {
|
|
1045
1038
|
const outInfo = tf.backend().runWebGLProgram(program, inputs, outputType);
|
|
1046
|
-
return tf.engine().
|
|
1039
|
+
return tf.engine().makeTensor(outInfo.dataId, outInfo.shape, outInfo.dtype);
|
|
1047
1040
|
}
|
|
1048
1041
|
}
|
|
1049
1042
|
export { Detector };
|