@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,327 @@
1
+ import * as tf from "@tensorflow/tfjs";
2
+ import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../estimation/utils.js";
3
+ const AR2_DEFAULT_TS = 6;
4
+ const AR2_DEFAULT_TS_GAP = 1;
5
+ const AR2_SEARCH_SIZE = 10;
6
+ const AR2_SEARCH_GAP = 1;
7
+ const AR2_SIM_THRESH = 0.8;
8
+ const TRACKING_KEYFRAME = 1; // 0: 256px, 1: 128px
9
+ // For some mobile device, only 16bit floating point texture is supported
10
+ // ref: https://www.tensorflow.org/js/guide/platform_environment#precision
11
+ // Empirical results shows that modelViewProjectTransform can go up beyond that, resulting in error
12
+ // We get around this by dividing the transform matrix by 1000, and then multiply back inside webgl program
13
+ const PRECISION_ADJUST = 1000;
14
+ class Tracker {
15
+ constructor(markerDimensions, trackingDataList, projectionTransform, inputWidth, inputHeight, debugMode = false) {
16
+ this.markerDimensions = markerDimensions;
17
+ this.trackingDataList = trackingDataList;
18
+ this.projectionTransform = projectionTransform;
19
+ this.debugMode = debugMode;
20
+ this.trackingKeyframeList = [];
21
+ for (let i = 0; i < trackingDataList.length; i++) {
22
+ this.trackingKeyframeList.push(trackingDataList[i][TRACKING_KEYFRAME]);
23
+ }
24
+ // prebuild feature and marker pixel tensors
25
+ let maxCount = 0;
26
+ for (let i = 0; i < this.trackingKeyframeList.length; i++) {
27
+ maxCount = Math.max(maxCount, this.trackingKeyframeList[i].points.length);
28
+ }
29
+ this.featurePointsListT = [];
30
+ this.imagePixelsListT = [];
31
+ this.imagePropertiesListT = [];
32
+ for (let i = 0; i < this.trackingKeyframeList.length; i++) {
33
+ const { featurePoints, imagePixels, imageProperties } = this._prebuild(this.trackingKeyframeList[i], maxCount);
34
+ this.featurePointsListT[i] = featurePoints;
35
+ this.imagePixelsListT[i] = imagePixels;
36
+ this.imagePropertiesListT[i] = imageProperties;
37
+ }
38
+ this.kernelCaches = {};
39
+ }
40
+ dummyRun(inputT) {
41
+ let transform = [
42
+ [1, 1, 1, 1],
43
+ [1, 1, 1, 1],
44
+ [1, 1, 1, 1],
45
+ ];
46
+ for (let targetIndex = 0; targetIndex < this.featurePointsListT.length; targetIndex++) {
47
+ this.track(inputT, transform, targetIndex);
48
+ }
49
+ }
50
+ track(inputImageT, lastModelViewTransform, targetIndex) {
51
+ let debugExtra = {};
52
+ const modelViewProjectionTransform = buildModelViewProjectionTransform(this.projectionTransform, lastModelViewTransform);
53
+ const modelViewProjectionTransformT = this._buildAdjustedModelViewTransform(modelViewProjectionTransform);
54
+ const markerWidth = this.markerDimensions[targetIndex][0];
55
+ const markerHeight = this.markerDimensions[targetIndex][1];
56
+ const keyframeWidth = this.trackingKeyframeList[targetIndex].width;
57
+ const keyframeHeight = this.trackingKeyframeList[targetIndex].height;
58
+ const featurePointsT = this.featurePointsListT[targetIndex];
59
+ const imagePixelsT = this.imagePixelsListT[targetIndex];
60
+ const imagePropertiesT = this.imagePropertiesListT[targetIndex];
61
+ const projectedImageT = this._computeProjection(modelViewProjectionTransformT, inputImageT, targetIndex);
62
+ const { matchingPointsT, simT } = this._computeMatching(featurePointsT, imagePixelsT, imagePropertiesT, projectedImageT);
63
+ const matchingPoints = matchingPointsT.arraySync();
64
+ const sim = simT.arraySync();
65
+ const trackingFrame = this.trackingKeyframeList[targetIndex];
66
+ const worldCoords = [];
67
+ const screenCoords = [];
68
+ const goodTrack = [];
69
+ for (let i = 0; i < matchingPoints.length; i++) {
70
+ if (sim[i] > AR2_SIM_THRESH && i < trackingFrame.points.length) {
71
+ goodTrack.push(i);
72
+ const point = computeScreenCoordiate(modelViewProjectionTransform, matchingPoints[i][0], matchingPoints[i][1]);
73
+ screenCoords.push(point);
74
+ worldCoords.push({
75
+ x: trackingFrame.points[i].x / trackingFrame.scale,
76
+ y: trackingFrame.points[i].y / trackingFrame.scale,
77
+ z: 0,
78
+ });
79
+ }
80
+ }
81
+ if (this.debugMode) {
82
+ debugExtra = {
83
+ projectedImage: projectedImageT.arraySync(),
84
+ matchingPoints: matchingPointsT.arraySync(),
85
+ goodTrack,
86
+ trackedPoints: screenCoords,
87
+ };
88
+ }
89
+ // tensors cleanup
90
+ modelViewProjectionTransformT.dispose();
91
+ projectedImageT.dispose();
92
+ matchingPointsT.dispose();
93
+ simT.dispose();
94
+ return { worldCoords, screenCoords, debugExtra };
95
+ }
96
+ _computeMatching(featurePointsT, imagePixelsT, imagePropertiesT, projectedImageT) {
97
+ const templateOneSize = AR2_DEFAULT_TS;
98
+ const templateSize = templateOneSize * 2 + 1;
99
+ const templateGap = AR2_DEFAULT_TS_GAP;
100
+ const searchOneSize = AR2_SEARCH_SIZE * templateGap;
101
+ const searchGap = AR2_SEARCH_GAP;
102
+ const searchSize = searchOneSize * 2 + 1;
103
+ const targetHeight = projectedImageT.shape[0];
104
+ const targetWidth = projectedImageT.shape[1];
105
+ const featureCount = featurePointsT.shape[0];
106
+ if (!this.kernelCaches.computeMatching) {
107
+ const kernel1 = {
108
+ variableNames: ["features", "markerPixels", "markerProperties", "targetPixels"],
109
+ outputShape: [featureCount, searchSize * searchSize],
110
+ userCode: `
111
+ void main() {
112
+ ivec2 coords = getOutputCoords();
113
+
114
+ int featureIndex = coords[0];
115
+ int searchOffsetIndex = coords[1];
116
+
117
+ int markerWidth = int(getMarkerProperties(0));
118
+ int markerHeight = int(getMarkerProperties(1));
119
+ float markerScale = getMarkerProperties(2);
120
+
121
+ int searchOffsetX = imod(searchOffsetIndex, ${searchSize}) * ${searchGap};
122
+ int searchOffsetY = searchOffsetIndex / ${searchSize} * ${searchGap};
123
+
124
+ int sCenterX = int(getFeatures(featureIndex, 0) * markerScale);
125
+ int sCenterY = int(getFeatures(featureIndex, 1) * markerScale);
126
+
127
+ int sx = sCenterX + searchOffsetX - ${searchOneSize};
128
+ int sy = sCenterY + searchOffsetY - ${searchOneSize};
129
+
130
+ if (sx < ${templateOneSize} || sx >= (${targetWidth} - ${templateOneSize}) || sy < ${templateOneSize} || sy >= (${targetHeight} - ${templateOneSize})) {
131
+ setOutput(-2.);
132
+ }
133
+ else {
134
+ float sumPoint = 0.;
135
+ float sumPointSquare = 0.;
136
+ float sumTemplate = 0.;
137
+ float sumTemplateSquare = 0.;
138
+ float sumPointTemplate = 0.;
139
+
140
+ for (int templateOffsetY = 0; templateOffsetY < ${templateSize}; templateOffsetY++) {
141
+ for (int templateOffsetX = 0; templateOffsetX < ${templateSize}; templateOffsetX++) {
142
+ int fx2 = sCenterX + templateOffsetX - ${templateOneSize};
143
+ int fy2 = sCenterY + templateOffsetY - ${templateOneSize};
144
+
145
+ int sx2 = sx + templateOffsetX - ${templateOneSize};
146
+ int sy2 = sy + templateOffsetY - ${templateOneSize};
147
+
148
+ int markerPixelIndex = fy2 * markerWidth + fx2;
149
+ float markerPixel = getMarkerPixels(markerPixelIndex);
150
+ float targetPixel = getTargetPixels(sy2, sx2);
151
+
152
+ sumTemplate += markerPixel;
153
+ sumTemplateSquare += markerPixel * markerPixel;
154
+ sumPoint += targetPixel;
155
+ sumPointSquare += targetPixel * targetPixel;
156
+ sumPointTemplate += targetPixel * markerPixel;
157
+ }
158
+ }
159
+
160
+ // Normalized cross-correlation
161
+ // !important divide first avoid overflow (e.g. sumPoint / count * sumPoint)
162
+ float count = float(${templateSize} * ${templateSize});
163
+ float pointVariance = sqrt(sumPointSquare - sumPoint / count * sumPoint);
164
+ float templateVariance = sqrt(sumTemplateSquare - sumTemplate / count * sumTemplate);
165
+
166
+ if (pointVariance < 0.0000001) {
167
+ setOutput(-3.);
168
+ } else if (templateVariance < 0.0000001) {
169
+ //setOutput(sumTemplate);
170
+ setOutput(-4.);
171
+ } else {
172
+ sumPointTemplate -= sumPoint / count * sumTemplate;
173
+ float sim = sumPointTemplate / pointVariance / templateVariance;
174
+ setOutput(sim);
175
+ }
176
+ }
177
+ }
178
+ `,
179
+ };
180
+ const kernel2 = {
181
+ variableNames: ["featurePoints", "markerProperties", "maxIndex"],
182
+ outputShape: [featureCount, 2], // [x, y]
183
+ userCode: `
184
+ void main() {
185
+ ivec2 coords = getOutputCoords();
186
+
187
+ float markerScale = getMarkerProperties(2);
188
+
189
+ int featureIndex = coords[0];
190
+
191
+ int maxIndex = int(getMaxIndex(featureIndex));
192
+ int searchLocationIndex = maxIndex / ${searchSize * searchSize};
193
+ int searchOffsetIndex = imod(maxIndex, ${searchSize * searchSize});
194
+
195
+ if (coords[1] == 0) {
196
+ int searchOffsetX = imod(searchOffsetIndex, ${searchSize}) * ${searchGap};
197
+ setOutput(getFeaturePoints(featureIndex, 0) + float(searchOffsetX - ${searchOneSize}) / markerScale);
198
+ }
199
+ else if (coords[1] == 1) {
200
+ int searchOffsetY = searchOffsetIndex / ${searchSize} * ${searchGap};
201
+ setOutput(getFeaturePoints(featureIndex, 1) + float(searchOffsetY - ${searchOneSize}) / markerScale);
202
+ }
203
+ }
204
+ `,
205
+ };
206
+ const kernel3 = {
207
+ variableNames: ["sims", "maxIndex"],
208
+ outputShape: [featureCount],
209
+ userCode: `
210
+ void main() {
211
+ int featureIndex = getOutputCoords();
212
+ int maxIndex = int(getMaxIndex(featureIndex));
213
+ setOutput(getSims(featureIndex, maxIndex));
214
+ }
215
+ `,
216
+ };
217
+ this.kernelCaches.computeMatching = [kernel1, kernel2, kernel3];
218
+ }
219
+ return tf.tidy(() => {
220
+ const programs = this.kernelCaches.computeMatching;
221
+ const allSims = this._compileAndRun(programs[0], [
222
+ featurePointsT,
223
+ imagePixelsT,
224
+ imagePropertiesT,
225
+ projectedImageT,
226
+ ]);
227
+ const maxIndex = allSims.argMax(1);
228
+ const matchingPointsT = this._compileAndRun(programs[1], [
229
+ featurePointsT,
230
+ imagePropertiesT,
231
+ maxIndex,
232
+ ]);
233
+ const simT = this._compileAndRun(programs[2], [allSims, maxIndex]);
234
+ return { matchingPointsT, simT };
235
+ });
236
+ }
237
+ _computeProjection(modelViewProjectionTransformT, inputImageT, targetIndex) {
238
+ const markerWidth = this.trackingKeyframeList[targetIndex].width;
239
+ const markerHeight = this.trackingKeyframeList[targetIndex].height;
240
+ const markerScale = this.trackingKeyframeList[targetIndex].scale;
241
+ const kernelKey = markerWidth + "-" + markerHeight + "-" + markerScale;
242
+ if (!this.kernelCaches.computeProjection) {
243
+ this.kernelCaches.computeProjection = {};
244
+ }
245
+ if (!this.kernelCaches.computeProjection[kernelKey]) {
246
+ const kernel = {
247
+ variableNames: ["M", "pixel"],
248
+ outputShape: [markerHeight, markerWidth],
249
+ userCode: `
250
+ void main() {
251
+ ivec2 coords = getOutputCoords();
252
+
253
+ float m00 = getM(0, 0) * ${PRECISION_ADJUST}.;
254
+ float m01 = getM(0, 1) * ${PRECISION_ADJUST}.;
255
+ float m03 = getM(0, 3) * ${PRECISION_ADJUST}.;
256
+ float m10 = getM(1, 0) * ${PRECISION_ADJUST}.;
257
+ float m11 = getM(1, 1) * ${PRECISION_ADJUST}.;
258
+ float m13 = getM(1, 3) * ${PRECISION_ADJUST}.;
259
+ float m20 = getM(2, 0) * ${PRECISION_ADJUST}.;
260
+ float m21 = getM(2, 1) * ${PRECISION_ADJUST}.;
261
+ float m23 = getM(2, 3) * ${PRECISION_ADJUST}.;
262
+
263
+ float y = float(coords[0]) / float(${markerScale});
264
+ float x = float(coords[1]) / float(${markerScale});
265
+ float uz = (x * m20) + (y * m21) + m23;
266
+ float oneOverUz = 1. / uz;
267
+
268
+ float ux = (x * m00) + (y * m01) + m03;
269
+ float uy = (x * m10) + (y * m11) + m13;
270
+
271
+ ux = floor(ux * oneOverUz + 0.5);
272
+ uy = floor(uy * oneOverUz + 0.5);
273
+ setOutput(getPixel(int(uy), int(ux)));
274
+ }
275
+ `,
276
+ };
277
+ this.kernelCaches.computeProjection[kernelKey] = kernel;
278
+ }
279
+ return tf.tidy(() => {
280
+ const program = this.kernelCaches.computeProjection[kernelKey];
281
+ const result = this._compileAndRun(program, [modelViewProjectionTransformT, inputImageT]);
282
+ return result;
283
+ });
284
+ }
285
+ _buildAdjustedModelViewTransform(modelViewProjectionTransform) {
286
+ return tf.tidy(() => {
287
+ let modelViewProjectionTransformAdjusted = [];
288
+ for (let i = 0; i < modelViewProjectionTransform.length; i++) {
289
+ modelViewProjectionTransformAdjusted.push([]);
290
+ for (let j = 0; j < modelViewProjectionTransform[i].length; j++) {
291
+ modelViewProjectionTransformAdjusted[i].push(modelViewProjectionTransform[i][j] / PRECISION_ADJUST);
292
+ }
293
+ }
294
+ const t = tf.tensor(modelViewProjectionTransformAdjusted, [3, 4]);
295
+ return t;
296
+ });
297
+ }
298
+ _prebuild(trackingFrame, maxCount) {
299
+ return tf.tidy(() => {
300
+ const scale = trackingFrame.scale;
301
+ const p = [];
302
+ for (let k = 0; k < maxCount; k++) {
303
+ if (k < trackingFrame.points.length) {
304
+ p.push([trackingFrame.points[k].x / scale, trackingFrame.points[k].y / scale]);
305
+ }
306
+ else {
307
+ p.push([-1, -1]);
308
+ }
309
+ }
310
+ const imagePixels = tf.tensor(trackingFrame.data, [
311
+ trackingFrame.width * trackingFrame.height,
312
+ ]);
313
+ const imageProperties = tf.tensor([trackingFrame.width, trackingFrame.height, trackingFrame.scale], [3]);
314
+ const featurePoints = tf.tensor(p, [p.length, 2], "float32");
315
+ return {
316
+ featurePoints,
317
+ imagePixels,
318
+ imageProperties,
319
+ };
320
+ });
321
+ }
322
+ _compileAndRun(program, inputs) {
323
+ const outInfo = tf.backend().compileAndRun(program, inputs);
324
+ return tf.engine().makeTensorFromDataId(outInfo.dataId, outInfo.shape, outInfo.dtype);
325
+ }
326
+ }
327
+ export { Tracker };
@@ -0,0 +1,5 @@
1
+ export class Cumsum {
2
+ constructor(data: any, width: any, height: any);
3
+ cumsum: never[][];
4
+ query(x1: any, y1: any, x2: any, y2: any): any;
5
+ }
@@ -0,0 +1,39 @@
1
+ // fast 2D submatrix sum using cumulative sum algorithm
2
+ class Cumsum {
3
+ constructor(data, width, height) {
4
+ this.cumsum = [];
5
+ for (let j = 0; j < height; j++) {
6
+ this.cumsum.push([]);
7
+ for (let i = 0; i < width; i++) {
8
+ this.cumsum[j].push(0);
9
+ }
10
+ }
11
+ this.cumsum[0][0] = data[0];
12
+ for (let i = 1; i < width; i++) {
13
+ this.cumsum[0][i] = this.cumsum[0][i - 1] + data[i];
14
+ }
15
+ for (let j = 1; j < height; j++) {
16
+ this.cumsum[j][0] = this.cumsum[j - 1][0] + data[j * width];
17
+ }
18
+ for (let j = 1; j < height; j++) {
19
+ for (let i = 1; i < width; i++) {
20
+ this.cumsum[j][i] =
21
+ data[j * width + i] +
22
+ this.cumsum[j - 1][i] +
23
+ this.cumsum[j][i - 1] -
24
+ this.cumsum[j - 1][i - 1];
25
+ }
26
+ }
27
+ }
28
+ query(x1, y1, x2, y2) {
29
+ let ret = this.cumsum[y2][x2];
30
+ if (y1 > 0)
31
+ ret -= this.cumsum[y1 - 1][x2];
32
+ if (x1 > 0)
33
+ ret -= this.cumsum[y2][x1 - 1];
34
+ if (x1 > 0 && y1 > 0)
35
+ ret += this.cumsum[y1 - 1][x1 - 1];
36
+ return ret;
37
+ }
38
+ }
39
+ export { Cumsum };
@@ -0,0 +1,8 @@
1
+ export function matrixInverse33(A: any, threshold: any): number[] | null;
2
+ export function matrixMul33(A: any, B: any): number[];
3
+ export function quadrilateralConvex(x1: any, x2: any, x3: any, x4: any): boolean;
4
+ export function smallestTriangleArea(x1: any, x2: any, x3: any, x4: any): number;
5
+ export function multiplyPointHomographyInhomogenous(x: any, H: any): number[];
6
+ export function checkThreePointsConsistent(x1: any, x2: any, x3: any, x1p: any, x2p: any, x3p: any): boolean;
7
+ export function checkFourPointsConsistent(x1: any, x2: any, x3: any, x4: any, x1p: any, x2p: any, x3p: any, x4p: any): boolean;
8
+ export function determinant(A: any): number;
@@ -0,0 +1,101 @@
1
+ // check which side point C on the line from A to B
2
+ const linePointSide = (A, B, C) => {
3
+ return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
4
+ };
5
+ // srcPoints, dstPoints: array of four elements [x, y]
6
+ const checkFourPointsConsistent = (x1, x2, x3, x4, x1p, x2p, x3p, x4p) => {
7
+ if (linePointSide(x1, x2, x3) > 0 !== linePointSide(x1p, x2p, x3p) > 0)
8
+ return false;
9
+ if (linePointSide(x2, x3, x4) > 0 !== linePointSide(x2p, x3p, x4p) > 0)
10
+ return false;
11
+ if (linePointSide(x3, x4, x1) > 0 !== linePointSide(x3p, x4p, x1p) > 0)
12
+ return false;
13
+ if (linePointSide(x4, x1, x2) > 0 !== linePointSide(x4p, x1p, x2p) > 0)
14
+ return false;
15
+ return true;
16
+ };
17
+ const checkThreePointsConsistent = (x1, x2, x3, x1p, x2p, x3p) => {
18
+ if (linePointSide(x1, x2, x3) > 0 !== linePointSide(x1p, x2p, x3p) > 0)
19
+ return false;
20
+ return true;
21
+ };
22
+ const determinant = (A) => {
23
+ const C1 = A[4] * A[8] - A[5] * A[7];
24
+ const C2 = A[3] * A[8] - A[5] * A[6];
25
+ const C3 = A[3] * A[7] - A[4] * A[6];
26
+ return A[0] * C1 - A[1] * C2 + A[2] * C3;
27
+ };
28
+ const matrixInverse33 = (A, threshold) => {
29
+ const det = determinant(A);
30
+ if (Math.abs(det) <= threshold)
31
+ return null;
32
+ const oneOver = 1.0 / det;
33
+ const B = [
34
+ (A[4] * A[8] - A[5] * A[7]) * oneOver,
35
+ (A[2] * A[7] - A[1] * A[8]) * oneOver,
36
+ (A[1] * A[5] - A[2] * A[4]) * oneOver,
37
+ (A[5] * A[6] - A[3] * A[8]) * oneOver,
38
+ (A[0] * A[8] - A[2] * A[6]) * oneOver,
39
+ (A[2] * A[3] - A[0] * A[5]) * oneOver,
40
+ (A[3] * A[7] - A[4] * A[6]) * oneOver,
41
+ (A[1] * A[6] - A[0] * A[7]) * oneOver,
42
+ (A[0] * A[4] - A[1] * A[3]) * oneOver,
43
+ ];
44
+ return B;
45
+ };
46
+ const matrixMul33 = (A, B) => {
47
+ const C = [];
48
+ C[0] = A[0] * B[0] + A[1] * B[3] + A[2] * B[6];
49
+ C[1] = A[0] * B[1] + A[1] * B[4] + A[2] * B[7];
50
+ C[2] = A[0] * B[2] + A[1] * B[5] + A[2] * B[8];
51
+ C[3] = A[3] * B[0] + A[4] * B[3] + A[5] * B[6];
52
+ C[4] = A[3] * B[1] + A[4] * B[4] + A[5] * B[7];
53
+ C[5] = A[3] * B[2] + A[4] * B[5] + A[5] * B[8];
54
+ C[6] = A[6] * B[0] + A[7] * B[3] + A[8] * B[6];
55
+ C[7] = A[6] * B[1] + A[7] * B[4] + A[8] * B[7];
56
+ C[8] = A[6] * B[2] + A[7] * B[5] + A[8] * B[8];
57
+ return C;
58
+ };
59
+ const multiplyPointHomographyInhomogenous = (x, H) => {
60
+ const w = H[6] * x[0] + H[7] * x[1] + H[8];
61
+ const xp = [];
62
+ xp[0] = (H[0] * x[0] + H[1] * x[1] + H[2]) / w;
63
+ xp[1] = (H[3] * x[0] + H[4] * x[1] + H[5]) / w;
64
+ return xp;
65
+ };
66
+ const smallestTriangleArea = (x1, x2, x3, x4) => {
67
+ const v12 = _vector(x2, x1);
68
+ const v13 = _vector(x3, x1);
69
+ const v14 = _vector(x4, x1);
70
+ const v32 = _vector(x2, x3);
71
+ const v34 = _vector(x4, x3);
72
+ const a1 = _areaOfTriangle(v12, v13);
73
+ const a2 = _areaOfTriangle(v13, v14);
74
+ const a3 = _areaOfTriangle(v12, v14);
75
+ const a4 = _areaOfTriangle(v32, v34);
76
+ return Math.min(Math.min(Math.min(a1, a2), a3), a4);
77
+ };
78
+ // check if four points form a convex quadrilaternal.
79
+ // all four combinations should have same sign
80
+ const quadrilateralConvex = (x1, x2, x3, x4) => {
81
+ const first = linePointSide(x1, x2, x3) <= 0;
82
+ if (linePointSide(x2, x3, x4) <= 0 !== first)
83
+ return false;
84
+ if (linePointSide(x3, x4, x1) <= 0 !== first)
85
+ return false;
86
+ if (linePointSide(x4, x1, x2) <= 0 !== first)
87
+ return false;
88
+ //if (linePointSide(x1, x2, x3) <= 0) return false;
89
+ //if (linePointSide(x2, x3, x4) <= 0) return false;
90
+ //if (linePointSide(x3, x4, x1) <= 0) return false;
91
+ //if (linePointSide(x4, x1, x2) <= 0) return false;
92
+ return true;
93
+ };
94
+ const _vector = (a, b) => {
95
+ return [a[0] - b[0], a[1] - b[1]];
96
+ };
97
+ const _areaOfTriangle = (u, v) => {
98
+ const a = u[0] * v[1] - u[1] * v[0];
99
+ return Math.abs(a) * 0.5;
100
+ };
101
+ export { matrixInverse33, matrixMul33, quadrilateralConvex, smallestTriangleArea, multiplyPointHomographyInhomogenous, checkThreePointsConsistent, checkFourPointsConsistent, determinant, };
@@ -0,0 +1 @@
1
+ export function solveHomography(srcPoints: any, dstPoints: any): any[] | null;
@@ -0,0 +1,138 @@
1
+ import { Matrix, inverse } from "ml-matrix";
2
+ const solveHomography = (srcPoints, dstPoints) => {
3
+ const { normPoints: normSrcPoints, param: srcParam } = _normalizePoints(srcPoints);
4
+ const { normPoints: normDstPoints, param: dstParam } = _normalizePoints(dstPoints);
5
+ const num = normDstPoints.length;
6
+ const AData = [];
7
+ const BData = [];
8
+ for (let j = 0; j < num; j++) {
9
+ const row1 = [
10
+ normSrcPoints[j][0],
11
+ normSrcPoints[j][1],
12
+ 1,
13
+ 0,
14
+ 0,
15
+ 0,
16
+ -(normSrcPoints[j][0] * normDstPoints[j][0]),
17
+ -(normSrcPoints[j][1] * normDstPoints[j][0]),
18
+ ];
19
+ const row2 = [
20
+ 0,
21
+ 0,
22
+ 0,
23
+ normSrcPoints[j][0],
24
+ normSrcPoints[j][1],
25
+ 1,
26
+ -(normSrcPoints[j][0] * normDstPoints[j][1]),
27
+ -(normSrcPoints[j][1] * normDstPoints[j][1]),
28
+ ];
29
+ AData.push(row1);
30
+ AData.push(row2);
31
+ BData.push([normDstPoints[j][0]]);
32
+ BData.push([normDstPoints[j][1]]);
33
+ }
34
+ try {
35
+ const A = new Matrix(AData);
36
+ const B = new Matrix(BData);
37
+ const AT = A.transpose();
38
+ const ATA = AT.mmul(A);
39
+ const ATB = AT.mmul(B);
40
+ const ATAInv = inverse(ATA);
41
+ const C = ATAInv.mmul(ATB).to1DArray();
42
+ const H = _denormalizeHomography(C, srcParam, dstParam);
43
+ return H;
44
+ }
45
+ catch (e) {
46
+ return null;
47
+ }
48
+ };
49
+ // centroid at origin and avg distance from origin is sqrt(2)
50
+ const _normalizePoints = (coords) => {
51
+ //return {normalizedCoords: coords, param: {meanX: 0, meanY: 0, s: 1}}; // skip normalization
52
+ let sumX = 0;
53
+ let sumY = 0;
54
+ for (let i = 0; i < coords.length; i++) {
55
+ sumX += coords[i][0];
56
+ sumY += coords[i][1];
57
+ }
58
+ let meanX = sumX / coords.length;
59
+ let meanY = sumY / coords.length;
60
+ let sumDiff = 0;
61
+ for (let i = 0; i < coords.length; i++) {
62
+ const diffX = coords[i][0] - meanX;
63
+ const diffY = coords[i][1] - meanY;
64
+ sumDiff += Math.sqrt(diffX * diffX + diffY * diffY);
65
+ }
66
+ let s = (Math.sqrt(2) * coords.length) / sumDiff;
67
+ const normPoints = [];
68
+ for (let i = 0; i < coords.length; i++) {
69
+ normPoints.push([(coords[i][0] - meanX) * s, (coords[i][1] - meanY) * s]);
70
+ }
71
+ return { normPoints, param: { meanX, meanY, s } };
72
+ };
73
+ // Denormalize homography
74
+ // where T is the normalization matrix, i.e.
75
+ //
76
+ // [1 0 -meanX]
77
+ // T = [0 1 -meanY]
78
+ // [0 0 1/s]
79
+ //
80
+ // [1 0 s*meanX]
81
+ // inv(T) = [0 1 s*meanY]
82
+ // [0 0 s]
83
+ //
84
+ // H = inv(Tdst) * Hn * Tsrc
85
+ //
86
+ // @param {
87
+ // nH: normH,
88
+ // srcParam: param of src transform,
89
+ // dstParam: param of dst transform
90
+ // }
91
+ const _denormalizeHomography = (nH, srcParam, dstParam) => {
92
+ /*
93
+ Matrix version
94
+ const normH = new Matrix([
95
+ [nH[0], nH[1], nH[2]],
96
+ [nH[3], nH[4], nH[5]],
97
+ [nH[6], nH[7], 1],
98
+ ]);
99
+ const Tsrc = new Matrix([
100
+ [1, 0, -srcParam.meanX],
101
+ [0, 1, -srcParam.meanY],
102
+ [0, 0, 1/srcParam.s],
103
+ ]);
104
+
105
+ const invTdst = new Matrix([
106
+ [1, 0, dstParam.s * dstParam.meanX],
107
+ [0, 1, dstParam.s * dstParam.meanY],
108
+ [0, 0, dstParam.s],
109
+ ]);
110
+ const H = invTdst.mmul(normH).mmul(Tsrc);
111
+ */
112
+ // plain implementation of the above using Matrix
113
+ const sMeanX = dstParam.s * dstParam.meanX;
114
+ const sMeanY = dstParam.s * dstParam.meanY;
115
+ const H = [
116
+ nH[0] + sMeanX * nH[6],
117
+ nH[1] + sMeanX * nH[7],
118
+ (nH[0] + sMeanX * nH[6]) * -srcParam.meanX +
119
+ (nH[1] + sMeanX * nH[7]) * -srcParam.meanY +
120
+ (nH[2] + sMeanX) / srcParam.s,
121
+ nH[3] + sMeanY * nH[6],
122
+ nH[4] + sMeanY * nH[7],
123
+ (nH[3] + sMeanY * nH[6]) * -srcParam.meanX +
124
+ (nH[4] + sMeanY * nH[7]) * -srcParam.meanY +
125
+ (nH[5] + sMeanY) / srcParam.s,
126
+ dstParam.s * nH[6],
127
+ dstParam.s * nH[7],
128
+ dstParam.s * nH[6] * -srcParam.meanX +
129
+ dstParam.s * nH[7] * -srcParam.meanY +
130
+ dstParam.s / srcParam.s,
131
+ ];
132
+ // make H[8] === 1;
133
+ for (let i = 0; i < 9; i++) {
134
+ H[i] = H[i] / H[8];
135
+ }
136
+ return H;
137
+ };
138
+ export { solveHomography };
@@ -0,0 +1,24 @@
1
+ export function downsampleBilinear({ image }: {
2
+ image: any;
3
+ }): {
4
+ data: Float32Array<ArrayBuffer>;
5
+ width: number;
6
+ height: number;
7
+ };
8
+ export function upsampleBilinear({ image, padOneWidth, padOneHeight }: {
9
+ image: any;
10
+ padOneWidth: any;
11
+ padOneHeight: any;
12
+ }): {
13
+ data: Float32Array<ArrayBuffer>;
14
+ width: number;
15
+ height: number;
16
+ };
17
+ export function resize({ image, ratio }: {
18
+ image: any;
19
+ ratio: any;
20
+ }): {
21
+ data: Uint8Array<ArrayBuffer>;
22
+ width: number;
23
+ height: number;
24
+ };