@srsergio/taptapp-ar 1.0.9 → 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 +9 -29
- package/dist/compiler/offline-compiler.js +38 -72
- 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/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 +38 -75
- package/src/compiler/three.js +0 -4
- package/src/compiler/tracker/tracker.js +183 -283
- 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,88 +0,0 @@
|
|
|
1
|
-
import { zeros, map, flatten as mathjsflatten } from "mathjs";
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {Object} Kernel
|
|
4
|
-
* @property {string[]} variableNames
|
|
5
|
-
* @property {number[]} outputShape
|
|
6
|
-
* @property {Function} userCode
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @param {MathBackendCPU} backend
|
|
12
|
-
* @param {Kernel} kernel
|
|
13
|
-
* @param {Array<.TensorInfo>} inputs
|
|
14
|
-
* @param {DataType} dtype
|
|
15
|
-
* @returns {Tensor}
|
|
16
|
-
*/
|
|
17
|
-
function runCode(backend, kernel, inputs, dtype) {
|
|
18
|
-
const inputData = inputs.map((value) => {
|
|
19
|
-
return backend.data.get(value.dataId).values;
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
//create getter functions for every variable name, clamping the input.
|
|
23
|
-
const tempData = {};
|
|
24
|
-
kernel.variableNames.forEach((name, index) => {
|
|
25
|
-
const funName = `get${capFirstLetter(name)}`;
|
|
26
|
-
//console.log("Making function:",funName,inputs[index].shape);
|
|
27
|
-
tempData[funName] = function (...args) {
|
|
28
|
-
const inputIndex = index;
|
|
29
|
-
for (let i = 0; i < args.length; i++) {
|
|
30
|
-
args[i] = clampInt(args[i], 0, inputs[inputIndex].shape[i]);
|
|
31
|
-
}
|
|
32
|
-
return inputData[index][flatten(args, inputs[inputIndex].shape)];
|
|
33
|
-
};
|
|
34
|
-
});
|
|
35
|
-
tempData.int = Math.trunc;
|
|
36
|
-
tempData.atan = Math.atan2;
|
|
37
|
-
//create an empty matrix to map the output size, because i'm lazy and want to use Matrix.map(...)
|
|
38
|
-
//const temp = new Matrix();
|
|
39
|
-
//console.log("Creating output shape:",kernel.outputShape);
|
|
40
|
-
const temp = zeros(kernel.outputShape); //reshape([0,0,0],kernel.outputShape);
|
|
41
|
-
const output = map(temp, (_value, index) => {
|
|
42
|
-
tempData.getOutputCoords = () => {
|
|
43
|
-
return index;
|
|
44
|
-
};
|
|
45
|
-
let out;
|
|
46
|
-
|
|
47
|
-
tempData.setOutput = (newValue) => {
|
|
48
|
-
out = Number.isNaN(newValue) ? 0 : Math.fround(newValue);
|
|
49
|
-
};
|
|
50
|
-
//bind the method calls and run the code
|
|
51
|
-
kernel.userCode.bind(tempData)();
|
|
52
|
-
return out;
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
//output.flat()
|
|
56
|
-
//convert the output from a matrix into a tensor
|
|
57
|
-
|
|
58
|
-
return backend.makeOutput(mathjsflatten(output), kernel.outputShape, dtype);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
* @param {string} word
|
|
64
|
-
* @returns
|
|
65
|
-
*/
|
|
66
|
-
function capFirstLetter(word) {
|
|
67
|
-
return word[0].toUpperCase() + word.substring(1);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function clampInt(n, min, max) {
|
|
71
|
-
return Math.min(Math.max(n, min), max - 1);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
75
|
-
* @param {number[]} input
|
|
76
|
-
* @param {number[]} max
|
|
77
|
-
* @returns
|
|
78
|
-
*/
|
|
79
|
-
function flatten(input, max) {
|
|
80
|
-
return input.reduce((prev, current, index) => {
|
|
81
|
-
for (let i = index + 1; i < max.length; i++) {
|
|
82
|
-
current *= max[i];
|
|
83
|
-
}
|
|
84
|
-
return prev + current;
|
|
85
|
-
}, 0);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export { runCode };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { registerKernel } from "@tensorflow/tfjs";
|
|
2
|
-
import { binomialFilterConfig } from "./binomialFilter.js";
|
|
3
|
-
import { buildExtremasConfig } from "./buildExtremas.js";
|
|
4
|
-
import { computeExtremaAnglesConfig } from "./computeExtremaAngles.js";
|
|
5
|
-
import { computeExtremaFreakConfig } from "./computeExtremaFreak.js";
|
|
6
|
-
import { computeFreakDescriptorConfig } from "./computeFreakDescriptors.js";
|
|
7
|
-
import { computeLocalizationConfig } from "./computeLocalization.js";
|
|
8
|
-
import { computeOrientationHistogramsConfig } from "./computeOrientationHistograms.js";
|
|
9
|
-
import { downsampleBilinearConfig } from "./downsampleBilinear.js";
|
|
10
|
-
import { extremaReductionConfig } from "./extremaReduction.js";
|
|
11
|
-
import { smoothHistogramsConfig } from "./smoothHistograms.js";
|
|
12
|
-
import { upsampleBilinearConfig } from "./upsampleBilinear.js";
|
|
13
|
-
|
|
14
|
-
//export function Register(){
|
|
15
|
-
registerKernel(binomialFilterConfig);
|
|
16
|
-
registerKernel(buildExtremasConfig);
|
|
17
|
-
registerKernel(computeExtremaAnglesConfig);
|
|
18
|
-
registerKernel(computeExtremaFreakConfig);
|
|
19
|
-
registerKernel(computeFreakDescriptorConfig);
|
|
20
|
-
registerKernel(computeLocalizationConfig);
|
|
21
|
-
registerKernel(computeOrientationHistogramsConfig);
|
|
22
|
-
registerKernel(downsampleBilinearConfig);
|
|
23
|
-
registerKernel(extremaReductionConfig);
|
|
24
|
-
registerKernel(smoothHistogramsConfig);
|
|
25
|
-
registerKernel(upsampleBilinearConfig);
|
|
26
|
-
//}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
function clamp(n, min, max) {
|
|
3
|
-
return Math.min(Math.max(min, n), max - 1);
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
const pruneImpl = (vals, width, height) => {
|
|
7
|
-
const w = Math.floor(width / 2);
|
|
8
|
-
const h = Math.floor(height / 2);
|
|
9
|
-
const resultValues = new Float32Array(w * h);
|
|
10
|
-
function getExtrema(x, y) {
|
|
11
|
-
x = clamp(x, 0, width);
|
|
12
|
-
y = clamp(y, 0, height);
|
|
13
|
-
return vals[y * width + x];
|
|
14
|
-
}
|
|
15
|
-
function setOutput(x, y, o) {
|
|
16
|
-
resultValues[y * width + x] = o;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
for (let x = 0; x < w; x++) {
|
|
20
|
-
for (let y = 0; y < h; y++) {
|
|
21
|
-
const x2 = x * 2;
|
|
22
|
-
const y2 = y * 2;
|
|
23
|
-
|
|
24
|
-
let location = 0.0;
|
|
25
|
-
let values = getExtrema(x2, y2);
|
|
26
|
-
|
|
27
|
-
if (getExtrema(x2, y2 + 1) != 0.0) {
|
|
28
|
-
location = 1.0;
|
|
29
|
-
values = getExtrema(x2, y2 + 1);
|
|
30
|
-
} else if (getExtrema(x2 + 1, y2) != 0.0) {
|
|
31
|
-
location = 2.0;
|
|
32
|
-
values = getExtrema(x2 + 1, y2);
|
|
33
|
-
} else if (getExtrema(x2 + 1, y2 + 1) != 0.0) {
|
|
34
|
-
location = 3.0;
|
|
35
|
-
values = getExtrema(x2 + 1, y2 + 1);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (values < 0.0) {
|
|
39
|
-
setOutput(x, y, location * -1000.0 + values);
|
|
40
|
-
} else {
|
|
41
|
-
setOutput(x, y, location * 1000.0 + values);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return resultValues;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const prune = (args) => {
|
|
49
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
50
|
-
const x = args.inputs.x;
|
|
51
|
-
/** @type {MathBackendCPU} */
|
|
52
|
-
const cpuBackend = args.backend;
|
|
53
|
-
const imageHeight = x.shape[0];
|
|
54
|
-
const imageWidth = x.shape[1];
|
|
55
|
-
/** @type {TypedArray} */
|
|
56
|
-
const values = cpuBackend.data.get(x.dataId).values;
|
|
57
|
-
|
|
58
|
-
const resultValues = pruneImpl(values, imageWidth, imageHeight);
|
|
59
|
-
|
|
60
|
-
return cpuBackend.makeOutput(
|
|
61
|
-
resultValues,
|
|
62
|
-
[Math.floor(imageHeight / 2), Math.floor(imageWidth / 2)],
|
|
63
|
-
"float32",
|
|
64
|
-
);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const pruneConfig = {
|
|
68
|
-
//: KernelConfig
|
|
69
|
-
kernelName: "Prune",
|
|
70
|
-
backendName: "cpu",
|
|
71
|
-
kernelFunc: prune, // as {} as KernelFunc,
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export {
|
|
75
|
-
pruneConfig,
|
|
76
|
-
prune,
|
|
77
|
-
pruneImpl,
|
|
78
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const ORIENTATION_NUM_BINS = 36;
|
|
2
|
-
const ORIENTATION_SMOOTHING_ITERATIONS = 5;
|
|
3
|
-
|
|
4
|
-
function smoothHistogramsImpl(histograms) {
|
|
5
|
-
const resultValues = new Float32Array(histograms.height * ORIENTATION_NUM_BINS);
|
|
6
|
-
function getHistogram(y, x) {
|
|
7
|
-
return histograms.values[y * histograms.width + x];
|
|
8
|
-
}
|
|
9
|
-
function setOutput(y, x, o) {
|
|
10
|
-
resultValues[y * ORIENTATION_NUM_BINS + x] = o;
|
|
11
|
-
}
|
|
12
|
-
function imod(x, y) {
|
|
13
|
-
return Math.trunc(x - y * Math.floor(x / y));
|
|
14
|
-
}
|
|
15
|
-
for (let featureIndex = 0; featureIndex < histograms.height; featureIndex++) {
|
|
16
|
-
for (let binIndex = 0; binIndex < ORIENTATION_NUM_BINS; binIndex++) {
|
|
17
|
-
const prevBin = imod(binIndex - 1 + ORIENTATION_NUM_BINS, ORIENTATION_NUM_BINS);
|
|
18
|
-
const nextBin = imod(binIndex + 1, ORIENTATION_NUM_BINS);
|
|
19
|
-
const result =
|
|
20
|
-
0.274068619061197 * getHistogram(featureIndex, prevBin) +
|
|
21
|
-
0.451862761877606 * getHistogram(featureIndex, binIndex) +
|
|
22
|
-
0.274068619061197 * getHistogram(featureIndex, nextBin);
|
|
23
|
-
|
|
24
|
-
setOutput(featureIndex, binIndex, result);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return resultValues;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const smoothHistograms = (args) => {
|
|
32
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
33
|
-
const { histograms } = args.inputs;
|
|
34
|
-
/** @type {MathBackendCPU} */
|
|
35
|
-
const backend = args.backend;
|
|
36
|
-
const histogramsData = {
|
|
37
|
-
values: backend.data.get(histograms.dataId).values,
|
|
38
|
-
height: histograms.shape[0],
|
|
39
|
-
width: histograms.shape[1],
|
|
40
|
-
};
|
|
41
|
-
//const program = GetProgram(histograms);
|
|
42
|
-
for (let i = 0; i < ORIENTATION_SMOOTHING_ITERATIONS; i++) {
|
|
43
|
-
histogramsData.values = smoothHistogramsImpl(histogramsData); //backend.runWebGLProgram(program, [histograms], histograms.dtype);//this._compileAndRun(program, [histograms]);
|
|
44
|
-
}
|
|
45
|
-
return backend.makeOutput(
|
|
46
|
-
histogramsData.values,
|
|
47
|
-
[histograms.shape[0], ORIENTATION_NUM_BINS],
|
|
48
|
-
histograms.dtype,
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const smoothHistogramsConfig = {
|
|
53
|
-
//: KernelConfig
|
|
54
|
-
kernelName: "SmoothHistograms",
|
|
55
|
-
backendName: "cpu",
|
|
56
|
-
kernelFunc: smoothHistograms, // as {} as KernelFunc,
|
|
57
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import * as FakeShader from "./fakeShader.js";
|
|
2
|
-
function getProgram(targetImage) {
|
|
3
|
-
const kernel = {
|
|
4
|
-
variableNames: ["p"],
|
|
5
|
-
outputShape: [targetImage.shape[0], targetImage.shape[1]],
|
|
6
|
-
userCode: function () {
|
|
7
|
-
const coords = this.getOutputCoords();
|
|
8
|
-
const j = coords[0];
|
|
9
|
-
const i = coords[1];
|
|
10
|
-
|
|
11
|
-
const sj = Math.fround(0.5 * j) - 0.25;
|
|
12
|
-
const si = Math.fround(0.5 * i) - 0.25;
|
|
13
|
-
|
|
14
|
-
const sj0 = Math.floor(sj);
|
|
15
|
-
const sj1 = Math.ceil(sj);
|
|
16
|
-
const si0 = Math.floor(si);
|
|
17
|
-
const si1 = Math.ceil(si);
|
|
18
|
-
|
|
19
|
-
const sj0I = this.int(sj0);
|
|
20
|
-
const sj1I = this.int(sj1);
|
|
21
|
-
const si0I = this.int(si0);
|
|
22
|
-
const si1I = this.int(si1);
|
|
23
|
-
|
|
24
|
-
let sum = 0.0;
|
|
25
|
-
sum += this.getP(sj0I, si0I) * Math.fround((si1 - si) * (sj1 - sj));
|
|
26
|
-
sum += this.getP(sj1I, si0I) * Math.fround((si1 - si) * (sj - sj0));
|
|
27
|
-
sum += this.getP(sj0I, si1I) * Math.fround((si - si0) * (sj1 - sj));
|
|
28
|
-
sum += this.getP(sj1I, si1I) * Math.fround((si - si0) * (sj - sj0));
|
|
29
|
-
this.setOutput(sum);
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
return kernel;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const upsampleBilinear = (args) => {
|
|
36
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
37
|
-
const { image, targetImage } = args.inputs;
|
|
38
|
-
|
|
39
|
-
/** @type {MathBackendCPU} */
|
|
40
|
-
const cpuBackend = args.backend;
|
|
41
|
-
|
|
42
|
-
const program = getProgram(targetImage);
|
|
43
|
-
return FakeShader.runCode(cpuBackend, program, [image], image.dtype);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const upsampleBilinearConfig = {
|
|
47
|
-
//: KernelConfig
|
|
48
|
-
kernelName: "UpsampleBilinear",
|
|
49
|
-
backendName: "cpu",
|
|
50
|
-
kernelFunc: upsampleBilinear, // as {} as KernelFunc,
|
|
51
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
const cache = {};
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {string} key
|
|
6
|
-
* @param {TensorInfo} image
|
|
7
|
-
* @returns {[GPGPUProgram,GPGPUProgram]}
|
|
8
|
-
*/
|
|
9
|
-
function GetKernels(image) {
|
|
10
|
-
const imageWidth = image.shape[1];
|
|
11
|
-
const imageHeight = image.shape[0];
|
|
12
|
-
const key = "w" + imageWidth + "h" + imageHeight;
|
|
13
|
-
if (!cache.hasOwnProperty(key)) {
|
|
14
|
-
const kernel1 = {
|
|
15
|
-
variableNames: ["p"],
|
|
16
|
-
outputShape: [imageHeight, imageWidth],
|
|
17
|
-
userCode: `
|
|
18
|
-
void main() {
|
|
19
|
-
ivec2 coords = getOutputCoords();
|
|
20
|
-
|
|
21
|
-
float sum = getP(coords[0], coords[1]-2);
|
|
22
|
-
sum += getP(coords[0], coords[1]-1) * 4.;
|
|
23
|
-
sum += getP(coords[0], coords[1]) * 6.;
|
|
24
|
-
sum += getP(coords[0], coords[1]+1) * 4.;
|
|
25
|
-
sum += getP(coords[0], coords[1]+2);
|
|
26
|
-
setOutput(sum);
|
|
27
|
-
}
|
|
28
|
-
`,
|
|
29
|
-
};
|
|
30
|
-
const kernel2 = {
|
|
31
|
-
variableNames: ["p"],
|
|
32
|
-
outputShape: [imageHeight, imageWidth],
|
|
33
|
-
userCode: `
|
|
34
|
-
void main() {
|
|
35
|
-
ivec2 coords = getOutputCoords();
|
|
36
|
-
|
|
37
|
-
float sum = getP(coords[0]-2, coords[1]);
|
|
38
|
-
sum += getP(coords[0]-1, coords[1]) * 4.;
|
|
39
|
-
sum += getP(coords[0], coords[1]) * 6.;
|
|
40
|
-
sum += getP(coords[0]+1, coords[1]) * 4.;
|
|
41
|
-
sum += getP(coords[0]+2, coords[1]);
|
|
42
|
-
sum /= 256.;
|
|
43
|
-
setOutput(sum);
|
|
44
|
-
}
|
|
45
|
-
`,
|
|
46
|
-
};
|
|
47
|
-
cache[key] = [kernel1, kernel2];
|
|
48
|
-
}
|
|
49
|
-
return cache[key];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const binomialFilter = (args) => {
|
|
53
|
-
//{inputs: UnaryInputs, backend: MathBackendCPU}
|
|
54
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
55
|
-
const image = args.inputs.image;
|
|
56
|
-
/** @type {MathBackendWebGL} */
|
|
57
|
-
const backend = args.backend;
|
|
58
|
-
|
|
59
|
-
const [kernel1, kernel2] = GetKernels(image);
|
|
60
|
-
|
|
61
|
-
const result1 = backend.runWebGLProgram(kernel1, [image], image.dtype);
|
|
62
|
-
const result2 = backend.runWebGLProgram(kernel2, [result1], image.dtype);
|
|
63
|
-
backend.disposeIntermediateTensorInfo(result1);
|
|
64
|
-
return result2;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export const binomialFilterConfig = {
|
|
68
|
-
//: KernelConfig
|
|
69
|
-
kernelName: "BinomialFilter",
|
|
70
|
-
backendName: "webgl",
|
|
71
|
-
kernelFunc: binomialFilter, // as {} as KernelFunc,
|
|
72
|
-
};
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { engine } from "@tensorflow/tfjs";
|
|
2
|
-
|
|
3
|
-
const FREAK_EXPANSION_FACTOR = 7.0;
|
|
4
|
-
|
|
5
|
-
const LAPLACIAN_THRESHOLD = 3.0;
|
|
6
|
-
const LAPLACIAN_SQR_THRESHOLD = LAPLACIAN_THRESHOLD * LAPLACIAN_THRESHOLD;
|
|
7
|
-
|
|
8
|
-
const EDGE_THRESHOLD = 4.0;
|
|
9
|
-
const EDGE_HESSIAN_THRESHOLD = ((EDGE_THRESHOLD + 1) * (EDGE_THRESHOLD + 1)) / EDGE_THRESHOLD;
|
|
10
|
-
|
|
11
|
-
const cache = {};
|
|
12
|
-
function GetProgram(image) {
|
|
13
|
-
const imageWidth = image.shape[1];
|
|
14
|
-
const imageHeight = image.shape[0];
|
|
15
|
-
const kernelKey = "w" + imageWidth + "h" + imageHeight;
|
|
16
|
-
if (!cache.hasOwnProperty(kernelKey)) {
|
|
17
|
-
const kernel = {
|
|
18
|
-
variableNames: ["image0", "image1", "image2"],
|
|
19
|
-
outputShape: [imageHeight, imageWidth],
|
|
20
|
-
userCode: `
|
|
21
|
-
void main() {
|
|
22
|
-
ivec2 coords = getOutputCoords();
|
|
23
|
-
|
|
24
|
-
int y = coords[0];
|
|
25
|
-
int x = coords[1];
|
|
26
|
-
|
|
27
|
-
float value = getImage1(y, x);
|
|
28
|
-
|
|
29
|
-
// Step 1: find local maxima/minima
|
|
30
|
-
if (value * value < ${LAPLACIAN_SQR_THRESHOLD}.) {
|
|
31
|
-
setOutput(0.);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (y < ${FREAK_EXPANSION_FACTOR} || y > ${imageHeight - 1 - FREAK_EXPANSION_FACTOR}) {
|
|
35
|
-
setOutput(0.);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (x < ${FREAK_EXPANSION_FACTOR} || x > ${imageWidth - 1 - FREAK_EXPANSION_FACTOR}) {
|
|
39
|
-
setOutput(0.);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
bool isMax = true;
|
|
44
|
-
bool isMin = true;
|
|
45
|
-
for (int dy = -1; dy <= 1; dy++) {
|
|
46
|
-
for (int dx = -1; dx <= 1; dx++) {
|
|
47
|
-
float value0 = getImage0(y+dy, x+dx);
|
|
48
|
-
float value1 = getImage1(y+dy, x+dx);
|
|
49
|
-
float value2 = getImage2(y+dy, x+dx);
|
|
50
|
-
|
|
51
|
-
if (value < value0 || value < value1 || value < value2) {
|
|
52
|
-
isMax = false;
|
|
53
|
-
}
|
|
54
|
-
if (value > value0 || value > value1 || value > value2) {
|
|
55
|
-
isMin = false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!isMax && !isMin) {
|
|
61
|
-
setOutput(0.);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// compute edge score and reject based on threshold
|
|
66
|
-
float dxx = getImage1(y, x+1) + getImage1(y, x-1) - 2. * getImage1(y, x);
|
|
67
|
-
float dyy = getImage1(y+1, x) + getImage1(y-1, x) - 2. * getImage1(y, x);
|
|
68
|
-
float dxy = 0.25 * (getImage1(y-1,x-1) + getImage1(y+1,x+1) - getImage1(y-1,x+1) - getImage1(y+1,x-1));
|
|
69
|
-
|
|
70
|
-
float det = (dxx * dyy) - (dxy * dxy);
|
|
71
|
-
|
|
72
|
-
if (abs(det) < 0.0001) { // determinant undefined. no solution
|
|
73
|
-
setOutput(0.);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
float edgeScore = (dxx + dyy) * (dxx + dyy) / det;
|
|
78
|
-
|
|
79
|
-
if (abs(edgeScore) >= ${EDGE_HESSIAN_THRESHOLD} ) {
|
|
80
|
-
setOutput(0.);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
setOutput(getImage1(y,x));
|
|
84
|
-
}
|
|
85
|
-
`,
|
|
86
|
-
};
|
|
87
|
-
cache[kernelKey] = kernel;
|
|
88
|
-
}
|
|
89
|
-
return cache[kernelKey];
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export const buildExtremas = (args) => {
|
|
93
|
-
let { image0, image1, image2 } = args.inputs;
|
|
94
|
-
/** @type {MathBackendWebGL} */
|
|
95
|
-
const backend = args.backend;
|
|
96
|
-
|
|
97
|
-
const program = GetProgram(image1);
|
|
98
|
-
|
|
99
|
-
image0 = engine().runKernel("DownsampleBilinear", { image: image0 });
|
|
100
|
-
image2 = engine().runKernel("UpsampleBilinear", { image: image2, targetImage: image1 });
|
|
101
|
-
return backend.runWebGLProgram(program, [image0, image1, image2], image1.dtype);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export const buildExtremasConfig = {
|
|
105
|
-
//: KernelConfig
|
|
106
|
-
kernelName: "BuildExtremas",
|
|
107
|
-
backendName: "webgl",
|
|
108
|
-
kernelFunc: buildExtremas, // as {} as KernelFunc,
|
|
109
|
-
};
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
const ORIENTATION_NUM_BINS = 36;
|
|
2
|
-
|
|
3
|
-
const cache = {};
|
|
4
|
-
function GetProgram(histograms) {
|
|
5
|
-
const key = histograms.shape[0];
|
|
6
|
-
if (!cache.hasOwnProperty(key)) {
|
|
7
|
-
const kernel = {
|
|
8
|
-
variableNames: ["histogram"],
|
|
9
|
-
outputShape: [histograms.shape[0]],
|
|
10
|
-
userCode: `
|
|
11
|
-
void main() {
|
|
12
|
-
int featureIndex = getOutputCoords();
|
|
13
|
-
|
|
14
|
-
int maxIndex = 0;
|
|
15
|
-
for (int i = 1; i < ${ORIENTATION_NUM_BINS}; i++) {
|
|
16
|
-
if (getHistogram(featureIndex, i) > getHistogram(featureIndex, maxIndex)) {
|
|
17
|
-
maxIndex = i;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
int prev = imod(maxIndex - 1 + ${ORIENTATION_NUM_BINS}, ${ORIENTATION_NUM_BINS});
|
|
22
|
-
int next = imod(maxIndex + 1, ${ORIENTATION_NUM_BINS});
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Fit a quatratic to 3 points. The system of equations is:
|
|
26
|
-
*
|
|
27
|
-
* y0 = A*x0^2 + B*x0 + C
|
|
28
|
-
* y1 = A*x1^2 + B*x1 + C
|
|
29
|
-
* y2 = A*x2^2 + B*x2 + C
|
|
30
|
-
*
|
|
31
|
-
* This system of equations is solved for A,B,C.
|
|
32
|
-
*/
|
|
33
|
-
float p10 = float(maxIndex - 1);
|
|
34
|
-
float p11 = getHistogram(featureIndex, prev);
|
|
35
|
-
float p20 = float(maxIndex);
|
|
36
|
-
float p21 = getHistogram(featureIndex, maxIndex);
|
|
37
|
-
float p30 = float(maxIndex + 1);
|
|
38
|
-
float p31 = getHistogram(featureIndex, next);
|
|
39
|
-
|
|
40
|
-
float d1 = (p30-p20)*(p30-p10);
|
|
41
|
-
float d2 = (p10-p20)*(p30-p10);
|
|
42
|
-
float d3 = p10-p20;
|
|
43
|
-
|
|
44
|
-
// If any of the denominators are zero then, just use maxIndex.
|
|
45
|
-
float fbin = float(maxIndex);
|
|
46
|
-
if ( abs(d1) > 0.00001 && abs(d2) > 0.00001 && abs(d3) > 0.00001) {
|
|
47
|
-
float a = p10*p10;
|
|
48
|
-
float b = p20*p20;
|
|
49
|
-
|
|
50
|
-
// Solve for the coefficients A,B,C
|
|
51
|
-
float A = ((p31-p21)/d1)-((p11-p21)/d2);
|
|
52
|
-
float B = ((p11-p21)+(A*(b-a)))/d3;
|
|
53
|
-
float C = p11-(A*a)-(B*p10);
|
|
54
|
-
fbin = -B / (2. * A);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
float an = 2.0 *${Math.PI} * (fbin + 0.5) / ${ORIENTATION_NUM_BINS}. - ${Math.PI};
|
|
58
|
-
setOutput(an);
|
|
59
|
-
}
|
|
60
|
-
`,
|
|
61
|
-
};
|
|
62
|
-
cache[key] = kernel;
|
|
63
|
-
}
|
|
64
|
-
return cache[key];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const computeExtremaAngles = (args) => {
|
|
68
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
69
|
-
const { histograms } = args.inputs;
|
|
70
|
-
/** @type {MathBackendWebGL} */
|
|
71
|
-
const backend = args.backend;
|
|
72
|
-
|
|
73
|
-
const program = GetProgram(histograms);
|
|
74
|
-
return backend.runWebGLProgram(program, [histograms], histograms.dtype);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const computeExtremaAnglesConfig = {
|
|
78
|
-
//: KernelConfig
|
|
79
|
-
kernelName: "ComputeExtremaAngles",
|
|
80
|
-
backendName: "webgl",
|
|
81
|
-
kernelFunc: computeExtremaAngles, // as {} as KernelFunc,
|
|
82
|
-
};
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { FREAKPOINTS } from "../../freak.js";
|
|
2
|
-
|
|
3
|
-
const FREAK_EXPANSION_FACTOR = 7.0;
|
|
4
|
-
const cache = {};
|
|
5
|
-
function GetProgram(imageCount, prunedExtremas) {
|
|
6
|
-
const key = `${imageCount}|${prunedExtremas.shape[0]}`;
|
|
7
|
-
if (!cache.hasOwnProperty(key)) {
|
|
8
|
-
const imageVariableNames = [];
|
|
9
|
-
for (let i = 1; i < imageCount; i++) {
|
|
10
|
-
imageVariableNames.push("image" + i);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let pixelsSubCodes = `float getPixel(int octave, int y, int x) {`;
|
|
14
|
-
for (let i = 1; i < imageCount; i++) {
|
|
15
|
-
pixelsSubCodes += `
|
|
16
|
-
if (octave == ${i}) {
|
|
17
|
-
return getImage${i}(y, x);
|
|
18
|
-
}
|
|
19
|
-
`;
|
|
20
|
-
}
|
|
21
|
-
pixelsSubCodes += `}`;
|
|
22
|
-
|
|
23
|
-
const kernel = {
|
|
24
|
-
variableNames: [...imageVariableNames, "extrema", "angles", "freakPoints"],
|
|
25
|
-
outputShape: [prunedExtremas.shape[0], FREAKPOINTS.length],
|
|
26
|
-
userCode: `
|
|
27
|
-
${pixelsSubCodes}
|
|
28
|
-
void main() {
|
|
29
|
-
ivec2 coords = getOutputCoords();
|
|
30
|
-
int featureIndex = coords[0];
|
|
31
|
-
int freakIndex = coords[1];
|
|
32
|
-
|
|
33
|
-
float freakSigma = getFreakPoints(freakIndex, 0);
|
|
34
|
-
float freakX = getFreakPoints(freakIndex, 1);
|
|
35
|
-
float freakY = getFreakPoints(freakIndex, 2);
|
|
36
|
-
|
|
37
|
-
int octave = int(getExtrema(featureIndex, 1));
|
|
38
|
-
float inputY = getExtrema(featureIndex, 2);
|
|
39
|
-
float inputX = getExtrema(featureIndex, 3);
|
|
40
|
-
float inputAngle = getAngles(featureIndex);
|
|
41
|
-
float cos = ${FREAK_EXPANSION_FACTOR}. * cos(inputAngle);
|
|
42
|
-
float sin = ${FREAK_EXPANSION_FACTOR}. * sin(inputAngle);
|
|
43
|
-
|
|
44
|
-
float yp = inputY + freakX * sin + freakY * cos;
|
|
45
|
-
float xp = inputX + freakX * cos + freakY * -sin;
|
|
46
|
-
|
|
47
|
-
int x0 = int(floor(xp));
|
|
48
|
-
int x1 = x0 + 1;
|
|
49
|
-
int y0 = int(floor(yp));
|
|
50
|
-
int y1 = y0 + 1;
|
|
51
|
-
|
|
52
|
-
float f1 = getPixel(octave, y0, x0);
|
|
53
|
-
float f2 = getPixel(octave, y0, x1);
|
|
54
|
-
float f3 = getPixel(octave, y1, x0);
|
|
55
|
-
float f4 = getPixel(octave, y1, x1);
|
|
56
|
-
|
|
57
|
-
float x1f = float(x1);
|
|
58
|
-
float y1f = float(y1);
|
|
59
|
-
float x0f = float(x0);
|
|
60
|
-
float y0f = float(y0);
|
|
61
|
-
|
|
62
|
-
// ratio for interpolation between four neighbouring points
|
|
63
|
-
float value = (x1f - xp) * (y1f - yp) * f1
|
|
64
|
-
+ (xp - x0f) * (y1f - yp) * f2
|
|
65
|
-
+ (x1f - xp) * (yp - y0f) * f3
|
|
66
|
-
+ (xp - x0f) * (yp - y0f) * f4;
|
|
67
|
-
|
|
68
|
-
setOutput(value);
|
|
69
|
-
}
|
|
70
|
-
`,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
cache[key] = kernel;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return cache[key];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export const computeExtremaFreak = (args) => {
|
|
80
|
-
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
81
|
-
const {
|
|
82
|
-
gaussianImagesT,
|
|
83
|
-
prunedExtremas,
|
|
84
|
-
prunedExtremasAngles,
|
|
85
|
-
freakPointsT,
|
|
86
|
-
pyramidImagesLength,
|
|
87
|
-
} = args.inputs;
|
|
88
|
-
/** @type {MathBackendWebGL} */
|
|
89
|
-
const backend = args.backend;
|
|
90
|
-
|
|
91
|
-
const program = GetProgram(pyramidImagesLength, prunedExtremas);
|
|
92
|
-
|
|
93
|
-
return backend.runWebGLProgram(
|
|
94
|
-
program,
|
|
95
|
-
[...gaussianImagesT, prunedExtremas, prunedExtremasAngles, freakPointsT],
|
|
96
|
-
"float32",
|
|
97
|
-
);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export const computeExtremaFreakConfig = {
|
|
101
|
-
//: KernelConfig
|
|
102
|
-
kernelName: "ComputeExtremaFreak",
|
|
103
|
-
backendName: "webgl",
|
|
104
|
-
kernelFunc: computeExtremaFreak, // as {} as KernelFunc,
|
|
105
|
-
};
|