@srsergio/taptapp-ar 1.0.8 → 1.0.10
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/controller.d.ts +15 -22
- package/dist/compiler/controller.js +73 -92
- package/dist/compiler/detector/crop-detector.d.ts +20 -51
- package/dist/compiler/detector/crop-detector.js +21 -15
- package/dist/compiler/input-loader.d.ts +15 -17
- package/dist/compiler/input-loader.js +58 -76
- package/dist/compiler/matching/hamming-distance.js +4 -4
- package/dist/compiler/matching/matcher.js +2 -2
- package/dist/compiler/matching/matching.d.ts +2 -16
- package/dist/compiler/matching/matching.js +72 -60
- package/dist/compiler/offline-compiler.d.ts +14 -65
- package/dist/compiler/offline-compiler.js +86 -55
- package/dist/compiler/three.js +0 -4
- package/dist/compiler/tracker/tracker.d.ts +26 -12
- package/dist/compiler/tracker/tracker.js +158 -259
- package/dist/compiler/utils/worker-pool.d.ts +2 -1
- package/dist/compiler/utils/worker-pool.js +4 -8
- package/package.json +1 -1
- package/src/compiler/controller.js +71 -93
- package/src/compiler/detector/crop-detector.js +26 -15
- package/src/compiler/input-loader.js +62 -88
- package/src/compiler/matching/hamming-distance.js +4 -4
- package/src/compiler/matching/hough.js +1 -1
- package/src/compiler/matching/matcher.js +2 -2
- package/src/compiler/matching/matching.js +80 -72
- package/src/compiler/offline-compiler.js +92 -58
- package/src/compiler/three.js +0 -4
- package/src/compiler/tracker/tracker.js +183 -283
- package/src/compiler/utils/worker-pool.js +4 -8
- package/dist/compiler/compiler-base.d.ts +0 -8
- package/dist/compiler/compiler-base.js +0 -179
- package/dist/compiler/compiler.d.ts +0 -9
- package/dist/compiler/compiler.js +0 -24
- package/dist/compiler/compiler.worker.d.ts +0 -1
- package/dist/compiler/compiler.worker.js +0 -28
- package/dist/compiler/detector/detector.d.ts +0 -97
- package/dist/compiler/detector/detector.js +0 -1042
- package/dist/compiler/detector/kernels/cpu/binomialFilter.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/binomialFilter.js +0 -50
- package/dist/compiler/detector/kernels/cpu/buildExtremas.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/buildExtremas.js +0 -89
- package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.d.ts +0 -7
- package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.js +0 -79
- package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.js +0 -68
- package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.js +0 -57
- package/dist/compiler/detector/kernels/cpu/computeLocalization.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/computeLocalization.js +0 -50
- package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -100
- package/dist/compiler/detector/kernels/cpu/downsampleBilinear.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/downsampleBilinear.js +0 -29
- package/dist/compiler/detector/kernels/cpu/extremaReduction.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/extremaReduction.js +0 -50
- package/dist/compiler/detector/kernels/cpu/fakeShader.d.ts +0 -20
- package/dist/compiler/detector/kernels/cpu/fakeShader.js +0 -80
- package/dist/compiler/detector/kernels/cpu/index.d.ts +0 -1
- package/dist/compiler/detector/kernels/cpu/index.js +0 -25
- package/dist/compiler/detector/kernels/cpu/prune.d.ts +0 -7
- package/dist/compiler/detector/kernels/cpu/prune.js +0 -62
- package/dist/compiler/detector/kernels/cpu/smoothHistograms.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/smoothHistograms.js +0 -47
- package/dist/compiler/detector/kernels/cpu/upsampleBilinear.d.ts +0 -6
- package/dist/compiler/detector/kernels/cpu/upsampleBilinear.js +0 -43
- package/dist/compiler/detector/kernels/index.d.ts +0 -1
- package/dist/compiler/detector/kernels/index.js +0 -2
- package/dist/compiler/detector/kernels/webgl/binomialFilter.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/binomialFilter.js +0 -67
- package/dist/compiler/detector/kernels/webgl/buildExtremas.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/buildExtremas.js +0 -101
- package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.js +0 -78
- package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.js +0 -86
- package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.js +0 -52
- package/dist/compiler/detector/kernels/webgl/computeLocalization.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/computeLocalization.js +0 -58
- package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.js +0 -116
- package/dist/compiler/detector/kernels/webgl/downsampleBilinear.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/downsampleBilinear.js +0 -46
- package/dist/compiler/detector/kernels/webgl/extremaReduction.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/extremaReduction.js +0 -48
- package/dist/compiler/detector/kernels/webgl/index.d.ts +0 -1
- package/dist/compiler/detector/kernels/webgl/index.js +0 -25
- package/dist/compiler/detector/kernels/webgl/smoothHistograms.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/smoothHistograms.js +0 -49
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.d.ts +0 -6
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.js +0 -56
- package/dist/compiler/tensorflow-setup.d.ts +0 -6
- package/dist/compiler/tensorflow-setup.js +0 -99
- package/src/compiler/compiler-base.js +0 -210
- package/src/compiler/compiler.js +0 -25
- package/src/compiler/compiler.worker.js +0 -30
- package/src/compiler/detector/detector.js +0 -1119
- package/src/compiler/detector/kernels/cpu/binomialFilter.js +0 -58
- package/src/compiler/detector/kernels/cpu/buildExtremas.js +0 -108
- package/src/compiler/detector/kernels/cpu/computeExtremaAngles.js +0 -91
- package/src/compiler/detector/kernels/cpu/computeExtremaFreak.js +0 -92
- package/src/compiler/detector/kernels/cpu/computeFreakDescriptors.js +0 -68
- package/src/compiler/detector/kernels/cpu/computeLocalization.js +0 -67
- package/src/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -124
- package/src/compiler/detector/kernels/cpu/downsampleBilinear.js +0 -33
- package/src/compiler/detector/kernels/cpu/extremaReduction.js +0 -53
- package/src/compiler/detector/kernels/cpu/fakeShader.js +0 -88
- package/src/compiler/detector/kernels/cpu/index.js +0 -26
- package/src/compiler/detector/kernels/cpu/prune.js +0 -78
- package/src/compiler/detector/kernels/cpu/smoothHistograms.js +0 -57
- package/src/compiler/detector/kernels/cpu/upsampleBilinear.js +0 -51
- package/src/compiler/detector/kernels/index.js +0 -2
- package/src/compiler/detector/kernels/webgl/binomialFilter.js +0 -72
- package/src/compiler/detector/kernels/webgl/buildExtremas.js +0 -109
- package/src/compiler/detector/kernels/webgl/computeExtremaAngles.js +0 -82
- package/src/compiler/detector/kernels/webgl/computeExtremaFreak.js +0 -105
- package/src/compiler/detector/kernels/webgl/computeFreakDescriptors.js +0 -56
- package/src/compiler/detector/kernels/webgl/computeLocalization.js +0 -70
- package/src/compiler/detector/kernels/webgl/computeOrientationHistograms.js +0 -129
- package/src/compiler/detector/kernels/webgl/downsampleBilinear.js +0 -50
- package/src/compiler/detector/kernels/webgl/extremaReduction.js +0 -50
- package/src/compiler/detector/kernels/webgl/index.js +0 -26
- package/src/compiler/detector/kernels/webgl/smoothHistograms.js +0 -53
- package/src/compiler/detector/kernels/webgl/upsampleBilinear.js +0 -62
- package/src/compiler/tensorflow-setup.js +0 -116
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import * as FakeShader from "./fakeShader.js";
|
|
2
|
-
function GetKernels(image) {
|
|
3
|
-
const imageWidth = image.shape[1];
|
|
4
|
-
const imageHeight = image.shape[0];
|
|
5
|
-
const kernel1 = {
|
|
6
|
-
variableNames: ["p"],
|
|
7
|
-
outputShape: [imageHeight, imageWidth],
|
|
8
|
-
userCode: function () {
|
|
9
|
-
const coords = this.getOutputCoords();
|
|
10
|
-
let sum = this.getP(coords[0], coords[1] - 2);
|
|
11
|
-
sum += this.getP(coords[0], coords[1] - 1) * 4;
|
|
12
|
-
sum += this.getP(coords[0], coords[1]) * 6;
|
|
13
|
-
sum += this.getP(coords[0], coords[1] + 1) * 4;
|
|
14
|
-
sum += this.getP(coords[0], coords[1] + 2);
|
|
15
|
-
this.setOutput(sum);
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
const kernel2 = {
|
|
19
|
-
variableNames: ["p"],
|
|
20
|
-
outputShape: [imageHeight, imageWidth],
|
|
21
|
-
userCode: function () {
|
|
22
|
-
const coords = this.getOutputCoords();
|
|
23
|
-
let sum = this.getP(coords[0] - 2, coords[1]);
|
|
24
|
-
sum += this.getP(coords[0] - 1, coords[1]) * 4;
|
|
25
|
-
sum += this.getP(coords[0], coords[1]) * 6;
|
|
26
|
-
sum += this.getP(coords[0] + 1, coords[1]) * 4;
|
|
27
|
-
sum += this.getP(coords[0] + 2, coords[1]);
|
|
28
|
-
sum /= 256;
|
|
29
|
-
this.setOutput(sum);
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
return [kernel1, kernel2];
|
|
33
|
-
//}
|
|
34
|
-
}
|
|
35
|
-
export const binomialFilter = (args) => {
|
|
36
|
-
//{inputs: UnaryInputs, backend: MathBackendCPU}
|
|
37
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
38
|
-
const image = args.inputs.image;
|
|
39
|
-
/** @type {MathBackendCPU} */
|
|
40
|
-
const backend = args.backend;
|
|
41
|
-
const [kernel1, kernel2] = GetKernels(image);
|
|
42
|
-
const result1 = FakeShader.runCode(backend, kernel1, [image], image.dtype);
|
|
43
|
-
return FakeShader.runCode(backend, kernel2, [result1], image.dtype);
|
|
44
|
-
};
|
|
45
|
-
export const binomialFilterConfig = {
|
|
46
|
-
//: KernelConfig
|
|
47
|
-
kernelName: "BinomialFilter",
|
|
48
|
-
backendName: "cpu",
|
|
49
|
-
kernelFunc: binomialFilter, // as {} as KernelFunc,
|
|
50
|
-
};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import * as FakeShader from "./fakeShader.js";
|
|
2
|
-
import { engine } from "@tensorflow/tfjs";
|
|
3
|
-
const FREAK_EXPANSION_FACTOR = 7.0;
|
|
4
|
-
const LAPLACIAN_THRESHOLD = 3.0;
|
|
5
|
-
const LAPLACIAN_SQR_THRESHOLD = LAPLACIAN_THRESHOLD * LAPLACIAN_THRESHOLD;
|
|
6
|
-
const EDGE_THRESHOLD = 4.0;
|
|
7
|
-
const EDGE_HESSIAN_THRESHOLD = ((EDGE_THRESHOLD + 1) * (EDGE_THRESHOLD + 1)) / EDGE_THRESHOLD;
|
|
8
|
-
function GetProgram(image) {
|
|
9
|
-
const imageWidth = image.shape[1];
|
|
10
|
-
const imageHeight = image.shape[0];
|
|
11
|
-
const kernel = {
|
|
12
|
-
variableNames: ["image0", "image1", "image2"],
|
|
13
|
-
outputShape: [imageHeight, imageWidth],
|
|
14
|
-
userCode: function () {
|
|
15
|
-
const coords = this.getOutputCoords();
|
|
16
|
-
const y = coords[0];
|
|
17
|
-
const x = coords[1];
|
|
18
|
-
const value = this.getImage1(y, x);
|
|
19
|
-
// Step 1: find local maxima/minima
|
|
20
|
-
if (value * value < LAPLACIAN_SQR_THRESHOLD) {
|
|
21
|
-
this.setOutput(0.0);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
if (y < FREAK_EXPANSION_FACTOR || y > imageHeight - 1 - FREAK_EXPANSION_FACTOR) {
|
|
25
|
-
this.setOutput(0.0);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (x < FREAK_EXPANSION_FACTOR || x > imageWidth - 1 - FREAK_EXPANSION_FACTOR) {
|
|
29
|
-
this.setOutput(0.0);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
let isMax = true;
|
|
33
|
-
let isMin = true;
|
|
34
|
-
for (let dy = -1; dy <= 1; dy++) {
|
|
35
|
-
for (let dx = -1; dx <= 1; dx++) {
|
|
36
|
-
const value0 = this.getImage0(y + dy, x + dx);
|
|
37
|
-
const value1 = this.getImage1(y + dy, x + dx);
|
|
38
|
-
const value2 = this.getImage2(y + dy, x + dx);
|
|
39
|
-
if (value < value0 || value < value1 || value < value2) {
|
|
40
|
-
isMax = false;
|
|
41
|
-
}
|
|
42
|
-
if (value > value0 || value > value1 || value > value2) {
|
|
43
|
-
isMin = false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (!isMax && !isMin) {
|
|
48
|
-
this.setOutput(0.0);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
// compute edge score and reject based on threshold
|
|
52
|
-
const dxx = this.getImage1(y, x + 1) + this.getImage1(y, x - 1) - 2 * this.getImage1(y, x);
|
|
53
|
-
const dyy = this.getImage1(y + 1, x) + this.getImage1(y - 1, x) - 2 * this.getImage1(y, x);
|
|
54
|
-
const dxy = 0.25 *
|
|
55
|
-
(this.getImage1(y - 1, x - 1) +
|
|
56
|
-
this.getImage1(y + 1, x + 1) -
|
|
57
|
-
this.getImage1(y - 1, x + 1) -
|
|
58
|
-
this.getImage1(y + 1, x - 1));
|
|
59
|
-
const det = dxx * dyy - dxy * dxy;
|
|
60
|
-
if (Math.abs(det) < 0.0001) {
|
|
61
|
-
// determinant undefined. no solution
|
|
62
|
-
this.setOutput(0.0);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const edgeScore = ((dxx + dyy) * (dxx + dyy)) / det;
|
|
66
|
-
if (Math.abs(edgeScore) >= EDGE_HESSIAN_THRESHOLD) {
|
|
67
|
-
this.setOutput(0.0);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
this.setOutput(this.getImage1(y, x));
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
return kernel;
|
|
74
|
-
}
|
|
75
|
-
export const buildExtremas = (args) => {
|
|
76
|
-
let { image0, image1, image2 } = args.inputs;
|
|
77
|
-
/** @type {MathBackendCPU} */
|
|
78
|
-
const backend = args.backend;
|
|
79
|
-
image0 = engine().runKernel("DownsampleBilinear", { image: image0 });
|
|
80
|
-
image2 = engine().runKernel("UpsampleBilinear", { image: image2, targetImage: image1 });
|
|
81
|
-
const program = GetProgram(image1);
|
|
82
|
-
return FakeShader.runCode(backend, program, [image0, image1, image2], image1.dtype);
|
|
83
|
-
};
|
|
84
|
-
export const buildExtremasConfig = {
|
|
85
|
-
//: KernelConfig
|
|
86
|
-
kernelName: "BuildExtremas",
|
|
87
|
-
backendName: "cpu",
|
|
88
|
-
kernelFunc: buildExtremas, // as {} as KernelFunc,
|
|
89
|
-
};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export function computeExtremaAnglesImpl(histogram: any): Float32Array<any>;
|
|
2
|
-
export function computeExtremaAngles(args: any): any;
|
|
3
|
-
export namespace computeExtremaAnglesConfig {
|
|
4
|
-
export let kernelName: string;
|
|
5
|
-
export let backendName: string;
|
|
6
|
-
export { computeExtremaAngles as kernelFunc };
|
|
7
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
const ORIENTATION_NUM_BINS = 36;
|
|
2
|
-
export function computeExtremaAnglesImpl(histogram) {
|
|
3
|
-
const resultValues = new Float32Array(histogram.height);
|
|
4
|
-
function getHistogram(featureIndex, prev) {
|
|
5
|
-
return histogram.values[featureIndex * histogram.width + prev];
|
|
6
|
-
}
|
|
7
|
-
function setOutput(featureIndex, an) {
|
|
8
|
-
resultValues[featureIndex] = an;
|
|
9
|
-
}
|
|
10
|
-
function imod(x, y) {
|
|
11
|
-
return Math.trunc(x - y * Math.floor(x / y));
|
|
12
|
-
}
|
|
13
|
-
for (let featureIndex = 0; featureIndex < histogram.height; featureIndex++) {
|
|
14
|
-
let maxIndex = 0;
|
|
15
|
-
for (let i = 1; i < ORIENTATION_NUM_BINS; i++) {
|
|
16
|
-
if (getHistogram(featureIndex, i) > getHistogram(featureIndex, maxIndex)) {
|
|
17
|
-
maxIndex = i;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
let prev = imod(maxIndex - 1 + ORIENTATION_NUM_BINS, ORIENTATION_NUM_BINS);
|
|
21
|
-
let next = imod(maxIndex + 1, ORIENTATION_NUM_BINS);
|
|
22
|
-
/**
|
|
23
|
-
* Fit a quatratic to 3 points. The system of equations is:
|
|
24
|
-
*
|
|
25
|
-
* y0 = A*x0^2 + B*x0 + C
|
|
26
|
-
* y1 = A*x1^2 + B*x1 + C
|
|
27
|
-
* y2 = A*x2^2 + B*x2 + C
|
|
28
|
-
*
|
|
29
|
-
* This system of equations is solved for A,B,C.
|
|
30
|
-
*/
|
|
31
|
-
const p10 = maxIndex - 1;
|
|
32
|
-
const p11 = getHistogram(featureIndex, prev);
|
|
33
|
-
const p20 = maxIndex;
|
|
34
|
-
const p21 = getHistogram(featureIndex, maxIndex);
|
|
35
|
-
const p30 = maxIndex + 1;
|
|
36
|
-
const p31 = getHistogram(featureIndex, next);
|
|
37
|
-
const d1 = (p30 - p20) * (p30 - p10);
|
|
38
|
-
const d2 = (p10 - p20) * (p30 - p10);
|
|
39
|
-
const d3 = p10 - p20;
|
|
40
|
-
// If any of the denominators are zero then, just use maxIndex.
|
|
41
|
-
let fbin = maxIndex;
|
|
42
|
-
if (Math.abs(d1) > 0.00001 && Math.abs(d2) > 0.00001 && Math.abs(d3) > 0.00001) {
|
|
43
|
-
const a = p10 * p10;
|
|
44
|
-
const b = p20 * p20;
|
|
45
|
-
// Solve for the coefficients A,B,C
|
|
46
|
-
let A = (p31 - p21) / d1 - (p11 - p21) / d2;
|
|
47
|
-
if (Number.isNaN(A))
|
|
48
|
-
A = 0;
|
|
49
|
-
const B = (p11 - p21 + A * (b - a)) / d3;
|
|
50
|
-
//const C = p11 - (A * a) - (B * p10);
|
|
51
|
-
fbin = -B / (2.0 * A);
|
|
52
|
-
if (Number.isNaN(fbin))
|
|
53
|
-
fbin = 0; //console.warn(`computeExtremaAngles::NaN! fbin=${fbin} maxIndex=${maxIndex} A=${A} B=${B} p31=${p31} p21=${p21} p11=${p11}`);
|
|
54
|
-
}
|
|
55
|
-
const an = (2.0 * Math.PI * (fbin + 0.5)) / ORIENTATION_NUM_BINS - Math.PI;
|
|
56
|
-
setOutput(featureIndex, an);
|
|
57
|
-
}
|
|
58
|
-
return resultValues;
|
|
59
|
-
}
|
|
60
|
-
export const computeExtremaAngles = (args) => {
|
|
61
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
62
|
-
const { histograms } = args.inputs;
|
|
63
|
-
/** @type {import('@tensorflow/tfjs-backend-cpu').MathBackendCPU} */
|
|
64
|
-
const backend = args.backend;
|
|
65
|
-
/** @type {TypedArray} */
|
|
66
|
-
const histogramValues = {
|
|
67
|
-
values: backend.data.get(histograms.dataId).values,
|
|
68
|
-
width: histograms.shape[1],
|
|
69
|
-
height: histograms.shape[0],
|
|
70
|
-
};
|
|
71
|
-
const resultValues = computeExtremaAnglesImpl(histogramValues);
|
|
72
|
-
return backend.makeOutput(resultValues, [histograms.shape[0]], histograms.dtype);
|
|
73
|
-
};
|
|
74
|
-
export const computeExtremaAnglesConfig = {
|
|
75
|
-
//: KernelConfig
|
|
76
|
-
kernelName: "ComputeExtremaAngles",
|
|
77
|
-
backendName: "cpu",
|
|
78
|
-
kernelFunc: computeExtremaAngles, // as {} as KernelFunc,
|
|
79
|
-
};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { FREAKPOINTS } from "../../freak.js";
|
|
2
|
-
import * as FakeShader from "./fakeShader.js";
|
|
3
|
-
const FREAK_EXPANSION_FACTOR = 7.0;
|
|
4
|
-
function GetProgram(prunedExtremasHeight, pyramidImagesLength) {
|
|
5
|
-
const imageVariableNames = [];
|
|
6
|
-
for (let i = 1; i < pyramidImagesLength; i++) {
|
|
7
|
-
imageVariableNames.push("image" + i);
|
|
8
|
-
}
|
|
9
|
-
const kernel = {
|
|
10
|
-
variableNames: [...imageVariableNames, "extrema", "angles", "freakPoints"],
|
|
11
|
-
outputShape: [prunedExtremasHeight, FREAKPOINTS.length],
|
|
12
|
-
userCode: function () {
|
|
13
|
-
const getPixel = (octave, y, x) => {
|
|
14
|
-
const key = "getImage" + octave;
|
|
15
|
-
if (octave < 1 || octave >= pyramidImagesLength)
|
|
16
|
-
return 0.0;
|
|
17
|
-
return this[key](y, x);
|
|
18
|
-
};
|
|
19
|
-
const coords = this.getOutputCoords();
|
|
20
|
-
const featureIndex = coords[0];
|
|
21
|
-
const freakIndex = coords[1];
|
|
22
|
-
//const freakSigma = this.getFreakPoints(freakIndex, 0);
|
|
23
|
-
const freakX = this.getFreakPoints(freakIndex, 1);
|
|
24
|
-
const freakY = this.getFreakPoints(freakIndex, 2);
|
|
25
|
-
const octave = this.int(this.getExtrema(featureIndex, 1));
|
|
26
|
-
const inputY = this.getExtrema(featureIndex, 2);
|
|
27
|
-
const inputX = this.getExtrema(featureIndex, 3);
|
|
28
|
-
const inputAngle = this.getAngles(featureIndex);
|
|
29
|
-
const cos = FREAK_EXPANSION_FACTOR * Math.cos(inputAngle);
|
|
30
|
-
const sin = FREAK_EXPANSION_FACTOR * Math.sin(inputAngle);
|
|
31
|
-
const yp = inputY + freakX * sin + freakY * cos;
|
|
32
|
-
const xp = inputX + freakX * cos + freakY * -sin;
|
|
33
|
-
const x0 = this.int(Math.floor(xp));
|
|
34
|
-
const x1 = x0 + 1;
|
|
35
|
-
const y0 = this.int(Math.floor(yp));
|
|
36
|
-
const y1 = y0 + 1;
|
|
37
|
-
const f1 = getPixel(octave, y0, x0);
|
|
38
|
-
const f2 = getPixel(octave, y0, x1);
|
|
39
|
-
const f3 = getPixel(octave, y1, x0);
|
|
40
|
-
const f4 = getPixel(octave, y1, x1);
|
|
41
|
-
/* const x1f = float(x1);
|
|
42
|
-
const y1f = float(y1);
|
|
43
|
-
const x0f = float(x0);
|
|
44
|
-
const y0f = float(y0); */
|
|
45
|
-
// ratio for interpolation between four neighbouring points
|
|
46
|
-
const value = (x1 - xp) * (y1 - yp) * f1 +
|
|
47
|
-
(xp - x0) * (y1 - yp) * f2 +
|
|
48
|
-
(x1 - xp) * (yp - y0) * f3 +
|
|
49
|
-
(xp - x0) * (yp - y0) * f4;
|
|
50
|
-
this.setOutput(value);
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
return kernel;
|
|
54
|
-
}
|
|
55
|
-
export const computeExtremaFreak = (args) => {
|
|
56
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
57
|
-
const { gaussianImagesT, prunedExtremas, prunedExtremasAngles, freakPointsT, pyramidImagesLength, } = args.inputs;
|
|
58
|
-
/** @type {MathBackendCPU} */
|
|
59
|
-
const backend = args.backend;
|
|
60
|
-
const prog = GetProgram(prunedExtremas.shape[0], pyramidImagesLength);
|
|
61
|
-
return FakeShader.runCode(backend, prog, [...gaussianImagesT, prunedExtremas, prunedExtremasAngles, freakPointsT], "float32");
|
|
62
|
-
};
|
|
63
|
-
export const computeExtremaFreakConfig = {
|
|
64
|
-
//: KernelConfig
|
|
65
|
-
kernelName: "ComputeExtremaFreak",
|
|
66
|
-
backendName: "cpu",
|
|
67
|
-
kernelFunc: computeExtremaFreak, // as {} as KernelFunc,
|
|
68
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { FREAKPOINTS } from "../../freak.js";
|
|
2
|
-
const FREAK_CONPARISON_COUNT = ((FREAKPOINTS.length - 1) * FREAKPOINTS.length) / 2;
|
|
3
|
-
const descriptorCount = Math.ceil(FREAK_CONPARISON_COUNT / 8);
|
|
4
|
-
function computeFreakDescriptorImpl(extremaFreaks, positionT) {
|
|
5
|
-
const resultValues = new Float32Array(extremaFreaks.height * descriptorCount);
|
|
6
|
-
function getP(y, x) {
|
|
7
|
-
return positionT.values[y * positionT.width + x];
|
|
8
|
-
}
|
|
9
|
-
function getFreak(y, x) {
|
|
10
|
-
return extremaFreaks.values[y * extremaFreaks.width + x];
|
|
11
|
-
}
|
|
12
|
-
function setOutput(y, x, o) {
|
|
13
|
-
resultValues[y * descriptorCount + x] = o;
|
|
14
|
-
}
|
|
15
|
-
for (let featureIndex = 0; featureIndex < extremaFreaks.height; featureIndex++) {
|
|
16
|
-
for (let _descIndex = 0; _descIndex < descriptorCount; _descIndex++) {
|
|
17
|
-
const descIndex = _descIndex * 8;
|
|
18
|
-
let sum = 0;
|
|
19
|
-
for (let i = 0; i < 8; i++) {
|
|
20
|
-
if (descIndex + i >= FREAK_CONPARISON_COUNT) {
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
const p1 = Math.trunc(getP(descIndex + i, 0));
|
|
24
|
-
const p2 = Math.trunc(getP(descIndex + i, 1));
|
|
25
|
-
const v1 = getFreak(featureIndex, p1);
|
|
26
|
-
const v2 = getFreak(featureIndex, p2);
|
|
27
|
-
if (v1 < v2 + 0.01) {
|
|
28
|
-
sum += Math.trunc(Math.pow(2.0, 7.0 - i));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
setOutput(featureIndex, _descIndex, sum);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return resultValues;
|
|
35
|
-
}
|
|
36
|
-
export const computeFreakDescriptor = (args) => {
|
|
37
|
-
const { extremaFreaks, positionT } = args.inputs;
|
|
38
|
-
const { backend } = args;
|
|
39
|
-
const freaksData = {
|
|
40
|
-
values: backend.data.get(extremaFreaks.dataId).values,
|
|
41
|
-
height: extremaFreaks.shape[0],
|
|
42
|
-
width: extremaFreaks.shape[1],
|
|
43
|
-
};
|
|
44
|
-
const positionData = {
|
|
45
|
-
values: backend.data.get(positionT.dataId).values,
|
|
46
|
-
width: positionT.shape[1],
|
|
47
|
-
};
|
|
48
|
-
//backend.runWebGLProgram(program,[extremaFreaks, positionT],'int32');
|
|
49
|
-
const resultValues = computeFreakDescriptorImpl(freaksData, positionData);
|
|
50
|
-
return backend.makeOutput(resultValues, [extremaFreaks.shape[0], descriptorCount], "int32");
|
|
51
|
-
};
|
|
52
|
-
export const computeFreakDescriptorConfig = {
|
|
53
|
-
//: KernelConfig
|
|
54
|
-
kernelName: "ComputeFreakDescriptors",
|
|
55
|
-
backendName: "cpu",
|
|
56
|
-
kernelFunc: computeFreakDescriptor, // as {} as KernelFunc,
|
|
57
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { tensor } from "@tensorflow/tfjs";
|
|
2
|
-
import * as FakeShader from "./fakeShader.js";
|
|
3
|
-
function GetProgram(numDogPyramidImages, extremasListLength) {
|
|
4
|
-
const dogVariableNames = [];
|
|
5
|
-
for (let i = 1; i < numDogPyramidImages; i++) {
|
|
6
|
-
dogVariableNames.push("image" + i);
|
|
7
|
-
}
|
|
8
|
-
const program = {
|
|
9
|
-
variableNames: [...dogVariableNames, "extrema"],
|
|
10
|
-
outputShape: [extremasListLength, 3, 3], // 3x3 pixels around the extrema
|
|
11
|
-
userCode: function () {
|
|
12
|
-
const getPixel = (octave, y, x) => {
|
|
13
|
-
const k = "getImage" + octave;
|
|
14
|
-
if (!this.hasOwnProperty(k)) {
|
|
15
|
-
throw new Error(`ComputeLocalization:: ${k} does not exist`);
|
|
16
|
-
}
|
|
17
|
-
return this[k](y, x);
|
|
18
|
-
};
|
|
19
|
-
const coords = this.getOutputCoords();
|
|
20
|
-
const featureIndex = coords[0];
|
|
21
|
-
const score = this.getExtrema(featureIndex, 0);
|
|
22
|
-
if (score == 0.0) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const dy = coords[1] - 1;
|
|
26
|
-
const dx = coords[2] - 1;
|
|
27
|
-
const octave = this.int(this.getExtrema(featureIndex, 1));
|
|
28
|
-
const y = this.int(this.getExtrema(featureIndex, 2));
|
|
29
|
-
const x = this.int(this.getExtrema(featureIndex, 3));
|
|
30
|
-
this.setOutput(getPixel(octave, y + dy, x + dx));
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
//}
|
|
34
|
-
return program;
|
|
35
|
-
}
|
|
36
|
-
export const computeLocalization = (args) => {
|
|
37
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
38
|
-
const { prunedExtremasList, dogPyramidImagesT } = args.inputs;
|
|
39
|
-
/** @type {MathBackendCPU} */
|
|
40
|
-
const backend = args.backend;
|
|
41
|
-
const program = GetProgram(dogPyramidImagesT.length, prunedExtremasList.length);
|
|
42
|
-
const prunedExtremasT = tensor(prunedExtremasList, [prunedExtremasList.length, prunedExtremasList[0].length], "int32");
|
|
43
|
-
return FakeShader.runCode(backend, program, [...dogPyramidImagesT.slice(1), prunedExtremasT], dogPyramidImagesT[0].dtype);
|
|
44
|
-
};
|
|
45
|
-
export const computeLocalizationConfig = {
|
|
46
|
-
//: KernelConfig
|
|
47
|
-
kernelName: "ComputeLocalization",
|
|
48
|
-
backendName: "cpu",
|
|
49
|
-
kernelFunc: computeLocalization, // as {} as KernelFunc,
|
|
50
|
-
};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import * as FakeShader from "./fakeShader.js";
|
|
2
|
-
const oneOver2PI = 0.159154943091895;
|
|
3
|
-
const ORIENTATION_NUM_BINS = 36;
|
|
4
|
-
function GetPrograms(prunedExtremasT, radialPropertiesT, pyramidImagesLength) {
|
|
5
|
-
const imageVariableNames = [];
|
|
6
|
-
for (let i = 1; i < pyramidImagesLength; i++) {
|
|
7
|
-
imageVariableNames.push("image" + i);
|
|
8
|
-
}
|
|
9
|
-
const kernel1 = {
|
|
10
|
-
variableNames: [...imageVariableNames, "extrema", "radial"],
|
|
11
|
-
outputShape: [prunedExtremasT.shape[0], radialPropertiesT.shape[0], 2], // last dimension: [fbin, magnitude]
|
|
12
|
-
userCode: function () {
|
|
13
|
-
//${ kernel1SubCodes }
|
|
14
|
-
const getPixel = (octave, y, x) => {
|
|
15
|
-
const k = "getImage" + octave;
|
|
16
|
-
if (!this.hasOwnProperty(k)) {
|
|
17
|
-
//console.error(`ComputeOrientationHistograms:: ${k} does not exist! y:${y} x:${x}`);
|
|
18
|
-
return 0.0;
|
|
19
|
-
}
|
|
20
|
-
return this[k](y, x);
|
|
21
|
-
};
|
|
22
|
-
//void main() {
|
|
23
|
-
const coords = this.getOutputCoords();
|
|
24
|
-
const featureIndex = coords[0];
|
|
25
|
-
const radialIndex = coords[1];
|
|
26
|
-
const propertyIndex = coords[2];
|
|
27
|
-
const radialY = this.int(this.getRadial(radialIndex, 0));
|
|
28
|
-
const radialX = this.int(this.getRadial(radialIndex, 1));
|
|
29
|
-
const radialW = this.getRadial(radialIndex, 2);
|
|
30
|
-
const octave = this.int(this.getExtrema(featureIndex, 1));
|
|
31
|
-
const y = this.int(this.getExtrema(featureIndex, 2));
|
|
32
|
-
const x = this.int(this.getExtrema(featureIndex, 3));
|
|
33
|
-
const xp = x + radialX;
|
|
34
|
-
const yp = y + radialY;
|
|
35
|
-
const dy = getPixel(octave, yp + 1, xp) - getPixel(octave, yp - 1, xp);
|
|
36
|
-
const dx = getPixel(octave, yp, xp + 1) - getPixel(octave, yp, xp - 1);
|
|
37
|
-
if (propertyIndex == 0) {
|
|
38
|
-
// be careful that atan(0, 0) gives 1.57 instead of 0 (different from js), but doesn't matter here, coz magnitude is 0
|
|
39
|
-
const angle = this.atan(dy, dx) + Math.PI;
|
|
40
|
-
const fbin = angle * ORIENTATION_NUM_BINS * oneOver2PI;
|
|
41
|
-
this.setOutput(fbin);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (propertyIndex == 1) {
|
|
45
|
-
const mag = Math.sqrt(dx * dx + dy * dy);
|
|
46
|
-
const magnitude = radialW * mag;
|
|
47
|
-
this.setOutput(magnitude);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
// }
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
const kernel2 = {
|
|
54
|
-
variableNames: ["fbinMag"],
|
|
55
|
-
outputShape: [prunedExtremasT.shape[0], ORIENTATION_NUM_BINS],
|
|
56
|
-
userCode: function () {
|
|
57
|
-
function imod(x, y) {
|
|
58
|
-
return Math.trunc(x - y * Math.floor(x / y));
|
|
59
|
-
}
|
|
60
|
-
const coords = this.getOutputCoords();
|
|
61
|
-
const featureIndex = coords[0];
|
|
62
|
-
const binIndex = coords[1];
|
|
63
|
-
let sum = 0;
|
|
64
|
-
for (let i = 0; i < radialPropertiesT.shape[0]; i++) {
|
|
65
|
-
const fbin = this.getFbinMag(featureIndex, i, 0);
|
|
66
|
-
const bin = Math.trunc(Math.floor(fbin - 0.5));
|
|
67
|
-
const b1 = imod(bin + ORIENTATION_NUM_BINS, ORIENTATION_NUM_BINS);
|
|
68
|
-
const b2 = imod(bin + 1 + ORIENTATION_NUM_BINS, ORIENTATION_NUM_BINS);
|
|
69
|
-
if (b1 == binIndex || b2 == binIndex) {
|
|
70
|
-
const magnitude = this.getFbinMag(featureIndex, i, 1);
|
|
71
|
-
const w2 = fbin - bin - 0.5;
|
|
72
|
-
const w1 = w2 * -1 + 1;
|
|
73
|
-
if (b1 == binIndex) {
|
|
74
|
-
sum += w1 * magnitude;
|
|
75
|
-
}
|
|
76
|
-
if (b2 == binIndex) {
|
|
77
|
-
sum += w2 * magnitude;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
this.setOutput(sum);
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
return [kernel1, kernel2];
|
|
85
|
-
//}
|
|
86
|
-
//return cache[key];
|
|
87
|
-
}
|
|
88
|
-
export const computeOrientationHistograms = (args) => {
|
|
89
|
-
const { gaussianImagesT, prunedExtremasT, radialPropertiesT, pyramidImagesLength } = args.inputs;
|
|
90
|
-
/** @type {MathBackendCPU} */
|
|
91
|
-
const backend = args.backend;
|
|
92
|
-
const [program1, program2] = GetPrograms(prunedExtremasT, radialPropertiesT, pyramidImagesLength);
|
|
93
|
-
const result1 = FakeShader.runCode(backend, program1, [...gaussianImagesT, prunedExtremasT, radialPropertiesT], radialPropertiesT.dtype);
|
|
94
|
-
return FakeShader.runCode(backend, program2, [result1], radialPropertiesT.dtype);
|
|
95
|
-
};
|
|
96
|
-
export const computeOrientationHistogramsConfig = {
|
|
97
|
-
kernelName: "ComputeOrientationHistograms",
|
|
98
|
-
backendName: "cpu",
|
|
99
|
-
kernelFunc: computeOrientationHistograms, // as {} as KernelFunc,
|
|
100
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import * as FakeShader from "./fakeShader.js";
|
|
2
|
-
export const downsampleBilinear = (args) => {
|
|
3
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
4
|
-
const x = args.inputs.image;
|
|
5
|
-
/** @type {MathBackendCPU} */
|
|
6
|
-
const backend = args.backend;
|
|
7
|
-
const kernel = {
|
|
8
|
-
variableNames: ["p"],
|
|
9
|
-
outputShape: [Math.floor(x.shape[0] / 2), Math.floor(x.shape[1] / 2)],
|
|
10
|
-
userCode: function () {
|
|
11
|
-
const coords = this.getOutputCoords();
|
|
12
|
-
const y = coords[0] * 2;
|
|
13
|
-
const x = coords[1] * 2;
|
|
14
|
-
let sum = new Float32Array(1);
|
|
15
|
-
sum[0] = Math.fround(this.getP(y, x) * 0.25);
|
|
16
|
-
sum[0] += Math.fround(this.getP(y + 1, x) * 0.25);
|
|
17
|
-
sum[0] += Math.fround(this.getP(y, x + 1) * 0.25);
|
|
18
|
-
sum[0] += Math.fround(this.getP(y + 1, x + 1) * 0.25);
|
|
19
|
-
this.setOutput(sum[0]);
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
return FakeShader.runCode(backend, kernel, [x], x.dtype);
|
|
23
|
-
};
|
|
24
|
-
export const downsampleBilinearConfig = {
|
|
25
|
-
//: KernelConfig
|
|
26
|
-
kernelName: "DownsampleBilinear",
|
|
27
|
-
backendName: "cpu",
|
|
28
|
-
kernelFunc: downsampleBilinear, // as {} as KernelFunc,
|
|
29
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import * as FakeShader from "./fakeShader.js";
|
|
2
|
-
function GetProgram(outHeight, outWidth) {
|
|
3
|
-
const kernel = {
|
|
4
|
-
variableNames: ["extrema"],
|
|
5
|
-
outputShape: [outHeight, outWidth],
|
|
6
|
-
userCode: function () {
|
|
7
|
-
const coords = this.getOutputCoords();
|
|
8
|
-
const y = coords[0] * 2;
|
|
9
|
-
const x = coords[1] * 2;
|
|
10
|
-
let location = 0.0;
|
|
11
|
-
let values = this.getExtrema(y, x);
|
|
12
|
-
if (this.getExtrema(y + 1, x) != 0.0) {
|
|
13
|
-
location = 1.0;
|
|
14
|
-
values = this.getExtrema(y + 1, x);
|
|
15
|
-
}
|
|
16
|
-
else if (this.getExtrema(y, x + 1) != 0.0) {
|
|
17
|
-
location = 2.0;
|
|
18
|
-
values = this.getExtrema(y, x + 1);
|
|
19
|
-
}
|
|
20
|
-
else if (this.getExtrema(y + 1, x + 1) != 0.0) {
|
|
21
|
-
location = 3.0;
|
|
22
|
-
values = this.getExtrema(y + 1, x + 1);
|
|
23
|
-
}
|
|
24
|
-
if (values < 0.0) {
|
|
25
|
-
this.setOutput(location * -1000.0 + values);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
this.setOutput(location * 1000.0 + values);
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
return kernel;
|
|
33
|
-
}
|
|
34
|
-
export const extremaReduction = (args) => {
|
|
35
|
-
const { extremasResultT } = args.inputs;
|
|
36
|
-
/** @type {MathBackendCPU} */
|
|
37
|
-
const backend = args.backend;
|
|
38
|
-
const extremaHeight = extremasResultT.shape[0];
|
|
39
|
-
const extremaWidth = extremasResultT.shape[1];
|
|
40
|
-
const outHeight = Math.floor(extremaHeight / 2.0);
|
|
41
|
-
const outWidth = Math.floor(extremaWidth / 2.0);
|
|
42
|
-
const program = GetProgram(outHeight, outWidth);
|
|
43
|
-
return FakeShader.runCode(backend, program, [extremasResultT], extremasResultT.dtype);
|
|
44
|
-
};
|
|
45
|
-
export const extremaReductionConfig = {
|
|
46
|
-
//: KernelConfig
|
|
47
|
-
kernelName: "ExtremaReduction",
|
|
48
|
-
backendName: "cpu",
|
|
49
|
-
kernelFunc: extremaReduction, // as {} as KernelFunc,
|
|
50
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export type Kernel = {
|
|
2
|
-
variableNames: string[];
|
|
3
|
-
outputShape: number[];
|
|
4
|
-
userCode: Function;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* @typedef {Object} Kernel
|
|
8
|
-
* @property {string[]} variableNames
|
|
9
|
-
* @property {number[]} outputShape
|
|
10
|
-
* @property {Function} userCode
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @param {MathBackendCPU} backend
|
|
15
|
-
* @param {Kernel} kernel
|
|
16
|
-
* @param {Array<.TensorInfo>} inputs
|
|
17
|
-
* @param {DataType} dtype
|
|
18
|
-
* @returns {Tensor}
|
|
19
|
-
*/
|
|
20
|
-
export function runCode(backend: MathBackendCPU, kernel: Kernel, inputs: any, dtype: DataType): Tensor;
|