@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,429 @@
1
+ /**
2
+ * Trying to do normalization before running ICP
3
+ * i.e. make coodinates centroid at origin and avg distance from origin is sqrt(2)
4
+ *
5
+ * can we get rid of projectionTransform, and just do ICP on modelViewTransform?
6
+ *
7
+ * but couldn't make it work yet. Can someone with theoretical knowledge on ICP reach out to help?, particularly Multiview Levenberg-Marquardt ICP
8
+ * I have problem understanding the jacobian and things like that
9
+ *
10
+ */
11
+ import { Matrix, inverse } from "ml-matrix";
12
+ import { applyModelViewProjectionTransform, buildModelViewProjectionTransform, computeScreenCoordiate, } from "./utils.js";
13
+ const TRACKING_THRESH = 5.0; // default
14
+ const K2_FACTOR = 4.0; // Question: should it be relative to the size of the screen instead of hardcoded?
15
+ const ICP_MAX_LOOP = 10;
16
+ const ICP_BREAK_LOOP_ERROR_THRESH = 0.1;
17
+ const ICP_BREAK_LOOP_ERROR_RATIO_THRESH = 0.99;
18
+ const ICP_BREAK_LOOP_ERROR_THRESH2 = 4.0;
19
+ // some temporary/intermediate variables used later. Declare them beforehand to reduce new object allocations
20
+ let mat = [[], [], []];
21
+ let J_U_Xc = [[], []]; // 2x3
22
+ let J_Xc_S = [[], [], []]; // 3x6
23
+ const refineEstimate = ({ initialModelViewTransform, projectionTransform, worldCoords: inWorldCoords, screenCoords: inScreenCoords, }) => {
24
+ const { normalizedCoords: worldCoords, param: worldParam } = normalizePoints(inWorldCoords);
25
+ const { normalizedCoords: screenCoords, param: screenParam } = normalizePoints(inScreenCoords);
26
+ const modelViewProjectionTransform = buildModelViewProjectionTransform(projectionTransform, initialModelViewTransform);
27
+ const normModelViewProjectionTransform = _getNormalizedModelViewTransform(modelViewProjectionTransform, worldParam, screenParam);
28
+ /*
29
+ * porjection matrix
30
+ * [k00, 0, k02]
31
+ * K = [ 0, k11, k12]
32
+ * [ 0, 0, 1]
33
+ *
34
+ * [1/k00, 0, -k02/k00]
35
+ * inv(K) = [ 0, 1/k11, -k12/k11]
36
+ * [ 0, 0, 1]
37
+ *
38
+ *
39
+ * denote modelViewProjectionTransform as A,
40
+ * since A = K * M, M = inv(K) * A
41
+ *
42
+ * [a00 / k00 - a20 * k02/k00, a01 / k00 - k02/k00 * a21, a02 / k00 - k02/k00 * a22, a03 / k00 - k02/k00 * a23]
43
+ * M = [a10 / k11 - a20 * k12/k11, a11 / k11 - k12/k11 * a21, a13 / k11 - k12/k11 * a22, a13 / k11 - k12/111 * a23]
44
+ * [ a20 , a21, a22, a23]
45
+ */
46
+ const a = normModelViewProjectionTransform;
47
+ const k = projectionTransform;
48
+ const normModelViewTransform = [
49
+ [
50
+ a[0][0] / k[0][0] - (a[2][0] * k[0][2]) / k[0][0],
51
+ a[0][1] / k[0][0] - (a[2][1] * k[0][2]) / k[0][0],
52
+ a[0][2] / k[0][0] - (a[2][2] * k[0][2]) / k[0][0],
53
+ a[0][3] / k[0][0] - (a[2][3] * k[0][2]) / k[0][0],
54
+ ],
55
+ [
56
+ a[1][0] / k[1][1] - (a[2][0] * k[1][2]) / k[1][1],
57
+ a[1][1] / k[1][1] - (a[2][1] * k[1][2]) / k[1][1],
58
+ a[1][2] / k[1][1] - (a[2][2] * k[1][2]) / k[1][1],
59
+ a[1][3] / k[1][1] - (a[2][3] * k[1][2]) / k[1][1],
60
+ ],
61
+ [a[2][0], a[2][1], a[2][2], a[2][3]],
62
+ ];
63
+ const inlierProbs = [1.0, 0.8, 0.6, 0.4, 0.0];
64
+ let updatedModelViewTransform = normModelViewTransform;
65
+ let finalModelViewTransform = null;
66
+ for (let i = 0; i < inlierProbs.length; i++) {
67
+ const ret = _doICP({
68
+ initialModelViewTransform: updatedModelViewTransform,
69
+ projectionTransform,
70
+ worldCoords,
71
+ screenCoords,
72
+ inlierProb: inlierProbs[i],
73
+ });
74
+ updatedModelViewTransform = ret.modelViewTransform;
75
+ if (ret.err < TRACKING_THRESH) {
76
+ finalModelViewTransform = updatedModelViewTransform;
77
+ break;
78
+ }
79
+ }
80
+ if (finalModelViewTransform === null)
81
+ return null;
82
+ const denormModelViewTransform = _getDenormalizedModelViewTransform(finalModelViewTransform, worldParam, screenParam);
83
+ return denormModelViewTransform;
84
+ };
85
+ // ICP iteration
86
+ // Question: can someone provide theoretical reference / mathematical proof for the following computations?
87
+ // I'm unable to derive the Jacobian
88
+ const _doICP = ({ initialModelViewTransform, projectionTransform, worldCoords, screenCoords, inlierProb, }) => {
89
+ const isRobustMode = inlierProb < 1;
90
+ let modelViewTransform = initialModelViewTransform;
91
+ let err0 = 0.0;
92
+ let err1 = 0.0;
93
+ let E = new Array(worldCoords.length);
94
+ let E2 = new Array(worldCoords.length);
95
+ let dxs = new Array(worldCoords.length);
96
+ let dys = new Array(worldCoords.length);
97
+ for (let l = 0; l <= ICP_MAX_LOOP; l++) {
98
+ const modelViewProjectionTransform = buildModelViewProjectionTransform(projectionTransform, modelViewTransform);
99
+ for (let n = 0; n < worldCoords.length; n++) {
100
+ const u = computeScreenCoordiate(modelViewProjectionTransform, worldCoords[n].x, worldCoords[n].y, worldCoords[n].z);
101
+ const dx = screenCoords[n].x - u.x;
102
+ const dy = screenCoords[n].y - u.y;
103
+ console.log("icp err", worldCoords[n], u, screenCoords[n]);
104
+ dxs[n] = dx;
105
+ dys[n] = dy;
106
+ E[n] = dx * dx + dy * dy;
107
+ }
108
+ let K2; // robust mode only
109
+ err1 = 0.0;
110
+ if (isRobustMode) {
111
+ const inlierNum = Math.max(3, Math.floor(worldCoords.length * inlierProb) - 1);
112
+ for (let n = 0; n < worldCoords.length; n++) {
113
+ E2[n] = E[n];
114
+ }
115
+ E2.sort((a, b) => {
116
+ return a - b;
117
+ });
118
+ K2 = Math.max(E2[inlierNum] * K2_FACTOR, 16.0);
119
+ for (let n = 0; n < worldCoords.length; n++) {
120
+ if (E2[n] > K2)
121
+ err1 += K2 / 6;
122
+ else
123
+ err1 += (K2 / 6.0) * (1.0 - (1.0 - E2[n] / K2) * (1.0 - E2[n] / K2) * (1.0 - E2[n] / K2));
124
+ }
125
+ }
126
+ else {
127
+ for (let n = 0; n < worldCoords.length; n++) {
128
+ err1 += E[n];
129
+ }
130
+ }
131
+ err1 /= worldCoords.length;
132
+ console.log("icp loop", inlierProb, l, err1);
133
+ if (err1 < ICP_BREAK_LOOP_ERROR_THRESH)
134
+ break;
135
+ //if (l > 0 && err1 < ICP_BREAK_LOOP_ERROR_THRESH2 && err1/err0 > ICP_BREAK_LOOP_ERROR_RATIO_THRESH) break;
136
+ if (l > 0 && err1 / err0 > ICP_BREAK_LOOP_ERROR_RATIO_THRESH)
137
+ break;
138
+ if (l === ICP_MAX_LOOP)
139
+ break;
140
+ err0 = err1;
141
+ const dU = [];
142
+ const allJ_U_S = [];
143
+ for (let n = 0; n < worldCoords.length; n++) {
144
+ if (isRobustMode && E[n] > K2) {
145
+ continue;
146
+ }
147
+ const J_U_S = _getJ_U_S({
148
+ modelViewProjectionTransform,
149
+ modelViewTransform,
150
+ projectionTransform,
151
+ worldCoord: worldCoords[n],
152
+ });
153
+ if (isRobustMode) {
154
+ const W = (1.0 - E[n] / K2) * (1.0 - E[n] / K2);
155
+ for (let j = 0; j < 2; j++) {
156
+ for (let i = 0; i < 6; i++) {
157
+ J_U_S[j][i] *= W;
158
+ }
159
+ }
160
+ dU.push([dxs[n] * W]);
161
+ dU.push([dys[n] * W]);
162
+ }
163
+ else {
164
+ dU.push([dxs[n]]);
165
+ dU.push([dys[n]]);
166
+ }
167
+ for (let i = 0; i < J_U_S.length; i++) {
168
+ allJ_U_S.push(J_U_S[i]);
169
+ }
170
+ }
171
+ const dS = _getDeltaS({ dU, J_U_S: allJ_U_S });
172
+ if (dS === null)
173
+ break;
174
+ modelViewTransform = _updateModelViewTransform({ modelViewTransform, dS });
175
+ }
176
+ return { modelViewTransform, err: err1 };
177
+ };
178
+ const _updateModelViewTransform = ({ modelViewTransform, dS }) => {
179
+ let ra = dS[0] * dS[0] + dS[1] * dS[1] + dS[2] * dS[2];
180
+ let q0, q1, q2;
181
+ if (ra < 0.000001) {
182
+ q0 = 1.0;
183
+ q1 = 0.0;
184
+ q2 = 0.0;
185
+ ra = 0.0;
186
+ }
187
+ else {
188
+ ra = Math.sqrt(ra);
189
+ q0 = dS[0] / ra;
190
+ q1 = dS[1] / ra;
191
+ q2 = dS[2] / ra;
192
+ }
193
+ const cra = Math.cos(ra);
194
+ const sra = Math.sin(ra);
195
+ const one_cra = 1.0 - cra;
196
+ mat[0][0] = q0 * q0 * one_cra + cra;
197
+ mat[0][1] = q0 * q1 * one_cra - q2 * sra;
198
+ mat[0][2] = q0 * q2 * one_cra + q1 * sra;
199
+ mat[0][3] = dS[3];
200
+ mat[1][0] = q1 * q0 * one_cra + q2 * sra;
201
+ mat[1][1] = q1 * q1 * one_cra + cra;
202
+ mat[1][2] = q1 * q2 * one_cra - q0 * sra;
203
+ mat[1][3] = dS[4];
204
+ mat[2][0] = q2 * q0 * one_cra - q1 * sra;
205
+ mat[2][1] = q2 * q1 * one_cra + q0 * sra;
206
+ mat[2][2] = q2 * q2 * one_cra + cra;
207
+ mat[2][3] = dS[5];
208
+ const mat2 = [[], [], []];
209
+ for (let j = 0; j < 3; j++) {
210
+ for (let i = 0; i < 4; i++) {
211
+ mat2[j][i] =
212
+ modelViewTransform[j][0] * mat[0][i] +
213
+ modelViewTransform[j][1] * mat[1][i] +
214
+ modelViewTransform[j][2] * mat[2][i];
215
+ }
216
+ mat2[j][3] += modelViewTransform[j][3];
217
+ }
218
+ return mat2;
219
+ };
220
+ const _getDeltaS = ({ dU, J_U_S }) => {
221
+ const J = new Matrix(J_U_S);
222
+ const U = new Matrix(dU);
223
+ const JT = J.transpose();
224
+ const JTJ = JT.mmul(J);
225
+ const JTU = JT.mmul(U);
226
+ let JTJInv;
227
+ try {
228
+ JTJInv = inverse(JTJ);
229
+ }
230
+ catch (e) {
231
+ return null;
232
+ }
233
+ const S = JTJInv.mmul(JTU);
234
+ return S.to1DArray();
235
+ };
236
+ const _getJ_U_S = ({ modelViewProjectionTransform, modelViewTransform, projectionTransform, worldCoord, }) => {
237
+ const T = modelViewTransform;
238
+ const { x, y, z } = worldCoord;
239
+ const u = applyModelViewProjectionTransform(modelViewProjectionTransform, x, y, z);
240
+ const z2 = u.z * u.z;
241
+ J_U_Xc[0][0] = (projectionTransform[0][0] * u.z - projectionTransform[2][0] * u.x) / z2;
242
+ J_U_Xc[0][1] = (projectionTransform[0][1] * u.z - projectionTransform[2][1] * u.x) / z2;
243
+ J_U_Xc[0][2] = (projectionTransform[0][2] * u.z - projectionTransform[2][2] * u.x) / z2;
244
+ J_U_Xc[1][0] = (projectionTransform[1][0] * u.z - projectionTransform[2][0] * u.y) / z2;
245
+ J_U_Xc[1][1] = (projectionTransform[1][1] * u.z - projectionTransform[2][1] * u.y) / z2;
246
+ J_U_Xc[1][2] = (projectionTransform[1][2] * u.z - projectionTransform[2][2] * u.y) / z2;
247
+ J_Xc_S[0][0] = T[0][2] * y;
248
+ J_Xc_S[0][1] = -T[0][2] * x;
249
+ J_Xc_S[0][2] = T[0][1] * x - T[0][0] * y;
250
+ J_Xc_S[0][3] = T[0][0];
251
+ J_Xc_S[0][4] = T[0][1];
252
+ J_Xc_S[0][5] = T[0][2];
253
+ J_Xc_S[1][0] = T[1][2] * y;
254
+ J_Xc_S[1][1] = -T[1][2] * x;
255
+ J_Xc_S[1][2] = T[1][1] * x - T[1][0] * y;
256
+ J_Xc_S[1][3] = T[1][0];
257
+ J_Xc_S[1][4] = T[1][1];
258
+ J_Xc_S[1][5] = T[1][2];
259
+ J_Xc_S[2][0] = T[2][2] * y;
260
+ J_Xc_S[2][1] = -T[2][2] * x;
261
+ J_Xc_S[2][2] = T[2][1] * x - T[2][0] * y;
262
+ J_Xc_S[2][3] = T[2][0];
263
+ J_Xc_S[2][4] = T[2][1];
264
+ J_Xc_S[2][5] = T[2][2];
265
+ const J_U_S = [[], []];
266
+ for (let j = 0; j < 2; j++) {
267
+ for (let i = 0; i < 6; i++) {
268
+ J_U_S[j][i] = 0.0;
269
+ for (let k = 0; k < 3; k++) {
270
+ J_U_S[j][i] += J_U_Xc[j][k] * J_Xc_S[k][i];
271
+ }
272
+ }
273
+ }
274
+ return J_U_S;
275
+ };
276
+ const _getNormalizedModelViewTransform = (modelViewTransform, worldParam, screenParam) => {
277
+ /*
278
+ * notations:
279
+ * m: modelViewTransform,
280
+ * [x,y,z,1]: world coordinates
281
+ * [x',y',z',1]: screen coordinates
282
+ *
283
+ * By normalizing coordinates with meanX, meanY and scale s, it means to transform the coordinates to
284
+ * note that z doesn't scale up, otherwise screen point doesn't scale, e.g. x' = x / z
285
+ * [s*(x-meanX)]
286
+ * [s*(y-meanY)]
287
+ * [z ]
288
+ * [1 ]
289
+ *
290
+ * Let's define transformation T, such that
291
+ * `normalizedP = T * P`
292
+ *
293
+ * [s * (x - meanX)] [s, 0, 0, -s*meanX] [x]
294
+ * [s * (y - meanY)] = [0, s, 0, -s*meanY] * [y]
295
+ * [z ] [0, 0, 1, 0] [z]
296
+ * [1 ] [0, 0, 0, 1] [1]
297
+ *
298
+ * and `P = inv(T) * normalizedP`
299
+ *
300
+ * [x] [1/s, 0 , 0, meanX] [s * (x - meanX)]
301
+ * [y] = [0 , 1/s, 0, meanY] * [s * (y - meanY)]
302
+ * [z] [0 , 0 , 1, 0] [z ]
303
+ * [1] [0 , 0 , 0, 1] [1 ]
304
+ *
305
+ *
306
+ * Before normalizating coordinates, the following holds:
307
+ * M * P = P' (P is world coordinate, and P' is screen coordinate)
308
+ *
309
+ * -> M * inv(T) * T * P = inv(T') * T' * P'
310
+ * -> T' * M * inv(T) * T * P = T' * P'
311
+ * here, T * P, and T' * P' are normalized coordaintes for world and screen, so, the modelViewTransform for normalized coordinates would be:
312
+ *
313
+ * Mnorm = T' * M * inv(T) =
314
+ *
315
+ * [s', 0, 0, -s'*meanX'] [m00, m01, m02, m03] [1/s, 0, 0, meanX]
316
+ * [ 0, s', 0, -s'*meanY'] * [m10, m11, m12, m13] * [ 0, 1/s, 0, meanY]
317
+ * [ 0, 0, 1, 0] [m20, m21, m22, m23] [ 0, 0, 1, 0]
318
+ * [ 0, 0, 0, 1] [0, 0, 0, 1] [ 0, 0, 0, 1]
319
+ *
320
+ * =
321
+ *
322
+ * [m00 * s'/s, m01 * s'/s, m02 * s', m00*s'*meanX + m01*s'*meanY + m03*s' - meanX'*s']
323
+ * [m10 * s'/s, m11 * s'/s, m12 * s', m10*s'*meanX + m11*s'*meanY + m13*s' - meanY'*s']
324
+ * [m20 / s , m21 / s , m22 , m20 *meanX + m21 *meanY + m23 ]
325
+ * [ 0, 0, 0, 1]
326
+ *
327
+ */
328
+ const m = modelViewTransform;
329
+ const ss = screenParam.s / worldParam.s;
330
+ const normModelViewTransform = [
331
+ [
332
+ m[0][0] * ss,
333
+ m[0][1] * ss,
334
+ m[0][2] * screenParam.s,
335
+ (m[0][0] * worldParam.meanX + m[0][1] * worldParam.meanY + m[0][3] - screenParam.meanX) *
336
+ screenParam.s,
337
+ ],
338
+ [
339
+ m[1][0] * ss,
340
+ m[1][1] * ss,
341
+ m[1][2] * screenParam.s,
342
+ (m[1][0] * worldParam.meanX + m[1][1] * worldParam.meanY + m[1][3] - screenParam.meanY) *
343
+ screenParam.s,
344
+ ],
345
+ [
346
+ m[2][0] / worldParam.s,
347
+ m[2][1] / worldParam.s,
348
+ m[2][2],
349
+ m[2][0] * worldParam.meanX + m[2][1] * worldParam.meanY + m[2][3],
350
+ ],
351
+ ];
352
+ return normModelViewTransform;
353
+ };
354
+ const _getDenormalizedModelViewTransform = (modelViewTransform, worldParam, screenParam) => {
355
+ /*
356
+ * Refer to _getNormalizedModelViewTransform, we have
357
+ *
358
+ * Mnorm = T' * M * inv(T)
359
+ *
360
+ * Therefore,
361
+ *
362
+ * M = inv(T') * Mnorm * T
363
+ *
364
+ * [1/s', 0, 0, meanX'] [m00, m01, m02, m03] [s, 0, 0, -s*meanX]
365
+ * [0 , 1/s', 0, meanY'] * [m10, m11, m12, m13] * [0, s, 0, -s*meanY]
366
+ * [0 , 0 , 1, 0] [m20, m21, m22, m23] [0, 0, 1, 0]
367
+ * [0 , 0 , 0, 1] [0, 0, 0, 1] [0, 0, 0, 1]
368
+ *
369
+ * =
370
+ *
371
+ * [m00*s/s', m01*s/s', m02/s', (-m00*s*meanX -m01*s*meanY+m03)/s' + meanX'],
372
+ * [m10*s/s', m11*s/s', m12/s', (-m10*s*meanX -m11*s*meanY+m13)/s' + meanY'],
373
+ * [m20*s ', m21*s ', m22 , -m20*s*meanX -m21*s*meanY+m23) ],
374
+ * [0 , 0, 0, 1]
375
+ *
376
+ */
377
+ const m = modelViewTransform;
378
+ const ss = worldParam.s / screenParam.s;
379
+ const sMeanX = worldParam.s * worldParam.meanX;
380
+ const sMeanY = worldParam.s * worldParam.meanY;
381
+ const denormModelViewTransform = [
382
+ [
383
+ m[0][0] * ss,
384
+ m[0][1] * ss,
385
+ m[0][2] / screenParam.s,
386
+ (-m[0][0] * sMeanX - m[0][1] * sMeanY + m[0][3]) / screenParam.s + screenParam.meanX,
387
+ ],
388
+ [
389
+ m[1][0] * ss,
390
+ m[1][1] * ss,
391
+ m[1][2] / screenParam.s,
392
+ (-m[1][0] * sMeanX - m[1][1] * sMeanY + m[1][3]) / screenParam.s + screenParam.meanY,
393
+ ],
394
+ [
395
+ m[2][0] * worldParam.s,
396
+ m[2][1] * worldParam.s,
397
+ m[2][2],
398
+ -m[2][0] * sMeanX - m[2][1] * sMeanY + m[2][3],
399
+ ],
400
+ ];
401
+ return denormModelViewTransform;
402
+ };
403
+ // centroid at origin and avg distance from origin is sqrt(2)
404
+ const normalizePoints = (coords) => {
405
+ let sumX = 0;
406
+ let sumY = 0;
407
+ for (let i = 0; i < coords.length; i++) {
408
+ sumX += coords[i].x;
409
+ sumY += coords[i].y;
410
+ }
411
+ let meanX = sumX / coords.length;
412
+ let meanY = sumY / coords.length;
413
+ let sumDiff = 0;
414
+ for (let i = 0; i < coords.length; i++) {
415
+ const diffX = coords[i].x - meanX;
416
+ const diffY = coords[i].y - meanY;
417
+ sumDiff += Math.sqrt(diffX * diffX + diffY * diffY);
418
+ }
419
+ let s = (Math.sqrt(2) * coords.length) / sumDiff;
420
+ const normalizedCoords = [];
421
+ for (let i = 0; i < coords.length; i++) {
422
+ normalizedCoords.push({
423
+ x: (coords[i].x - meanX) * s,
424
+ y: (coords[i].y - meanY) * s,
425
+ });
426
+ }
427
+ return { normalizedCoords, param: { meanX, meanY, s } };
428
+ };
429
+ export { refineEstimate };
@@ -0,0 +1,6 @@
1
+ export function refineEstimate({ initialModelViewTransform, projectionTransform, worldCoords, screenCoords, }: {
2
+ initialModelViewTransform: any;
3
+ projectionTransform: any;
4
+ worldCoords: any;
5
+ screenCoords: any;
6
+ }): never[][] | null;