@srsergio/taptapp-ar 1.0.0
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 +62 -0
- package/dist/compiler/aframe.d.ts +1 -0
- package/dist/compiler/aframe.js +275 -0
- package/dist/compiler/compiler-base.d.ts +12 -0
- package/dist/compiler/compiler-base.js +165 -0
- package/dist/compiler/compiler.d.ts +9 -0
- package/dist/compiler/compiler.js +24 -0
- package/dist/compiler/compiler.worker.d.ts +1 -0
- package/dist/compiler/compiler.worker.js +28 -0
- package/dist/compiler/controller.d.ts +101 -0
- package/dist/compiler/controller.js +400 -0
- package/dist/compiler/controller.worker.d.ts +1 -0
- package/dist/compiler/controller.worker.js +61 -0
- package/dist/compiler/detector/crop-detector.d.ts +65 -0
- package/dist/compiler/detector/crop-detector.js +59 -0
- package/dist/compiler/detector/detector.d.ts +98 -0
- package/dist/compiler/detector/detector.js +1049 -0
- package/dist/compiler/detector/freak.d.ts +1 -0
- package/dist/compiler/detector/freak.js +89 -0
- package/dist/compiler/detector/kernels/cpu/binomialFilter.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/binomialFilter.js +51 -0
- package/dist/compiler/detector/kernels/cpu/buildExtremas.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/buildExtremas.js +89 -0
- package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.d.ts +7 -0
- package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.js +79 -0
- package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.js +68 -0
- package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.js +57 -0
- package/dist/compiler/detector/kernels/cpu/computeLocalization.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/computeLocalization.js +54 -0
- package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.js +118 -0
- package/dist/compiler/detector/kernels/cpu/downsampleBilinear.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/downsampleBilinear.js +29 -0
- package/dist/compiler/detector/kernels/cpu/extremaReduction.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/extremaReduction.js +50 -0
- package/dist/compiler/detector/kernels/cpu/fakeShader.d.ts +20 -0
- package/dist/compiler/detector/kernels/cpu/fakeShader.js +80 -0
- package/dist/compiler/detector/kernels/cpu/index.d.ts +1 -0
- package/dist/compiler/detector/kernels/cpu/index.js +25 -0
- package/dist/compiler/detector/kernels/cpu/prune.d.ts +1 -0
- package/dist/compiler/detector/kernels/cpu/prune.js +103 -0
- package/dist/compiler/detector/kernels/cpu/smoothHistograms.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/smoothHistograms.js +47 -0
- package/dist/compiler/detector/kernels/cpu/upsampleBilinear.d.ts +6 -0
- package/dist/compiler/detector/kernels/cpu/upsampleBilinear.js +43 -0
- package/dist/compiler/detector/kernels/index.d.ts +1 -0
- package/dist/compiler/detector/kernels/index.js +2 -0
- package/dist/compiler/detector/kernels/webgl/binomialFilter.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/binomialFilter.js +67 -0
- package/dist/compiler/detector/kernels/webgl/buildExtremas.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/buildExtremas.js +101 -0
- package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.js +78 -0
- package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.js +86 -0
- package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.js +52 -0
- package/dist/compiler/detector/kernels/webgl/computeLocalization.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/computeLocalization.js +58 -0
- package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.js +116 -0
- package/dist/compiler/detector/kernels/webgl/downsampleBilinear.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/downsampleBilinear.js +46 -0
- package/dist/compiler/detector/kernels/webgl/extremaReduction.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/extremaReduction.js +48 -0
- package/dist/compiler/detector/kernels/webgl/index.d.ts +1 -0
- package/dist/compiler/detector/kernels/webgl/index.js +25 -0
- package/dist/compiler/detector/kernels/webgl/smoothHistograms.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/smoothHistograms.js +49 -0
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.d.ts +6 -0
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.js +56 -0
- package/dist/compiler/estimation/esimate-experiment.d.ts +5 -0
- package/dist/compiler/estimation/esimate-experiment.js +267 -0
- package/dist/compiler/estimation/estimate.d.ts +5 -0
- package/dist/compiler/estimation/estimate.js +51 -0
- package/dist/compiler/estimation/estimator.d.ts +13 -0
- package/dist/compiler/estimation/estimator.js +30 -0
- package/dist/compiler/estimation/refine-estimate-experiment.d.ts +6 -0
- package/dist/compiler/estimation/refine-estimate-experiment.js +429 -0
- package/dist/compiler/estimation/refine-estimate.d.ts +6 -0
- package/dist/compiler/estimation/refine-estimate.js +299 -0
- package/dist/compiler/estimation/utils.d.ts +10 -0
- package/dist/compiler/estimation/utils.js +80 -0
- package/dist/compiler/image-list.d.ts +13 -0
- package/dist/compiler/image-list.js +52 -0
- package/dist/compiler/index.d.ts +3 -0
- package/dist/compiler/index.js +10 -0
- package/dist/compiler/input-loader.d.ts +23 -0
- package/dist/compiler/input-loader.js +88 -0
- package/dist/compiler/matching/hamming-distance.d.ts +1 -0
- package/dist/compiler/matching/hamming-distance.js +20 -0
- package/dist/compiler/matching/hierarchical-clustering.d.ts +7 -0
- package/dist/compiler/matching/hierarchical-clustering.js +109 -0
- package/dist/compiler/matching/hough.d.ts +1 -0
- package/dist/compiler/matching/hough.js +169 -0
- package/dist/compiler/matching/matcher.d.ts +28 -0
- package/dist/compiler/matching/matcher.js +48 -0
- package/dist/compiler/matching/matching.d.ts +41 -0
- package/dist/compiler/matching/matching.js +197 -0
- package/dist/compiler/matching/ransacHomography.d.ts +1 -0
- package/dist/compiler/matching/ransacHomography.js +136 -0
- package/dist/compiler/offline-compiler.d.ts +10 -0
- package/dist/compiler/offline-compiler.js +450 -0
- package/dist/compiler/tensorflow-setup.d.ts +7 -0
- package/dist/compiler/tensorflow-setup.js +73 -0
- package/dist/compiler/three.d.ts +66 -0
- package/dist/compiler/three.js +310 -0
- package/dist/compiler/tracker/extract-utils.d.ts +1 -0
- package/dist/compiler/tracker/extract-utils.js +29 -0
- package/dist/compiler/tracker/extract.d.ts +4 -0
- package/dist/compiler/tracker/extract.js +349 -0
- package/dist/compiler/tracker/tracker.d.ts +38 -0
- package/dist/compiler/tracker/tracker.js +327 -0
- package/dist/compiler/utils/cumsum.d.ts +5 -0
- package/dist/compiler/utils/cumsum.js +39 -0
- package/dist/compiler/utils/geometry.d.ts +8 -0
- package/dist/compiler/utils/geometry.js +101 -0
- package/dist/compiler/utils/homography.d.ts +1 -0
- package/dist/compiler/utils/homography.js +138 -0
- package/dist/compiler/utils/images.d.ts +24 -0
- package/dist/compiler/utils/images.js +99 -0
- package/dist/compiler/utils/randomizer.d.ts +5 -0
- package/dist/compiler/utils/randomizer.js +25 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/react/AREditor.d.ts +5 -0
- package/dist/react/AREditor.js +159 -0
- package/dist/react/ProgressDialog.d.ts +13 -0
- package/dist/react/ProgressDialog.js +57 -0
- package/dist/react/types.d.ts +22 -0
- package/dist/react/types.js +14 -0
- package/package.json +53 -0
- package/src/astro/ARScene.astro +59 -0
- package/src/astro/ARVideoTrigger.astro +73 -0
- package/src/astro/overlays/ErrorOverlay.astro +40 -0
- package/src/astro/overlays/LoadingOverlay.astro +28 -0
- package/src/astro/overlays/ScanningOverlay.astro +119 -0
- package/src/astro/scripts/ARScripts.astro +118 -0
- package/src/astro/styles/ARStyles.astro +147 -0
- package/src/compiler/aframe.js +343 -0
- package/src/compiler/compiler-base.js +195 -0
- package/src/compiler/compiler.js +25 -0
- package/src/compiler/compiler.worker.js +30 -0
- package/src/compiler/controller.js +473 -0
- package/src/compiler/controller.worker.js +77 -0
- package/src/compiler/detector/crop-detector.js +68 -0
- package/src/compiler/detector/detector.js +1130 -0
- package/src/compiler/detector/freak.js +91 -0
- package/src/compiler/detector/kernels/cpu/binomialFilter.js +59 -0
- package/src/compiler/detector/kernels/cpu/buildExtremas.js +108 -0
- package/src/compiler/detector/kernels/cpu/computeExtremaAngles.js +91 -0
- package/src/compiler/detector/kernels/cpu/computeExtremaFreak.js +92 -0
- package/src/compiler/detector/kernels/cpu/computeFreakDescriptors.js +68 -0
- package/src/compiler/detector/kernels/cpu/computeLocalization.js +71 -0
- package/src/compiler/detector/kernels/cpu/computeOrientationHistograms.js +141 -0
- package/src/compiler/detector/kernels/cpu/downsampleBilinear.js +33 -0
- package/src/compiler/detector/kernels/cpu/extremaReduction.js +53 -0
- package/src/compiler/detector/kernels/cpu/fakeShader.js +88 -0
- package/src/compiler/detector/kernels/cpu/index.js +26 -0
- package/src/compiler/detector/kernels/cpu/prune.js +114 -0
- package/src/compiler/detector/kernels/cpu/smoothHistograms.js +57 -0
- package/src/compiler/detector/kernels/cpu/upsampleBilinear.js +51 -0
- package/src/compiler/detector/kernels/index.js +2 -0
- package/src/compiler/detector/kernels/webgl/binomialFilter.js +72 -0
- package/src/compiler/detector/kernels/webgl/buildExtremas.js +109 -0
- package/src/compiler/detector/kernels/webgl/computeExtremaAngles.js +82 -0
- package/src/compiler/detector/kernels/webgl/computeExtremaFreak.js +105 -0
- package/src/compiler/detector/kernels/webgl/computeFreakDescriptors.js +56 -0
- package/src/compiler/detector/kernels/webgl/computeLocalization.js +70 -0
- package/src/compiler/detector/kernels/webgl/computeOrientationHistograms.js +129 -0
- package/src/compiler/detector/kernels/webgl/downsampleBilinear.js +50 -0
- package/src/compiler/detector/kernels/webgl/extremaReduction.js +50 -0
- package/src/compiler/detector/kernels/webgl/index.js +26 -0
- package/src/compiler/detector/kernels/webgl/smoothHistograms.js +53 -0
- package/src/compiler/detector/kernels/webgl/upsampleBilinear.js +62 -0
- package/src/compiler/estimation/esimate-experiment.js +316 -0
- package/src/compiler/estimation/estimate.js +67 -0
- package/src/compiler/estimation/estimator.js +34 -0
- package/src/compiler/estimation/refine-estimate-experiment.js +512 -0
- package/src/compiler/estimation/refine-estimate.js +365 -0
- package/src/compiler/estimation/utils.js +97 -0
- package/src/compiler/image-list.js +62 -0
- package/src/compiler/index.js +13 -0
- package/src/compiler/input-loader.js +107 -0
- package/src/compiler/matching/hamming-distance.js +23 -0
- package/src/compiler/matching/hierarchical-clustering.js +131 -0
- package/src/compiler/matching/hough.js +206 -0
- package/src/compiler/matching/matcher.js +59 -0
- package/src/compiler/matching/matching.js +237 -0
- package/src/compiler/matching/ransacHomography.js +192 -0
- package/src/compiler/offline-compiler.js +553 -0
- package/src/compiler/tensorflow-setup.js +88 -0
- package/src/compiler/three.js +368 -0
- package/src/compiler/tracker/extract-utils.js +34 -0
- package/src/compiler/tracker/extract.js +419 -0
- package/src/compiler/tracker/tracker.js +397 -0
- package/src/compiler/utils/cumsum.js +40 -0
- package/src/compiler/utils/geometry.js +114 -0
- package/src/compiler/utils/homography.js +150 -0
- package/src/compiler/utils/images.js +111 -0
- package/src/compiler/utils/randomizer.js +29 -0
- package/src/index.ts +8 -0
- package/src/react/AREditor.tsx +394 -0
- package/src/react/ProgressDialog.tsx +185 -0
- package/src/react/types.ts +35 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { MathBackendWebGL } from "@tensorflow/tfjs-backend-webgl";
|
|
2
|
+
const cache = {};
|
|
3
|
+
function GetProgram(image, targetImage) {
|
|
4
|
+
const targetImageWidth = targetImage.shape[1];
|
|
5
|
+
const targetImageHeight = targetImage.shape[0];
|
|
6
|
+
const kernelKey = "w" + targetImageWidth + "h" + targetImageHeight;
|
|
7
|
+
if (!cache.hasOwnProperty(kernelKey)) {
|
|
8
|
+
const kernel = {
|
|
9
|
+
variableNames: ["p"],
|
|
10
|
+
outputShape: [targetImageHeight, targetImageWidth],
|
|
11
|
+
userCode: `
|
|
12
|
+
void main() {
|
|
13
|
+
ivec2 coords = getOutputCoords();
|
|
14
|
+
int j = coords[0];
|
|
15
|
+
int i = coords[1];
|
|
16
|
+
|
|
17
|
+
float sj = 0.5 * float(j) - 0.25;
|
|
18
|
+
float si = 0.5 * float(i) - 0.25;
|
|
19
|
+
|
|
20
|
+
float sj0 = floor(sj);
|
|
21
|
+
float sj1 = ceil(sj);
|
|
22
|
+
float si0 = floor(si);
|
|
23
|
+
float si1 = ceil(si);
|
|
24
|
+
|
|
25
|
+
int sj0I = int(sj0);
|
|
26
|
+
int sj1I = int(sj1);
|
|
27
|
+
int si0I = int(si0);
|
|
28
|
+
int si1I = int(si1);
|
|
29
|
+
|
|
30
|
+
float sum = 0.0;
|
|
31
|
+
sum += getP(sj0I, si0I) * (si1 - si) * (sj1 - sj);
|
|
32
|
+
sum += getP(sj1I, si0I) * (si1 - si) * (sj - sj0);
|
|
33
|
+
sum += getP(sj0I, si1I) * (si - si0) * (sj1 - sj);
|
|
34
|
+
sum += getP(sj1I, si1I) * (si - si0) * (sj - sj0);
|
|
35
|
+
setOutput(sum);
|
|
36
|
+
}
|
|
37
|
+
`,
|
|
38
|
+
};
|
|
39
|
+
cache[kernelKey] = kernel;
|
|
40
|
+
}
|
|
41
|
+
return cache[kernelKey];
|
|
42
|
+
}
|
|
43
|
+
export const upsampleBilinear = (args) => {
|
|
44
|
+
/** @type {import('@tensorflow/tfjs').TensorInfo} */
|
|
45
|
+
const { image, targetImage } = args.inputs;
|
|
46
|
+
/** @type {MathBackendWebGL} */
|
|
47
|
+
const backend = args.backend;
|
|
48
|
+
const program = GetProgram(image, targetImage);
|
|
49
|
+
return backend.runWebGLProgram(program, [image], image.dtype);
|
|
50
|
+
};
|
|
51
|
+
export const upsampleBilinearConfig = {
|
|
52
|
+
//: KernelConfig
|
|
53
|
+
kernelName: "UpsampleBilinear",
|
|
54
|
+
backendName: "webgl",
|
|
55
|
+
kernelFunc: upsampleBilinear, // as {} as KernelFunc,
|
|
56
|
+
};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// try to implement https://hal.inria.fr/inria-00174036/PDF/RR-6303.pdf
|
|
2
|
+
import { Matrix, inverse } from "ml-matrix";
|
|
3
|
+
import { SVD } from "svd-js";
|
|
4
|
+
import { solveHomography } from "../utils/homography";
|
|
5
|
+
import { computeScreenCoordiate } from "./utils";
|
|
6
|
+
const opposites_of_minors = (M, row, col) => {
|
|
7
|
+
let x1 = col === 0 ? 1 : 0;
|
|
8
|
+
let x2 = col === 2 ? 1 : 2;
|
|
9
|
+
let y1 = row === 0 ? 1 : 0;
|
|
10
|
+
let y2 = row === 2 ? 1 : 2;
|
|
11
|
+
return M[y1][x2] * M[y2][x1] - M[y1][x1] * M[y2][x2];
|
|
12
|
+
};
|
|
13
|
+
const findRmatFrom_tstar_n = (H, tstar, n, v) => {
|
|
14
|
+
// computes R = H( I - (2/v)*te_star*ne_t )
|
|
15
|
+
const twoDivV = 2 / v;
|
|
16
|
+
const tmp = [
|
|
17
|
+
[1 - twoDivV * tstar[0] * n[0], 0 - twoDivV * tstar[0] * n[1], 0 - twoDivV * tstar[0] * n[2]],
|
|
18
|
+
[0 - twoDivV * tstar[1] * n[0], 1 - twoDivV * tstar[1] * n[1], 0 - twoDivV * tstar[1] * n[2]],
|
|
19
|
+
[0 - twoDivV * tstar[2] * n[0], 0 - twoDivV * tstar[2] * n[1], 1 - twoDivV * tstar[2] * n[2]],
|
|
20
|
+
];
|
|
21
|
+
const R = [
|
|
22
|
+
[0, 0, 0],
|
|
23
|
+
[0, 0, 0],
|
|
24
|
+
[0, 0, 0],
|
|
25
|
+
];
|
|
26
|
+
for (let i = 0; i < 3; i++) {
|
|
27
|
+
for (let j = 0; j < 3; j++) {
|
|
28
|
+
for (let k = 0; k < 3; k++) {
|
|
29
|
+
R[i][j] += H[i][k] * tmp[k][j];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//const R = H.mmul( new Matrix(tmp));
|
|
34
|
+
return R;
|
|
35
|
+
};
|
|
36
|
+
const estimate = ({ screenCoords, worldCoords, projectionTransform }) => {
|
|
37
|
+
const Harray = solveHomography(worldCoords.map((p) => [p.x, p.y]), screenCoords.map((p) => [p.x, p.y]));
|
|
38
|
+
const G = new Matrix([
|
|
39
|
+
[Harray[0], Harray[1], Harray[2]],
|
|
40
|
+
[Harray[3], Harray[4], Harray[5]],
|
|
41
|
+
[Harray[6], Harray[7], Harray[8]],
|
|
42
|
+
]);
|
|
43
|
+
const K = new Matrix(projectionTransform);
|
|
44
|
+
const KInv = inverse(K);
|
|
45
|
+
const KInvArr = KInv.to2DArray();
|
|
46
|
+
const KArr = K.to2DArray();
|
|
47
|
+
const Hhat = KInv.mmul(G).mmul(K);
|
|
48
|
+
const { q } = SVD(Hhat.to2DArray());
|
|
49
|
+
const H = Hhat.div(q[1]);
|
|
50
|
+
const HTH = H.transpose().mmul(H);
|
|
51
|
+
const S = Matrix.sub(HTH, Matrix.eye(3, 3)).to2DArray();
|
|
52
|
+
console.log("G", G);
|
|
53
|
+
console.log("svd q", q);
|
|
54
|
+
console.log("Hhat", Hhat);
|
|
55
|
+
console.log("H", H);
|
|
56
|
+
console.log("HTH", HTH);
|
|
57
|
+
console.log("S", S);
|
|
58
|
+
// M00, M11, M22
|
|
59
|
+
const M00 = opposites_of_minors(S, 0, 0);
|
|
60
|
+
const M11 = opposites_of_minors(S, 1, 1);
|
|
61
|
+
const M22 = opposites_of_minors(S, 2, 2);
|
|
62
|
+
const rtM00 = Math.sqrt(M00);
|
|
63
|
+
const rtM11 = Math.sqrt(M11);
|
|
64
|
+
const rtM22 = Math.sqrt(M22);
|
|
65
|
+
// M01, M12, M02
|
|
66
|
+
const M01 = opposites_of_minors(S, 0, 1);
|
|
67
|
+
const e01 = M01 >= 0 ? 1 : -1;
|
|
68
|
+
const M12 = opposites_of_minors(S, 1, 2);
|
|
69
|
+
const e12 = M12 >= 0 ? 1 : -1;
|
|
70
|
+
const M02 = opposites_of_minors(S, 0, 2);
|
|
71
|
+
const e02 = M02 >= 0 ? 1 : -1;
|
|
72
|
+
let maxIndex = 0;
|
|
73
|
+
if (Math.abs(S[1][1]) > Math.abs(S[maxIndex][maxIndex]))
|
|
74
|
+
maxIndex = 1;
|
|
75
|
+
if (Math.abs(S[2][2]) > Math.abs(S[maxIndex][maxIndex]))
|
|
76
|
+
maxIndex = 2;
|
|
77
|
+
console.log("rtM00", rtM00, rtM11, rtM22);
|
|
78
|
+
console.log("M01", M01, M12, M02, e01, e12, e02);
|
|
79
|
+
let npa = [0, 0, 0];
|
|
80
|
+
let npb = [0, 0, 0];
|
|
81
|
+
console.log("max index", maxIndex);
|
|
82
|
+
if (maxIndex === 0) {
|
|
83
|
+
npa[0] = npb[0] = S[0][0];
|
|
84
|
+
npa[1] = S[0][1] + rtM22;
|
|
85
|
+
npb[1] = S[0][1] - rtM22;
|
|
86
|
+
npa[2] = S[0][2] + e12 * rtM11;
|
|
87
|
+
npb[2] = S[0][2] - e12 * rtM11;
|
|
88
|
+
}
|
|
89
|
+
else if (maxIndex === 1) {
|
|
90
|
+
npa[0] = S[0][1] + rtM22;
|
|
91
|
+
npb[0] = S[0][1] - rtM22;
|
|
92
|
+
npa[1] = npb[1] = S[1][1];
|
|
93
|
+
npa[2] = S[1][2] - e02 * rtM00;
|
|
94
|
+
npb[2] = S[1][2] + e02 * rtM00;
|
|
95
|
+
}
|
|
96
|
+
else if (maxIndex === 2) {
|
|
97
|
+
npa[0] = S[0][2] + e01 * rtM11;
|
|
98
|
+
npb[0] = S[0][2] - e01 * rtM11;
|
|
99
|
+
npa[1] = S[1][2] + rtM00;
|
|
100
|
+
npb[1] = S[1][2] - rtM00;
|
|
101
|
+
npa[2] = npb[2] = S[2][2];
|
|
102
|
+
}
|
|
103
|
+
console.log("npa", npa);
|
|
104
|
+
console.log("npb", npb);
|
|
105
|
+
const traceS = S[0][0] + S[1][1] + S[2][2];
|
|
106
|
+
const v = 2.0 * Math.sqrt(1 + traceS - M00 - M11 - M22);
|
|
107
|
+
const ESii = S[maxIndex][maxIndex] >= 0 ? 1 : -1;
|
|
108
|
+
const r_2 = 2 + traceS + v;
|
|
109
|
+
const nt_2 = 2 + traceS - v;
|
|
110
|
+
const r = Math.sqrt(r_2);
|
|
111
|
+
const n_t = Math.sqrt(nt_2);
|
|
112
|
+
console.log("r n_t", r, n_t);
|
|
113
|
+
const npaNorm = Math.sqrt(npa[0] * npa[0] + npa[1] * npa[1] + npa[2] * npa[2]);
|
|
114
|
+
const npbNorm = Math.sqrt(npb[0] * npb[0] + npb[1] * npb[1] + npb[2] * npb[2]);
|
|
115
|
+
const na = [npa[0] / npaNorm, npa[1] / npaNorm, npa[2] / npaNorm];
|
|
116
|
+
const nb = [npb[0] / npbNorm, npb[1] / npbNorm, npb[2] / npbNorm];
|
|
117
|
+
console.log("na nb", na, nb);
|
|
118
|
+
const half_nt = 0.5 * n_t;
|
|
119
|
+
const esii_t_r = ESii * r;
|
|
120
|
+
const ta_star = [];
|
|
121
|
+
for (let i = 0; i < 3; i++) {
|
|
122
|
+
ta_star[i] = half_nt * (esii_t_r * nb[i] - n_t * na[i]);
|
|
123
|
+
}
|
|
124
|
+
const tb_star = [];
|
|
125
|
+
for (let i = 0; i < 3; i++) {
|
|
126
|
+
tb_star[i] = half_nt * (esii_t_r * na[i] - n_t * nb[i]);
|
|
127
|
+
}
|
|
128
|
+
const HArr = H.to2DArray();
|
|
129
|
+
console.log("ta_star", ta_star, tb_star);
|
|
130
|
+
/*
|
|
131
|
+
"""solutions = []
|
|
132
|
+
# Ra, ta
|
|
133
|
+
R = findRmatFrom_tstar_n(H, ta_star, na, v)
|
|
134
|
+
t = R.dot(ta_star)
|
|
135
|
+
solutions.append((R, t, na))
|
|
136
|
+
# Ra, -ta
|
|
137
|
+
solutions.append((R, -t, -na))
|
|
138
|
+
# Rb, tb
|
|
139
|
+
R = findRmatFrom_tstar_n(H, tb_star, nb, v)
|
|
140
|
+
t = R.dot(tb_star)
|
|
141
|
+
solutions.append((R, t, nb))
|
|
142
|
+
# Rb, -tb
|
|
143
|
+
solutions.append((R, -t, -nb))
|
|
144
|
+
*/
|
|
145
|
+
const findT = (R1, ta_star) => {
|
|
146
|
+
const t = [
|
|
147
|
+
R1[0][0] * ta_star[0] + R1[0][1] * ta_star[1] + R1[0][2] * ta_star[2],
|
|
148
|
+
R1[1][0] * ta_star[0] + R1[1][1] * ta_star[1] + R1[1][2] * ta_star[2],
|
|
149
|
+
R1[2][0] * ta_star[0] + R1[2][1] * ta_star[1] + R1[2][2] * ta_star[2],
|
|
150
|
+
];
|
|
151
|
+
return t;
|
|
152
|
+
};
|
|
153
|
+
const Ra = findRmatFrom_tstar_n(HArr, ta_star, na, v);
|
|
154
|
+
const ta = findT(Ra, ta_star);
|
|
155
|
+
const nta = [-ta[0], -ta[1], -ta[2]];
|
|
156
|
+
console.log("RaTRa", new Matrix(Ra).transpose().mmul(new Matrix(Ra)));
|
|
157
|
+
const Rb = findRmatFrom_tstar_n(HArr, tb_star, nb, v);
|
|
158
|
+
const tb = findT(Rb, tb_star);
|
|
159
|
+
const ntb = [-tb[0], -tb[1], -tb[2]];
|
|
160
|
+
const findModelViewProjectionTransform = (R, t) => {
|
|
161
|
+
const transform = [
|
|
162
|
+
[R[0][0], R[0][1], R[0][2], t[0]],
|
|
163
|
+
[R[1][0], R[1][1], R[1][2], t[1]],
|
|
164
|
+
[R[2][0], R[2][1], R[2][2], t[2]],
|
|
165
|
+
];
|
|
166
|
+
return transform;
|
|
167
|
+
const modelViewProjectionTransform = [[], [], []];
|
|
168
|
+
for (let j = 0; j < 3; j++) {
|
|
169
|
+
for (let i = 0; i < 4; i++) {
|
|
170
|
+
modelViewProjectionTransform[j][i] =
|
|
171
|
+
KArr[j][0] * transform[0][i] +
|
|
172
|
+
KArr[j][1] * transform[1][i] +
|
|
173
|
+
KArr[j][2] * transform[2][i];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return modelViewProjectionTransform;
|
|
177
|
+
};
|
|
178
|
+
console.log("Ra ta", Ra, ta);
|
|
179
|
+
console.log("Rb tb", Rb, tb);
|
|
180
|
+
const tnT = new Matrix([
|
|
181
|
+
[ta[0] * na[0], ta[0] * na[1], ta[0] * na[2]],
|
|
182
|
+
[ta[1] * na[0], ta[1] * na[1], ta[1] * na[2]],
|
|
183
|
+
[ta[2] * na[0], ta[2] * na[1], ta[2] * na[2]],
|
|
184
|
+
]);
|
|
185
|
+
const RtnT = new Matrix(Ra).add(tnT);
|
|
186
|
+
console.log("tnT", tnT);
|
|
187
|
+
console.log("RtnT", RtnT);
|
|
188
|
+
const modelViewProjectionTransforms = [];
|
|
189
|
+
modelViewProjectionTransforms.push(findModelViewProjectionTransform(Ra, ta));
|
|
190
|
+
modelViewProjectionTransforms.push(findModelViewProjectionTransform(Ra, nta));
|
|
191
|
+
modelViewProjectionTransforms.push(findModelViewProjectionTransform(Rb, tb));
|
|
192
|
+
modelViewProjectionTransforms.push(findModelViewProjectionTransform(Rb, ntb));
|
|
193
|
+
const applyMatrix = (K, pt) => {
|
|
194
|
+
let kx = K[0][0] * pt[0] + K[0][1] * pt[1] + K[0][2];
|
|
195
|
+
let ky = K[1][0] * pt[0] + K[1][1] * pt[1] + K[1][2];
|
|
196
|
+
let kz = K[2][0] * pt[0] + K[2][1] * pt[1] + K[2][2];
|
|
197
|
+
kx /= kz;
|
|
198
|
+
ky /= kz;
|
|
199
|
+
return [kx, ky];
|
|
200
|
+
};
|
|
201
|
+
for (let s = 0; s < modelViewProjectionTransforms.length; s++) {
|
|
202
|
+
console.log("solution", s);
|
|
203
|
+
const modelViewProjectionTransform = modelViewProjectionTransforms[s];
|
|
204
|
+
for (let i = 0; i < worldCoords.length; i++) {
|
|
205
|
+
let world = applyMatrix(KInvArr, [worldCoords[i].x, worldCoords[i].y]);
|
|
206
|
+
let world2 = applyMatrix(RtnT.to2DArray(), world);
|
|
207
|
+
let screen = applyMatrix(KInvArr, [screenCoords[i].x, screenCoords[i].y]);
|
|
208
|
+
console.log("map", worldCoords[i], screenCoords[i]);
|
|
209
|
+
console.log("mapped", world, world2, screen);
|
|
210
|
+
//const mapped = computeScreenCoordiate(modelViewProjectionTransform, worldCoords[i].x, worldCoords[i].y, 0);
|
|
211
|
+
//console.log("mapped", worldCoords[i], screenCoords[i], mapped);
|
|
212
|
+
//console.log("mapped", worldCoords[i], screenCoords[i], kx2, ky2, mapped);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
for (let s = 0; s < modelViewProjectionTransforms.length; s++) {
|
|
216
|
+
console.log("mvp solution", s);
|
|
217
|
+
const modelViewProjectionTransform = modelViewProjectionTransforms[s];
|
|
218
|
+
for (let i = 0; i < worldCoords.length; i++) {
|
|
219
|
+
let world = applyMatrix(KInvArr, [worldCoords[i].x, worldCoords[i].y]);
|
|
220
|
+
let screen = applyMatrix(KInvArr, [screenCoords[i].x, screenCoords[i].y]);
|
|
221
|
+
//const mapped = computeScreenCoordiate(modelViewProjectionTransform, worldCoords[i].x, worldCoords[i].y, 0);
|
|
222
|
+
const mapped = computeScreenCoordiate(modelViewProjectionTransform, world[0], world[1], 0);
|
|
223
|
+
console.log("mapped", worldCoords[i], screenCoords[i], world, screen, mapped);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
/*
|
|
228
|
+
|
|
229
|
+
const R1 = findRmatFrom_tstar_n(HArr, ta_star, na, v);
|
|
230
|
+
const R2 = findRmatFrom_tstar_n(HArr, tb_star, nb, v);
|
|
231
|
+
console.log("R1", R1);
|
|
232
|
+
console.log("R2", R2);
|
|
233
|
+
|
|
234
|
+
const t = [
|
|
235
|
+
R1[0][0] * ta_star[0] + R1[0][1] * ta_star[1] + R1[0][2] * ta_star[2],
|
|
236
|
+
R1[1][0] * ta_star[0] + R1[1][1] * ta_star[1] + R1[1][2] * ta_star[2],
|
|
237
|
+
R1[2][0] * ta_star[0] + R1[2][1] * ta_star[1] + R1[2][2] * ta_star[2]
|
|
238
|
+
]
|
|
239
|
+
|
|
240
|
+
const R = R2;
|
|
241
|
+
|
|
242
|
+
const modelViewProjectionTransform = [
|
|
243
|
+
[R[0][0], R[0][1], R[0][2], t[0]],
|
|
244
|
+
[R[1][0], R[1][1], R[1][2], t[0]],
|
|
245
|
+
[R[2][0], R[2][1], R[2][2], t[0]],
|
|
246
|
+
];
|
|
247
|
+
*/
|
|
248
|
+
for (let i = 0; i < worldCoords.length; i++) {
|
|
249
|
+
const mapped = computeScreenCoordiate(modelViewProjectionTransform, worldCoords[i].x, worldCoords[i].y, 0);
|
|
250
|
+
console.log("mapped", worldCoords[i], screenCoords[i], mapped);
|
|
251
|
+
}
|
|
252
|
+
// this is the full computation if the projectTransform does not look like the expected format, but more computations
|
|
253
|
+
const modelViewTransform = [[], [], []];
|
|
254
|
+
for (let j = 0; j < 3; j++) {
|
|
255
|
+
for (let i = 0; i < 4; i++) {
|
|
256
|
+
modelViewTransform[j][i] =
|
|
257
|
+
KInvArr[j][0] * modelViewProjectionTransform[0][i] +
|
|
258
|
+
KInvArr[j][1] * modelViewProjectionTransform[1][i] +
|
|
259
|
+
KInvArr[j][2] * modelViewProjectionTransform[2][i];
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
console.log("KInvArr", KInvArr);
|
|
263
|
+
console.log("modelViewProjectionTransform", modelViewProjectionTransform);
|
|
264
|
+
console.log("modelViewTransform", modelViewTransform);
|
|
265
|
+
return modelViewTransform;
|
|
266
|
+
};
|
|
267
|
+
export { estimate };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Matrix, inverse } from "ml-matrix";
|
|
2
|
+
import { solveHomography } from "../utils/homography.js";
|
|
3
|
+
// build world matrix with list of matching worldCoords|screenCoords
|
|
4
|
+
//
|
|
5
|
+
// Step 1. estimate homography with list of pairs
|
|
6
|
+
// Ref: https://www.uio.no/studier/emner/matnat/its/TEK5030/v19/lect/lecture_4_3-estimating-homographies-from-feature-correspondences.pdf (Basic homography estimation from points)
|
|
7
|
+
//
|
|
8
|
+
// Step 2. decompose homography into rotation and translation matrixes (i.e. world matrix)
|
|
9
|
+
// Ref: can anyone provide reference?
|
|
10
|
+
const estimate = ({ screenCoords, worldCoords, projectionTransform }) => {
|
|
11
|
+
const Harray = solveHomography(worldCoords.map((p) => [p.x, p.y]), screenCoords.map((p) => [p.x, p.y]));
|
|
12
|
+
const H = new Matrix([
|
|
13
|
+
[Harray[0], Harray[1], Harray[2]],
|
|
14
|
+
[Harray[3], Harray[4], Harray[5]],
|
|
15
|
+
[Harray[6], Harray[7], Harray[8]],
|
|
16
|
+
]);
|
|
17
|
+
const K = new Matrix(projectionTransform);
|
|
18
|
+
const KInv = inverse(K);
|
|
19
|
+
const _KInvH = KInv.mmul(H);
|
|
20
|
+
const KInvH = _KInvH.to1DArray();
|
|
21
|
+
const norm1 = Math.sqrt(KInvH[0] * KInvH[0] + KInvH[3] * KInvH[3] + KInvH[6] * KInvH[6]);
|
|
22
|
+
const norm2 = Math.sqrt(KInvH[1] * KInvH[1] + KInvH[4] * KInvH[4] + KInvH[7] * KInvH[7]);
|
|
23
|
+
const tnorm = (norm1 + norm2) / 2;
|
|
24
|
+
const rotate = [];
|
|
25
|
+
rotate[0] = KInvH[0] / norm1;
|
|
26
|
+
rotate[3] = KInvH[3] / norm1;
|
|
27
|
+
rotate[6] = KInvH[6] / norm1;
|
|
28
|
+
rotate[1] = KInvH[1] / norm2;
|
|
29
|
+
rotate[4] = KInvH[4] / norm2;
|
|
30
|
+
rotate[7] = KInvH[7] / norm2;
|
|
31
|
+
rotate[2] = rotate[3] * rotate[7] - rotate[6] * rotate[4];
|
|
32
|
+
rotate[5] = rotate[6] * rotate[1] - rotate[0] * rotate[7];
|
|
33
|
+
rotate[8] = rotate[0] * rotate[4] - rotate[1] * rotate[3];
|
|
34
|
+
const norm3 = Math.sqrt(rotate[2] * rotate[2] + rotate[5] * rotate[5] + rotate[8] * rotate[8]);
|
|
35
|
+
rotate[2] /= norm3;
|
|
36
|
+
rotate[5] /= norm3;
|
|
37
|
+
rotate[8] /= norm3;
|
|
38
|
+
// TODO: artoolkit has check_rotation() that somehow switch the rotate vector. not sure what that does. Can anyone advice?
|
|
39
|
+
// https://github.com/artoolkitx/artoolkit5/blob/5bf0b671ff16ead527b9b892e6aeb1a2771f97be/lib/SRC/ARICP/icpUtil.c#L215
|
|
40
|
+
const tran = [];
|
|
41
|
+
tran[0] = KInvH[2] / tnorm;
|
|
42
|
+
tran[1] = KInvH[5] / tnorm;
|
|
43
|
+
tran[2] = KInvH[8] / tnorm;
|
|
44
|
+
let initialModelViewTransform = [
|
|
45
|
+
[rotate[0], rotate[1], rotate[2], tran[0]],
|
|
46
|
+
[rotate[3], rotate[4], rotate[5], tran[1]],
|
|
47
|
+
[rotate[6], rotate[7], rotate[8], tran[2]],
|
|
48
|
+
];
|
|
49
|
+
return initialModelViewTransform;
|
|
50
|
+
};
|
|
51
|
+
export { estimate };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class Estimator {
|
|
2
|
+
constructor(projectionTransform: any);
|
|
3
|
+
projectionTransform: any;
|
|
4
|
+
estimate({ screenCoords, worldCoords }: {
|
|
5
|
+
screenCoords: any;
|
|
6
|
+
worldCoords: any;
|
|
7
|
+
}): number[][];
|
|
8
|
+
refineEstimate({ initialModelViewTransform, worldCoords, screenCoords }: {
|
|
9
|
+
initialModelViewTransform: any;
|
|
10
|
+
worldCoords: any;
|
|
11
|
+
screenCoords: any;
|
|
12
|
+
}): never[][] | null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { estimate } from "./estimate.js";
|
|
2
|
+
import { refineEstimate } from "./refine-estimate.js";
|
|
3
|
+
class Estimator {
|
|
4
|
+
constructor(projectionTransform) {
|
|
5
|
+
this.projectionTransform = projectionTransform;
|
|
6
|
+
}
|
|
7
|
+
// Solve homography between screen points and world points using Direct Linear Transformation
|
|
8
|
+
// then decompose homography into rotation and translation matrix (i.e. modelViewTransform)
|
|
9
|
+
estimate({ screenCoords, worldCoords }) {
|
|
10
|
+
const modelViewTransform = estimate({
|
|
11
|
+
screenCoords,
|
|
12
|
+
worldCoords,
|
|
13
|
+
projectionTransform: this.projectionTransform,
|
|
14
|
+
});
|
|
15
|
+
return modelViewTransform;
|
|
16
|
+
}
|
|
17
|
+
// Given an initial guess of the modelViewTransform and new pairs of screen-world coordinates,
|
|
18
|
+
// use Iterative Closest Point to refine the transformation
|
|
19
|
+
//refineEstimate({initialModelViewTransform, screenCoords, worldCoords}) {
|
|
20
|
+
refineEstimate({ initialModelViewTransform, worldCoords, screenCoords }) {
|
|
21
|
+
const updatedModelViewTransform = refineEstimate({
|
|
22
|
+
initialModelViewTransform,
|
|
23
|
+
worldCoords,
|
|
24
|
+
screenCoords,
|
|
25
|
+
projectionTransform: this.projectionTransform,
|
|
26
|
+
});
|
|
27
|
+
return updatedModelViewTransform;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export { Estimator };
|