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