Guest User

js-aruco + meteor package dump

a guest
Mar 31st, 2015
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //////////////////////////////////////////////////////////////////////////
  2. //                                                                      //
  3. // This is a generated file. You can view the original                  //
  4. // source in your browser if your browser supports source maps.         //
  5. //                                                                      //
  6. // If you are using Chrome, open the Developer Tools and click the gear //
  7. // icon in its lower right corner. In the General Settings panel, turn  //
  8. // on 'Enable source maps'.                                             //
  9. //                                                                      //
  10. // If you are using Firefox 23, go to `about:config` and set the        //
  11. // `devtools.debugger.source-maps-enabled` preference to true.          //
  12. // (The preference should be on by default in Firefox 24; versions      //
  13. // older than 23 do not support source maps.)                           //
  14. //                                                                      //
  15. //////////////////////////////////////////////////////////////////////////
  16.  
  17.  
  18. (function () {
  19.  
  20. /* Imports */
  21. var Meteor = Package.meteor.Meteor;
  22.  
  23. (function () {
  24.  
  25. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  26. //                                                                                                        //
  27. // packages/js-aruco/aruco.js                                                                             //
  28. //                                                                                                        //
  29. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  30.                                                                                                           //
  31. /*                                                                                                        // 1
  32. Copyright (c) 2011 Juan Mellado                                                                           // 2
  33.                                                                                                           // 3
  34. Permission is hereby granted, free of charge, to any person obtaining a copy                              // 4
  35. of this software and associated documentation files (the "Software"), to deal                             // 5
  36. in the Software without restriction, including without limitation the rights                              // 6
  37. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                                 // 7
  38. copies of the Software, and to permit persons to whom the Software is                                     // 8
  39. furnished to do so, subject to the following conditions:                                                  // 9
  40.                                                                                                           // 10
  41. The above copyright notice and this permission notice shall be included in                                // 11
  42. all copies or substantial portions of the Software.                                                       // 12
  43.                                                                                                           // 13
  44. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                                // 14
  45. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                                  // 15
  46. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                               // 16
  47. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                                    // 17
  48. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,                             // 18
  49. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                                 // 19
  50. THE SOFTWARE.                                                                                             // 20
  51. */                                                                                                        // 21
  52.                                                                                                           // 22
  53. /*                                                                                                        // 23
  54. References:                                                                                               // 24
  55. - "ArUco: a minimal library for Augmented Reality applications based on OpenCv"                           // 25
  56.   http://www.uco.es/investiga/grupos/ava/node/26                                                          // 26
  57. */                                                                                                        // 27
  58.                                                                                                           // 28
  59. var AR = AR || {};                                                                                        // 29
  60.                                                                                                           // 30
  61. AR.Marker = function(id, corners){                                                                        // 31
  62.   this.id = id;                                                                                           // 32
  63.   this.corners = corners;                                                                                 // 33
  64. };                                                                                                        // 34
  65.                                                                                                           // 35
  66. AR.Detector = function(){                                                                                 // 36
  67.   this.grey = new CV.Image();                                                                             // 37
  68.   this.thres = new CV.Image();                                                                            // 38
  69.   this.homography = new CV.Image();                                                                       // 39
  70.   this.binary = [];                                                                                       // 40
  71.   this.contours = [];                                                                                     // 41
  72.   this.polys = [];                                                                                        // 42
  73.   this.candidates = [];                                                                                   // 43
  74. };                                                                                                        // 44
  75.                                                                                                           // 45
  76. AR.Detector.prototype.detect = function(image){                                                           // 46
  77.   CV.grayscale(image, this.grey);                                                                         // 47
  78.   CV.adaptiveThreshold(this.grey, this.thres, 2, 7);                                                      // 48
  79.                                                                                                           // 49
  80.   this.contours = CV.findContours(this.thres, this.binary);                                               // 50
  81.                                                                                                           // 51
  82.   this.candidates = this.findCandidates(this.contours, image.width * 0.20, 0.05, 10);                     // 52
  83.   this.candidates = this.clockwiseCorners(this.candidates);                                               // 53
  84.   this.candidates = this.notTooNear(this.candidates, 10);                                                 // 54
  85.                                                                                                           // 55
  86.   return this.findMarkers(this.grey, this.candidates, 49);                                                // 56
  87. };                                                                                                        // 57
  88.                                                                                                           // 58
  89. AR.Detector.prototype.findCandidates = function(contours, minSize, epsilon, minLength){                   // 59
  90.   var candidates = [], len = contours.length, contour, poly, i;                                           // 60
  91.                                                                                                           // 61
  92.   this.polys = [];                                                                                        // 62
  93.                                                                                                           // 63
  94.   for (i = 0; i < len; ++ i){                                                                             // 64
  95.     contour = contours[i];                                                                                // 65
  96.                                                                                                           // 66
  97.     if (contour.length >= minSize){                                                                       // 67
  98.       poly = CV.approxPolyDP(contour, contour.length * epsilon);                                          // 68
  99.                                                                                                           // 69
  100.       this.polys.push(poly);                                                                              // 70
  101.                                                                                                           // 71
  102.       if ( (4 === poly.length) && ( CV.isContourConvex(poly) ) ){                                         // 72
  103.                                                                                                           // 73
  104.         if ( CV.minEdgeLength(poly) >= minLength){                                                        // 74
  105.           candidates.push(poly);                                                                          // 75
  106.         }                                                                                                 // 76
  107.       }                                                                                                   // 77
  108.     }                                                                                                     // 78
  109.   }                                                                                                       // 79
  110.                                                                                                           // 80
  111.   return candidates;                                                                                      // 81
  112. };                                                                                                        // 82
  113.                                                                                                           // 83
  114. AR.Detector.prototype.clockwiseCorners = function(candidates){                                            // 84
  115.   var len = candidates.length, dx1, dx2, dy1, dy2, swap, i;                                               // 85
  116.                                                                                                           // 86
  117.   for (i = 0; i < len; ++ i){                                                                             // 87
  118.     dx1 = candidates[i][1].x - candidates[i][0].x;                                                        // 88
  119.     dy1 = candidates[i][1].y - candidates[i][0].y;                                                        // 89
  120.     dx2 = candidates[i][2].x - candidates[i][0].x;                                                        // 90
  121.     dy2 = candidates[i][2].y - candidates[i][0].y;                                                        // 91
  122.                                                                                                           // 92
  123.     if ( (dx1 * dy2 - dy1 * dx2) < 0){                                                                    // 93
  124.       swap = candidates[i][1];                                                                            // 94
  125.       candidates[i][1] = candidates[i][3];                                                                // 95
  126.       candidates[i][3] = swap;                                                                            // 96
  127.     }                                                                                                     // 97
  128.   }                                                                                                       // 98
  129.                                                                                                           // 99
  130.   return candidates;                                                                                      // 100
  131. };                                                                                                        // 101
  132.                                                                                                           // 102
  133. AR.Detector.prototype.notTooNear = function(candidates, minDist){                                         // 103
  134.   var notTooNear = [], len = candidates.length, dist, dx, dy, i, j, k;                                    // 104
  135.                                                                                                           // 105
  136.   for (i = 0; i < len; ++ i){                                                                             // 106
  137.                                                                                                           // 107
  138.     for (j = i + 1; j < len; ++ j){                                                                       // 108
  139.       dist = 0;                                                                                           // 109
  140.                                                                                                           // 110
  141.       for (k = 0; k < 4; ++ k){                                                                           // 111
  142.         dx = candidates[i][k].x - candidates[j][k].x;                                                     // 112
  143.         dy = candidates[i][k].y - candidates[j][k].y;                                                     // 113
  144.                                                                                                           // 114
  145.         dist += dx * dx + dy * dy;                                                                        // 115
  146.       }                                                                                                   // 116
  147.                                                                                                           // 117
  148.       if ( (dist / 4) < (minDist * minDist) ){                                                            // 118
  149.                                                                                                           // 119
  150.         if ( CV.perimeter( candidates[i] ) < CV.perimeter( candidates[j] ) ){                             // 120
  151.           candidates[i].tooNear = true;                                                                   // 121
  152.         }else{                                                                                            // 122
  153.           candidates[j].tooNear = true;                                                                   // 123
  154.         }                                                                                                 // 124
  155.       }                                                                                                   // 125
  156.     }                                                                                                     // 126
  157.   }                                                                                                       // 127
  158.                                                                                                           // 128
  159.   for (i = 0; i < len; ++ i){                                                                             // 129
  160.     if ( !candidates[i].tooNear ){                                                                        // 130
  161.       notTooNear.push( candidates[i] );                                                                   // 131
  162.     }                                                                                                     // 132
  163.   }                                                                                                       // 133
  164.                                                                                                           // 134
  165.   return notTooNear;                                                                                      // 135
  166. };                                                                                                        // 136
  167.                                                                                                           // 137
  168. AR.Detector.prototype.findMarkers = function(imageSrc, candidates, warpSize){                             // 138
  169.   var markers = [], len = candidates.length, candidate, marker, i;                                        // 139
  170.                                                                                                           // 140
  171.   for (i = 0; i < len; ++ i){                                                                             // 141
  172.     candidate = candidates[i];                                                                            // 142
  173.                                                                                                           // 143
  174.     CV.warp(imageSrc, this.homography, candidate, warpSize);                                              // 144
  175.                                                                                                           // 145
  176.     CV.threshold(this.homography, this.homography, CV.otsu(this.homography) );                            // 146
  177.                                                                                                           // 147
  178.     marker = this.getMarker(this.homography, candidate);                                                  // 148
  179.     if (marker){                                                                                          // 149
  180.       markers.push(marker);                                                                               // 150
  181.     }                                                                                                     // 151
  182.   }                                                                                                       // 152
  183.                                                                                                           // 153
  184.   return markers;                                                                                         // 154
  185. };                                                                                                        // 155
  186.                                                                                                           // 156
  187. AR.Detector.prototype.getMarker = function(imageSrc, candidate){                                          // 157
  188.   var width = (imageSrc.width / 7) >>> 0,                                                                 // 158
  189.       minZero = (width * width) >> 1,                                                                     // 159
  190.       bits = [], rotations = [], distances = [],                                                          // 160
  191.       square, pair, inc, i, j;                                                                            // 161
  192.                                                                                                           // 162
  193.   for (i = 0; i < 7; ++ i){                                                                               // 163
  194.     inc = (0 === i || 6 === i)? 1: 6;                                                                     // 164
  195.                                                                                                           // 165
  196.     for (j = 0; j < 7; j += inc){                                                                         // 166
  197.       square = {x: j * width, y: i * width, width: width, height: width};                                 // 167
  198.       if ( CV.countNonZero(imageSrc, square) > minZero){                                                  // 168
  199.         return null;                                                                                      // 169
  200.       }                                                                                                   // 170
  201.     }                                                                                                     // 171
  202.   }                                                                                                       // 172
  203.                                                                                                           // 173
  204.   for (i = 0; i < 5; ++ i){                                                                               // 174
  205.     bits[i] = [];                                                                                         // 175
  206.                                                                                                           // 176
  207.     for (j = 0; j < 5; ++ j){                                                                             // 177
  208.       square = {x: (j + 1) * width, y: (i + 1) * width, width: width, height: width};                     // 178
  209.                                                                                                           // 179
  210.       bits[i][j] = CV.countNonZero(imageSrc, square) > minZero? 1: 0;                                     // 180
  211.     }                                                                                                     // 181
  212.   }                                                                                                       // 182
  213.                                                                                                           // 183
  214.   rotations[0] = bits;                                                                                    // 184
  215.   distances[0] = this.hammingDistance( rotations[0] );                                                    // 185
  216.                                                                                                           // 186
  217.   pair = {first: distances[0], second: 0};                                                                // 187
  218.                                                                                                           // 188
  219.   for (i = 1; i < 4; ++ i){                                                                               // 189
  220.     rotations[i] = this.rotate( rotations[i - 1] );                                                       // 190
  221.     distances[i] = this.hammingDistance( rotations[i] );                                                  // 191
  222.                                                                                                           // 192
  223.     if (distances[i] < pair.first){                                                                       // 193
  224.       pair.first = distances[i];                                                                          // 194
  225.       pair.second = i;                                                                                    // 195
  226.     }                                                                                                     // 196
  227.   }                                                                                                       // 197
  228.                                                                                                           // 198
  229.   if (0 !== pair.first){                                                                                  // 199
  230.     return null;                                                                                          // 200
  231.   }                                                                                                       // 201
  232.                                                                                                           // 202
  233.   return new AR.Marker(                                                                                   // 203
  234.     this.mat2id( rotations[pair.second] ),                                                                // 204
  235.     this.rotate2(candidate, 4 - pair.second) );                                                           // 205
  236. };                                                                                                        // 206
  237.                                                                                                           // 207
  238. AR.Detector.prototype.hammingDistance = function(bits){                                                   // 208
  239.   var ids = [ [1,0,0,0,0], [1,0,1,1,1], [0,1,0,0,1], [0,1,1,1,0] ],                                       // 209
  240.       dist = 0, sum, minSum, i, j, k;                                                                     // 210
  241.                                                                                                           // 211
  242.   for (i = 0; i < 5; ++ i){                                                                               // 212
  243.     minSum = Infinity;                                                                                    // 213
  244.                                                                                                           // 214
  245.     for (j = 0; j < 4; ++ j){                                                                             // 215
  246.       sum = 0;                                                                                            // 216
  247.                                                                                                           // 217
  248.       for (k = 0; k < 5; ++ k){                                                                           // 218
  249.           sum += bits[i][k] === ids[j][k]? 0: 1;                                                          // 219
  250.       }                                                                                                   // 220
  251.                                                                                                           // 221
  252.       if (sum < minSum){                                                                                  // 222
  253.         minSum = sum;                                                                                     // 223
  254.       }                                                                                                   // 224
  255.     }                                                                                                     // 225
  256.                                                                                                           // 226
  257.     dist += minSum;                                                                                       // 227
  258.   }                                                                                                       // 228
  259.                                                                                                           // 229
  260.   return dist;                                                                                            // 230
  261. };                                                                                                        // 231
  262.                                                                                                           // 232
  263. AR.Detector.prototype.mat2id = function(bits){                                                            // 233
  264.   var id = 0, i;                                                                                          // 234
  265.                                                                                                           // 235
  266.   for (i = 0; i < 5; ++ i){                                                                               // 236
  267.     id <<= 1;                                                                                             // 237
  268.     id |= bits[i][1];                                                                                     // 238
  269.     id <<= 1;                                                                                             // 239
  270.     id |= bits[i][3];                                                                                     // 240
  271.   }                                                                                                       // 241
  272.                                                                                                           // 242
  273.   return id;                                                                                              // 243
  274. };                                                                                                        // 244
  275.                                                                                                           // 245
  276. AR.Detector.prototype.rotate = function(src){                                                             // 246
  277.   var dst = [], len = src.length, i, j;                                                                   // 247
  278.                                                                                                           // 248
  279.   for (i = 0; i < len; ++ i){                                                                             // 249
  280.     dst[i] = [];                                                                                          // 250
  281.     for (j = 0; j < src[i].length; ++ j){                                                                 // 251
  282.       dst[i][j] = src[src[i].length - j - 1][i];                                                          // 252
  283.     }                                                                                                     // 253
  284.   }                                                                                                       // 254
  285.                                                                                                           // 255
  286.   return dst;                                                                                             // 256
  287. };                                                                                                        // 257
  288.                                                                                                           // 258
  289. AR.Detector.prototype.rotate2 = function(src, rotation){                                                  // 259
  290.   var dst = [], len = src.length, i;                                                                      // 260
  291.                                                                                                           // 261
  292.   for (i = 0; i < len; ++ i){                                                                             // 262
  293.     dst[i] = src[ (rotation + i) % len ];                                                                 // 263
  294.   }                                                                                                       // 264
  295.                                                                                                           // 265
  296.   return dst;                                                                                             // 266
  297. };                                                                                                        // 267
  298.                                                                                                           // 268
  299. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  300.  
  301. }).call(this);
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308. (function () {
  309.  
  310. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  311. //                                                                                                        //
  312. // packages/js-aruco/cv.js                                                                                //
  313. //                                                                                                        //
  314. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  315.                                                                                                           //
  316. /*                                                                                                        // 1
  317. Copyright (c) 2011 Juan Mellado                                                                           // 2
  318.                                                                                                           // 3
  319. Permission is hereby granted, free of charge, to any person obtaining a copy                              // 4
  320. of this software and associated documentation files (the "Software"), to deal                             // 5
  321. in the Software without restriction, including without limitation the rights                              // 6
  322. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell                                 // 7
  323. copies of the Software, and to permit persons to whom the Software is                                     // 8
  324. furnished to do so, subject to the following conditions:                                                  // 9
  325.                                                                                                           // 10
  326. The above copyright notice and this permission notice shall be included in                                // 11
  327. all copies or substantial portions of the Software.                                                       // 12
  328.                                                                                                           // 13
  329. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR                                // 14
  330. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,                                  // 15
  331. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE                               // 16
  332. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER                                    // 17
  333. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,                             // 18
  334. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN                                 // 19
  335. THE SOFTWARE.                                                                                             // 20
  336. */                                                                                                        // 21
  337.                                                                                                           // 22
  338. /*                                                                                                        // 23
  339. References:                                                                                               // 24
  340. - "OpenCV: Open Computer Vision Library"                                                                  // 25
  341.   http://sourceforge.net/projects/opencvlibrary/                                                          // 26
  342. - "Stack Blur: Fast But Goodlooking"                                                                      // 27
  343.   http://incubator.quasimondo.com/processing/fast_blur_deluxe.php                                         // 28
  344. */                                                                                                        // 29
  345.                                                                                                           // 30
  346. var CV = CV || {};                                                                                        // 31
  347.                                                                                                           // 32
  348. CV.Image = function(width, height, data){                                                                 // 33
  349.   this.width = width || 0;                                                                                // 34
  350.   this.height = height || 0;                                                                              // 35
  351.   this.data = data || [];                                                                                 // 36
  352. };                                                                                                        // 37
  353.                                                                                                           // 38
  354. CV.grayscale = function(imageSrc, imageDst){                                                              // 39
  355.   var src = imageSrc.data, dst = imageDst.data, len = src.length,                                         // 40
  356.       i = 0, j = 0;                                                                                       // 41
  357.                                                                                                           // 42
  358.   for (; i < len; i += 4){                                                                                // 43
  359.     dst[j ++] =                                                                                           // 44
  360.       (src[i] * 0.299 + src[i + 1] * 0.587 + src[i + 2] * 0.114 + 0.5) & 0xff;                            // 45
  361.   }                                                                                                       // 46
  362.                                                                                                           // 47
  363.   imageDst.width = imageSrc.width;                                                                        // 48
  364.   imageDst.height = imageSrc.height;                                                                      // 49
  365.                                                                                                           // 50
  366.   return imageDst;                                                                                        // 51
  367. };                                                                                                        // 52
  368.                                                                                                           // 53
  369. CV.threshold = function(imageSrc, imageDst, threshold){                                                   // 54
  370.   var src = imageSrc.data, dst = imageDst.data,                                                           // 55
  371.       len = src.length, tab = [], i;                                                                      // 56
  372.                                                                                                           // 57
  373.   for (i = 0; i < 256; ++ i){                                                                             // 58
  374.     tab[i] = i <= threshold? 0: 255;                                                                      // 59
  375.   }                                                                                                       // 60
  376.                                                                                                           // 61
  377.   for (i = 0; i < len; ++ i){                                                                             // 62
  378.     dst[i] = tab[ src[i] ];                                                                               // 63
  379.   }                                                                                                       // 64
  380.                                                                                                           // 65
  381.   imageDst.width = imageSrc.width;                                                                        // 66
  382.   imageDst.height = imageSrc.height;                                                                      // 67
  383.                                                                                                           // 68
  384.   return imageDst;                                                                                        // 69
  385. };                                                                                                        // 70
  386.                                                                                                           // 71
  387. CV.adaptiveThreshold = function(imageSrc, imageDst, kernelSize, threshold){                               // 72
  388.   var src = imageSrc.data, dst = imageDst.data, len = src.length, tab = [], i;                            // 73
  389.                                                                                                           // 74
  390.   CV.stackBoxBlur(imageSrc, imageDst, kernelSize);                                                        // 75
  391.                                                                                                           // 76
  392.   for (i = 0; i < 768; ++ i){                                                                             // 77
  393.     tab[i] = (i - 255 <= -threshold)? 255: 0;                                                             // 78
  394.   }                                                                                                       // 79
  395.                                                                                                           // 80
  396.   for (i = 0; i < len; ++ i){                                                                             // 81
  397.     dst[i] = tab[ src[i] - dst[i] + 255 ];                                                                // 82
  398.   }                                                                                                       // 83
  399.                                                                                                           // 84
  400.   imageDst.width = imageSrc.width;                                                                        // 85
  401.   imageDst.height = imageSrc.height;                                                                      // 86
  402.                                                                                                           // 87
  403.   return imageDst;                                                                                        // 88
  404. };                                                                                                        // 89
  405.                                                                                                           // 90
  406. CV.otsu = function(imageSrc){                                                                             // 91
  407.   var src = imageSrc.data, len = src.length, hist = [],                                                   // 92
  408.       threshold = 0, sum = 0, sumB = 0, wB = 0, wF = 0, max = 0,                                          // 93
  409.       mu, between, i;                                                                                     // 94
  410.                                                                                                           // 95
  411.   for (i = 0; i < 256; ++ i){                                                                             // 96
  412.     hist[i] = 0;                                                                                          // 97
  413.   }                                                                                                       // 98
  414.                                                                                                           // 99
  415.   for (i = 0; i < len; ++ i){                                                                             // 100
  416.     hist[ src[i] ] ++;                                                                                    // 101
  417.   }                                                                                                       // 102
  418.                                                                                                           // 103
  419.   for (i = 0; i < 256; ++ i){                                                                             // 104
  420.     sum += hist[i] * i;                                                                                   // 105
  421.   }                                                                                                       // 106
  422.                                                                                                           // 107
  423.   for (i = 0; i < 256; ++ i){                                                                             // 108
  424.     wB += hist[i];                                                                                        // 109
  425.     if (0 !== wB){                                                                                        // 110
  426.                                                                                                           // 111
  427.       wF = len - wB;                                                                                      // 112
  428.       if (0 === wF){                                                                                      // 113
  429.         break;                                                                                            // 114
  430.       }                                                                                                   // 115
  431.                                                                                                           // 116
  432.       sumB += hist[i] * i;                                                                                // 117
  433.                                                                                                           // 118
  434.       mu = (sumB / wB) - ( (sum - sumB) / wF );                                                           // 119
  435.                                                                                                           // 120
  436.       between = wB * wF * mu * mu;                                                                        // 121
  437.                                                                                                           // 122
  438.       if (between > max){                                                                                 // 123
  439.         max = between;                                                                                    // 124
  440.         threshold = i;                                                                                    // 125
  441.       }                                                                                                   // 126
  442.     }                                                                                                     // 127
  443.   }                                                                                                       // 128
  444.                                                                                                           // 129
  445.   return threshold;                                                                                       // 130
  446. };                                                                                                        // 131
  447.                                                                                                           // 132
  448. CV.stackBoxBlurMult =                                                                                     // 133
  449.   [1, 171, 205, 293, 57, 373, 79, 137, 241, 27, 391, 357, 41, 19, 283, 265];                              // 134
  450.                                                                                                           // 135
  451. CV.stackBoxBlurShift =                                                                                    // 136
  452.   [0, 9, 10, 11, 9, 12, 10, 11, 12, 9, 13, 13, 10, 9, 13, 13];                                            // 137
  453.                                                                                                           // 138
  454. CV.BlurStack = function(){                                                                                // 139
  455.   this.color = 0;                                                                                         // 140
  456.   this.next = null;                                                                                       // 141
  457. };                                                                                                        // 142
  458.                                                                                                           // 143
  459. CV.stackBoxBlur = function(imageSrc, imageDst, kernelSize){                                               // 144
  460.   var src = imageSrc.data, dst = imageDst.data,                                                           // 145
  461.       height = imageSrc.height, width = imageSrc.width,                                                   // 146
  462.       heightMinus1 = height - 1, widthMinus1 = width - 1,                                                 // 147
  463.       size = kernelSize + kernelSize + 1, radius = kernelSize + 1,                                        // 148
  464.       mult = CV.stackBoxBlurMult[kernelSize],                                                             // 149
  465.       shift = CV.stackBoxBlurShift[kernelSize],                                                           // 150
  466.       stack, stackStart, color, sum, pos, start, p, x, y, i;                                              // 151
  467.                                                                                                           // 152
  468.   stack = stackStart = new CV.BlurStack();                                                                // 153
  469.   for (i = 1; i < size; ++ i){                                                                            // 154
  470.     stack = stack.next = new CV.BlurStack();                                                              // 155
  471.   }                                                                                                       // 156
  472.   stack.next = stackStart;                                                                                // 157
  473.                                                                                                           // 158
  474.   pos = 0;                                                                                                // 159
  475.                                                                                                           // 160
  476.   for (y = 0; y < height; ++ y){                                                                          // 161
  477.     start = pos;                                                                                          // 162
  478.                                                                                                           // 163
  479.     color = src[pos];                                                                                     // 164
  480.     sum = radius * color;                                                                                 // 165
  481.                                                                                                           // 166
  482.     stack = stackStart;                                                                                   // 167
  483.     for (i = 0; i < radius; ++ i){                                                                        // 168
  484.       stack.color = color;                                                                                // 169
  485.       stack = stack.next;                                                                                 // 170
  486.     }                                                                                                     // 171
  487.     for (i = 1; i < radius; ++ i){                                                                        // 172
  488.       stack.color = src[pos + i];                                                                         // 173
  489.       sum += stack.color;                                                                                 // 174
  490.       stack = stack.next;                                                                                 // 175
  491.     }                                                                                                     // 176
  492.                                                                                                           // 177
  493.     stack = stackStart;                                                                                   // 178
  494.     for (x = 0; x < width; ++ x){                                                                         // 179
  495.       dst[pos ++] = (sum * mult) >>> shift;                                                               // 180
  496.                                                                                                           // 181
  497.       p = x + radius;                                                                                     // 182
  498.       p = start + (p < widthMinus1? p: widthMinus1);                                                      // 183
  499.       sum -= stack.color - src[p];                                                                        // 184
  500.                                                                                                           // 185
  501.       stack.color = src[p];                                                                               // 186
  502.       stack = stack.next;                                                                                 // 187
  503.     }                                                                                                     // 188
  504.   }                                                                                                       // 189
  505.                                                                                                           // 190
  506.   for (x = 0; x < width; ++ x){                                                                           // 191
  507.     pos = x;                                                                                              // 192
  508.     start = pos + width;                                                                                  // 193
  509.                                                                                                           // 194
  510.     color = dst[pos];                                                                                     // 195
  511.     sum = radius * color;                                                                                 // 196
  512.                                                                                                           // 197
  513.     stack = stackStart;                                                                                   // 198
  514.     for (i = 0; i < radius; ++ i){                                                                        // 199
  515.       stack.color = color;                                                                                // 200
  516.       stack = stack.next;                                                                                 // 201
  517.     }                                                                                                     // 202
  518.     for (i = 1; i < radius; ++ i){                                                                        // 203
  519.       stack.color = dst[start];                                                                           // 204
  520.       sum += stack.color;                                                                                 // 205
  521.       stack = stack.next;                                                                                 // 206
  522.                                                                                                           // 207
  523.       start += width;                                                                                     // 208
  524.     }                                                                                                     // 209
  525.                                                                                                           // 210
  526.     stack = stackStart;                                                                                   // 211
  527.     for (y = 0; y < height; ++ y){                                                                        // 212
  528.       dst[pos] = (sum * mult) >>> shift;                                                                  // 213
  529.                                                                                                           // 214
  530.       p = y + radius;                                                                                     // 215
  531.       p = x + ( (p < heightMinus1? p: heightMinus1) * width );                                            // 216
  532.       sum -= stack.color - dst[p];                                                                        // 217
  533.                                                                                                           // 218
  534.       stack.color = dst[p];                                                                               // 219
  535.       stack = stack.next;                                                                                 // 220
  536.                                                                                                           // 221
  537.       pos += width;                                                                                       // 222
  538.     }                                                                                                     // 223
  539.   }                                                                                                       // 224
  540.                                                                                                           // 225
  541.   return imageDst;                                                                                        // 226
  542. };                                                                                                        // 227
  543.                                                                                                           // 228
  544. CV.gaussianBlur = function(imageSrc, imageDst, imageMean, kernelSize){                                    // 229
  545.   var kernel = CV.gaussianKernel(kernelSize);                                                             // 230
  546.                                                                                                           // 231
  547.   imageDst.width = imageSrc.width;                                                                        // 232
  548.   imageDst.height = imageSrc.height;                                                                      // 233
  549.                                                                                                           // 234
  550.   imageMean.width = imageSrc.width;                                                                       // 235
  551.   imageMean.height = imageSrc.height;                                                                     // 236
  552.                                                                                                           // 237
  553.   CV.gaussianBlurFilter(imageSrc, imageMean, kernel, true);                                               // 238
  554.   CV.gaussianBlurFilter(imageMean, imageDst, kernel, false);                                              // 239
  555.                                                                                                           // 240
  556.   return imageDst;                                                                                        // 241
  557. };                                                                                                        // 242
  558.                                                                                                           // 243
  559. CV.gaussianBlurFilter = function(imageSrc, imageDst, kernel, horizontal){                                 // 244
  560.   var src = imageSrc.data, dst = imageDst.data,                                                           // 245
  561.       height = imageSrc.height, width = imageSrc.width,                                                   // 246
  562.       pos = 0, limit = kernel.length >> 1,                                                                // 247
  563.       cur, value, i, j, k;                                                                                // 248
  564.                                                                                                           // 249
  565.   for (i = 0; i < height; ++ i){                                                                          // 250
  566.                                                                                                           // 251
  567.     for (j = 0; j < width; ++ j){                                                                         // 252
  568.       value = 0.0;                                                                                        // 253
  569.                                                                                                           // 254
  570.       for (k = -limit; k <= limit; ++ k){                                                                 // 255
  571.                                                                                                           // 256
  572.         if (horizontal){                                                                                  // 257
  573.           cur = pos + k;                                                                                  // 258
  574.           if (j + k < 0){                                                                                 // 259
  575.             cur = pos;                                                                                    // 260
  576.           }                                                                                               // 261
  577.           else if (j + k >= width){                                                                       // 262
  578.             cur = pos;                                                                                    // 263
  579.           }                                                                                               // 264
  580.         }else{                                                                                            // 265
  581.           cur = pos + (k * width);                                                                        // 266
  582.           if (i + k < 0){                                                                                 // 267
  583.             cur = pos;                                                                                    // 268
  584.           }                                                                                               // 269
  585.           else if (i + k >= height){                                                                      // 270
  586.             cur = pos;                                                                                    // 271
  587.           }                                                                                               // 272
  588.         }                                                                                                 // 273
  589.                                                                                                           // 274
  590.         value += kernel[limit + k] * src[cur];                                                            // 275
  591.       }                                                                                                   // 276
  592.                                                                                                           // 277
  593.       dst[pos ++] = horizontal? value: (value + 0.5) & 0xff;                                              // 278
  594.     }                                                                                                     // 279
  595.   }                                                                                                       // 280
  596.                                                                                                           // 281
  597.   return imageDst;                                                                                        // 282
  598. };                                                                                                        // 283
  599.                                                                                                           // 284
  600. CV.gaussianKernel = function(kernelSize){                                                                 // 285
  601.   var tab =                                                                                               // 286
  602.     [ [1],                                                                                                // 287
  603.       [0.25, 0.5, 0.25],                                                                                  // 288
  604.       [0.0625, 0.25, 0.375, 0.25, 0.0625],                                                                // 289
  605.       [0.03125, 0.109375, 0.21875, 0.28125, 0.21875, 0.109375, 0.03125] ],                                // 290
  606.     kernel = [], center, sigma, scale2X, sum, x, i;                                                       // 291
  607.                                                                                                           // 292
  608.   if ( (kernelSize <= 7) && (kernelSize % 2 === 1) ){                                                     // 293
  609.     kernel = tab[kernelSize >> 1];                                                                        // 294
  610.   }else{                                                                                                  // 295
  611.     center = (kernelSize - 1.0) * 0.5;                                                                    // 296
  612.     sigma = 0.8 + (0.3 * (center - 1.0) );                                                                // 297
  613.     scale2X = -0.5 / (sigma * sigma);                                                                     // 298
  614.     sum = 0.0;                                                                                            // 299
  615.     for (i = 0; i < kernelSize; ++ i){                                                                    // 300
  616.       x = i - center;                                                                                     // 301
  617.       sum += kernel[i] = Math.exp(scale2X * x * x);                                                       // 302
  618.     }                                                                                                     // 303
  619.     sum = 1 / sum;                                                                                        // 304
  620.     for (i = 0; i < kernelSize; ++ i){                                                                    // 305
  621.       kernel[i] *= sum;                                                                                   // 306
  622.     }                                                                                                     // 307
  623.   }                                                                                                       // 308
  624.                                                                                                           // 309
  625.   return kernel;                                                                                          // 310
  626. };                                                                                                        // 311
  627.                                                                                                           // 312
  628. CV.findContours = function(imageSrc, binary){                                                             // 313
  629.   var width = imageSrc.width, height = imageSrc.height, contours = [],                                    // 314
  630.       src, deltas, pos, pix, nbd, outer, hole, i, j;                                                      // 315
  631.                                                                                                           // 316
  632.   src = CV.binaryBorder(imageSrc, binary);                                                                // 317
  633.                                                                                                           // 318
  634.   deltas = CV.neighborhoodDeltas(width + 2);                                                              // 319
  635.                                                                                                           // 320
  636.   pos = width + 3;                                                                                        // 321
  637.   nbd = 1;                                                                                                // 322
  638.                                                                                                           // 323
  639.   for (i = 0; i < height; ++ i, pos += 2){                                                                // 324
  640.                                                                                                           // 325
  641.     for (j = 0; j < width; ++ j, ++ pos){                                                                 // 326
  642.       pix = src[pos];                                                                                     // 327
  643.                                                                                                           // 328
  644.       if (0 !== pix){                                                                                     // 329
  645.         outer = hole = false;                                                                             // 330
  646.                                                                                                           // 331
  647.         if (1 === pix && 0 === src[pos - 1]){                                                             // 332
  648.           outer = true;                                                                                   // 333
  649.         }                                                                                                 // 334
  650.         else if (pix >= 1 && 0 === src[pos + 1]){                                                         // 335
  651.           hole = true;                                                                                    // 336
  652.         }                                                                                                 // 337
  653.                                                                                                           // 338
  654.         if (outer || hole){                                                                               // 339
  655.           ++ nbd;                                                                                         // 340
  656.                                                                                                           // 341
  657.           contours.push( CV.borderFollowing(src, pos, nbd, {x: j, y: i}, hole, deltas) );                 // 342
  658.         }                                                                                                 // 343
  659.       }                                                                                                   // 344
  660.     }                                                                                                     // 345
  661.   }                                                                                                       // 346
  662.                                                                                                           // 347
  663.   return contours;                                                                                        // 348
  664. };                                                                                                        // 349
  665.                                                                                                           // 350
  666. CV.borderFollowing = function(src, pos, nbd, point, hole, deltas){                                        // 351
  667.   var contour = [], pos1, pos3, pos4, s, s_end, s_prev;                                                   // 352
  668.                                                                                                           // 353
  669.   contour.hole = hole;                                                                                    // 354
  670.                                                                                                           // 355
  671.   s = s_end = hole? 0: 4;                                                                                 // 356
  672.   do{                                                                                                     // 357
  673.     s = (s - 1) & 7;                                                                                      // 358
  674.     pos1 = pos + deltas[s];                                                                               // 359
  675.     if (src[pos1] !== 0){                                                                                 // 360
  676.       break;                                                                                              // 361
  677.     }                                                                                                     // 362
  678.   }while(s !== s_end);                                                                                    // 363
  679.                                                                                                           // 364
  680.   if (s === s_end){                                                                                       // 365
  681.     src[pos] = -nbd;                                                                                      // 366
  682.     contour.push( {x: point.x, y: point.y} );                                                             // 367
  683.                                                                                                           // 368
  684.   }else{                                                                                                  // 369
  685.     pos3 = pos;                                                                                           // 370
  686.     s_prev = s ^ 4;                                                                                       // 371
  687.                                                                                                           // 372
  688.     while(true){                                                                                          // 373
  689.       s_end = s;                                                                                          // 374
  690.                                                                                                           // 375
  691.       do{                                                                                                 // 376
  692.         pos4 = pos3 + deltas[++ s];                                                                       // 377
  693.       }while(src[pos4] === 0);                                                                            // 378
  694.                                                                                                           // 379
  695.       s &= 7;                                                                                             // 380
  696.                                                                                                           // 381
  697.       if ( ( (s - 1) >>> 0) < (s_end >>> 0) ){                                                            // 382
  698.         src[pos3] = -nbd;                                                                                 // 383
  699.       }                                                                                                   // 384
  700.       else if (src[pos3] === 1){                                                                          // 385
  701.         src[pos3] = nbd;                                                                                  // 386
  702.       }                                                                                                   // 387
  703.                                                                                                           // 388
  704.       contour.push( {x: point.x, y: point.y} );                                                           // 389
  705.                                                                                                           // 390
  706.       s_prev = s;                                                                                         // 391
  707.                                                                                                           // 392
  708.       point.x += CV.neighborhood[s][0];                                                                   // 393
  709.       point.y += CV.neighborhood[s][1];                                                                   // 394
  710.                                                                                                           // 395
  711.       if ( (pos4 === pos) && (pos3 === pos1) ){                                                           // 396
  712.         break;                                                                                            // 397
  713.       }                                                                                                   // 398
  714.                                                                                                           // 399
  715.       pos3 = pos4;                                                                                        // 400
  716.       s = (s + 4) & 7;                                                                                    // 401
  717.     }                                                                                                     // 402
  718.   }                                                                                                       // 403
  719.                                                                                                           // 404
  720.   return contour;                                                                                         // 405
  721. };                                                                                                        // 406
  722.                                                                                                           // 407
  723. CV.neighborhood =                                                                                         // 408
  724.   [ [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1], [0, 1], [1, 1] ];                               // 409
  725.                                                                                                           // 410
  726. CV.neighborhoodDeltas = function(width){                                                                  // 411
  727.   var deltas = [], len = CV.neighborhood.length, i = 0;                                                   // 412
  728.                                                                                                           // 413
  729.   for (; i < len; ++ i){                                                                                  // 414
  730.     deltas[i] = CV.neighborhood[i][0] + (CV.neighborhood[i][1] * width);                                  // 415
  731.   }                                                                                                       // 416
  732.                                                                                                           // 417
  733.   return deltas.concat(deltas);                                                                           // 418
  734. };                                                                                                        // 419
  735.                                                                                                           // 420
  736. CV.approxPolyDP = function(contour, epsilon){                                                             // 421
  737.   var slice = {start_index: 0, end_index: 0},                                                             // 422
  738.       right_slice = {start_index: 0, end_index: 0},                                                       // 423
  739.       poly = [], stack = [], len = contour.length,                                                        // 424
  740.       pt, start_pt, end_pt, dist, max_dist, le_eps,                                                       // 425
  741.       dx, dy, i, j, k;                                                                                    // 426
  742.                                                                                                           // 427
  743.   epsilon *= epsilon;                                                                                     // 428
  744.                                                                                                           // 429
  745.   k = 0;                                                                                                  // 430
  746.                                                                                                           // 431
  747.   for (i = 0; i < 3; ++ i){                                                                               // 432
  748.     max_dist = 0;                                                                                         // 433
  749.                                                                                                           // 434
  750.     k = (k + right_slice.start_index) % len;                                                              // 435
  751.     start_pt = contour[k];                                                                                // 436
  752.     if (++ k === len) {k = 0;}                                                                            // 437
  753.                                                                                                           // 438
  754.     for (j = 1; j < len; ++ j){                                                                           // 439
  755.       pt = contour[k];                                                                                    // 440
  756.       if (++ k === len) {k = 0;}                                                                          // 441
  757.                                                                                                           // 442
  758.       dx = pt.x - start_pt.x;                                                                             // 443
  759.       dy = pt.y - start_pt.y;                                                                             // 444
  760.       dist = dx * dx + dy * dy;                                                                           // 445
  761.                                                                                                           // 446
  762.       if (dist > max_dist){                                                                               // 447
  763.         max_dist = dist;                                                                                  // 448
  764.         right_slice.start_index = j;                                                                      // 449
  765.       }                                                                                                   // 450
  766.     }                                                                                                     // 451
  767.   }                                                                                                       // 452
  768.                                                                                                           // 453
  769.   if (max_dist <= epsilon){                                                                               // 454
  770.     poly.push( {x: start_pt.x, y: start_pt.y} );                                                          // 455
  771.                                                                                                           // 456
  772.   }else{                                                                                                  // 457
  773.     slice.start_index = k;                                                                                // 458
  774.     slice.end_index = (right_slice.start_index += slice.start_index);                                     // 459
  775.                                                                                                           // 460
  776.     right_slice.start_index -= right_slice.start_index >= len? len: 0;                                    // 461
  777.     right_slice.end_index = slice.start_index;                                                            // 462
  778.     if (right_slice.end_index < right_slice.start_index){                                                 // 463
  779.       right_slice.end_index += len;                                                                       // 464
  780.     }                                                                                                     // 465
  781.                                                                                                           // 466
  782.     stack.push( {start_index: right_slice.start_index, end_index: right_slice.end_index} );               // 467
  783.     stack.push( {start_index: slice.start_index, end_index: slice.end_index} );                           // 468
  784.   }                                                                                                       // 469
  785.                                                                                                           // 470
  786.   while(stack.length !== 0){                                                                              // 471
  787.     slice = stack.pop();                                                                                  // 472
  788.                                                                                                           // 473
  789.     end_pt = contour[slice.end_index % len];                                                              // 474
  790.     start_pt = contour[k = slice.start_index % len];                                                      // 475
  791.     if (++ k === len) {k = 0;}                                                                            // 476
  792.                                                                                                           // 477
  793.     if (slice.end_index <= slice.start_index + 1){                                                        // 478
  794.       le_eps = true;                                                                                      // 479
  795.                                                                                                           // 480
  796.     }else{                                                                                                // 481
  797.       max_dist = 0;                                                                                       // 482
  798.                                                                                                           // 483
  799.       dx = end_pt.x - start_pt.x;                                                                         // 484
  800.       dy = end_pt.y - start_pt.y;                                                                         // 485
  801.                                                                                                           // 486
  802.       for (i = slice.start_index + 1; i < slice.end_index; ++ i){                                         // 487
  803.         pt = contour[k];                                                                                  // 488
  804.         if (++ k === len) {k = 0;}                                                                        // 489
  805.                                                                                                           // 490
  806.         dist = Math.abs( (pt.y - start_pt.y) * dx - (pt.x - start_pt.x) * dy);                            // 491
  807.                                                                                                           // 492
  808.         if (dist > max_dist){                                                                             // 493
  809.           max_dist = dist;                                                                                // 494
  810.           right_slice.start_index = i;                                                                    // 495
  811.         }                                                                                                 // 496
  812.       }                                                                                                   // 497
  813.                                                                                                           // 498
  814.       le_eps = max_dist * max_dist <= epsilon * (dx * dx + dy * dy);                                      // 499
  815.     }                                                                                                     // 500
  816.                                                                                                           // 501
  817.     if (le_eps){                                                                                          // 502
  818.       poly.push( {x: start_pt.x, y: start_pt.y} );                                                        // 503
  819.                                                                                                           // 504
  820.     }else{                                                                                                // 505
  821.       right_slice.end_index = slice.end_index;                                                            // 506
  822.       slice.end_index = right_slice.start_index;                                                          // 507
  823.                                                                                                           // 508
  824.       stack.push( {start_index: right_slice.start_index, end_index: right_slice.end_index} );             // 509
  825.       stack.push( {start_index: slice.start_index, end_index: slice.end_index} );                         // 510
  826.     }                                                                                                     // 511
  827.   }                                                                                                       // 512
  828.                                                                                                           // 513
  829.   return poly;                                                                                            // 514
  830. };                                                                                                        // 515
  831.                                                                                                           // 516
  832. CV.warp = function(imageSrc, imageDst, contour, warpSize){                                                // 517
  833.   var src = imageSrc.data, dst = imageDst.data,                                                           // 518
  834.       width = imageSrc.width, height = imageSrc.height,                                                   // 519
  835.       pos = 0,                                                                                            // 520
  836.       sx1, sx2, dx1, dx2, sy1, sy2, dy1, dy2, p1, p2, p3, p4,                                             // 521
  837.       m, r, s, t, u, v, w, x, y, i, j;                                                                    // 522
  838.                                                                                                           // 523
  839.   m = CV.getPerspectiveTransform(contour, warpSize - 1);                                                  // 524
  840.                                                                                                           // 525
  841.   r = m[8];                                                                                               // 526
  842.   s = m[2];                                                                                               // 527
  843.   t = m[5];                                                                                               // 528
  844.                                                                                                           // 529
  845.   for (i = 0; i < warpSize; ++ i){                                                                        // 530
  846.     r += m[7];                                                                                            // 531
  847.     s += m[1];                                                                                            // 532
  848.     t += m[4];                                                                                            // 533
  849.                                                                                                           // 534
  850.     u = r;                                                                                                // 535
  851.     v = s;                                                                                                // 536
  852.     w = t;                                                                                                // 537
  853.                                                                                                           // 538
  854.     for (j = 0; j < warpSize; ++ j){                                                                      // 539
  855.       u += m[6];                                                                                          // 540
  856.       v += m[0];                                                                                          // 541
  857.       w += m[3];                                                                                          // 542
  858.                                                                                                           // 543
  859.       x = v / u;                                                                                          // 544
  860.       y = w / u;                                                                                          // 545
  861.                                                                                                           // 546
  862.       sx1 = x >>> 0;                                                                                      // 547
  863.       sx2 = (sx1 === width - 1)? sx1: sx1 + 1;                                                            // 548
  864.       dx1 = x - sx1;                                                                                      // 549
  865.       dx2 = 1.0 - dx1;                                                                                    // 550
  866.                                                                                                           // 551
  867.       sy1 = y >>> 0;                                                                                      // 552
  868.       sy2 = (sy1 === height - 1)? sy1: sy1 + 1;                                                           // 553
  869.       dy1 = y - sy1;                                                                                      // 554
  870.       dy2 = 1.0 - dy1;                                                                                    // 555
  871.                                                                                                           // 556
  872.       p1 = p2 = sy1 * width;                                                                              // 557
  873.       p3 = p4 = sy2 * width;                                                                              // 558
  874.                                                                                                           // 559
  875.       dst[pos ++] =                                                                                       // 560
  876.         (dy2 * (dx2 * src[p1 + sx1] + dx1 * src[p2 + sx2]) +                                              // 561
  877.          dy1 * (dx2 * src[p3 + sx1] + dx1 * src[p4 + sx2]) ) & 0xff;                                      // 562
  878.                                                                                                           // 563
  879.     }                                                                                                     // 564
  880.   }                                                                                                       // 565
  881.                                                                                                           // 566
  882.   imageDst.width = warpSize;                                                                              // 567
  883.   imageDst.height = warpSize;                                                                             // 568
  884.                                                                                                           // 569
  885.   return imageDst;                                                                                        // 570
  886. };                                                                                                        // 571
  887.                                                                                                           // 572
  888. CV.getPerspectiveTransform = function(src, size){                                                         // 573
  889.   var rq = CV.square2quad(src);                                                                           // 574
  890.                                                                                                           // 575
  891.   rq[0] /= size;                                                                                          // 576
  892.   rq[1] /= size;                                                                                          // 577
  893.   rq[3] /= size;                                                                                          // 578
  894.   rq[4] /= size;                                                                                          // 579
  895.   rq[6] /= size;                                                                                          // 580
  896.   rq[7] /= size;                                                                                          // 581
  897.                                                                                                           // 582
  898.   return rq;                                                                                              // 583
  899. };                                                                                                        // 584
  900.                                                                                                           // 585
  901. CV.square2quad = function(src){                                                                           // 586
  902.   var sq = [], px, py, dx1, dx2, dy1, dy2, den;                                                           // 587
  903.                                                                                                           // 588
  904.   px = src[0].x - src[1].x + src[2].x - src[3].x;                                                         // 589
  905.   py = src[0].y - src[1].y + src[2].y - src[3].y;                                                         // 590
  906.                                                                                                           // 591
  907.   if (0 === px && 0 === py){                                                                              // 592
  908.     sq[0] = src[1].x - src[0].x;                                                                          // 593
  909.     sq[1] = src[2].x - src[1].x;                                                                          // 594
  910.     sq[2] = src[0].x;                                                                                     // 595
  911.     sq[3] = src[1].y - src[0].y;                                                                          // 596
  912.     sq[4] = src[2].y - src[1].y;                                                                          // 597
  913.     sq[5] = src[0].y;                                                                                     // 598
  914.     sq[6] = 0;                                                                                            // 599
  915.     sq[7] = 0;                                                                                            // 600
  916.     sq[8] = 1;                                                                                            // 601
  917.                                                                                                           // 602
  918.   }else{                                                                                                  // 603
  919.     dx1 = src[1].x - src[2].x;                                                                            // 604
  920.     dx2 = src[3].x - src[2].x;                                                                            // 605
  921.     dy1 = src[1].y - src[2].y;                                                                            // 606
  922.     dy2 = src[3].y - src[2].y;                                                                            // 607
  923.     den = dx1 * dy2 - dx2 * dy1;                                                                          // 608
  924.                                                                                                           // 609
  925.     sq[6] = (px * dy2 - dx2 * py) / den;                                                                  // 610
  926.     sq[7] = (dx1 * py - px * dy1) / den;                                                                  // 611
  927.     sq[8] = 1;                                                                                            // 612
  928.     sq[0] = src[1].x - src[0].x + sq[6] * src[1].x;                                                       // 613
  929.     sq[1] = src[3].x - src[0].x + sq[7] * src[3].x;                                                       // 614
  930.     sq[2] = src[0].x;                                                                                     // 615
  931.     sq[3] = src[1].y - src[0].y + sq[6] * src[1].y;                                                       // 616
  932.     sq[4] = src[3].y - src[0].y + sq[7] * src[3].y;                                                       // 617
  933.     sq[5] = src[0].y;                                                                                     // 618
  934.   }                                                                                                       // 619
  935.                                                                                                           // 620
  936.   return sq;                                                                                              // 621
  937. };                                                                                                        // 622
  938.                                                                                                           // 623
  939. CV.isContourConvex = function(contour){                                                                   // 624
  940.   var orientation = 0, convex = true,                                                                     // 625
  941.       len = contour.length, i = 0, j = 0,                                                                 // 626
  942.       cur_pt, prev_pt, dxdy0, dydx0, dx0, dy0, dx, dy;                                                    // 627
  943.                                                                                                           // 628
  944.   prev_pt = contour[len - 1];                                                                             // 629
  945.   cur_pt = contour[0];                                                                                    // 630
  946.                                                                                                           // 631
  947.   dx0 = cur_pt.x - prev_pt.x;                                                                             // 632
  948.   dy0 = cur_pt.y - prev_pt.y;                                                                             // 633
  949.                                                                                                           // 634
  950.   for (; i < len; ++ i){                                                                                  // 635
  951.     if (++ j === len) {j = 0;}                                                                            // 636
  952.                                                                                                           // 637
  953.     prev_pt = cur_pt;                                                                                     // 638
  954.     cur_pt = contour[j];                                                                                  // 639
  955.                                                                                                           // 640
  956.     dx = cur_pt.x - prev_pt.x;                                                                            // 641
  957.     dy = cur_pt.y - prev_pt.y;                                                                            // 642
  958.     dxdy0 = dx * dy0;                                                                                     // 643
  959.     dydx0 = dy * dx0;                                                                                     // 644
  960.                                                                                                           // 645
  961.     orientation |= dydx0 > dxdy0? 1: (dydx0 < dxdy0? 2: 3);                                               // 646
  962.                                                                                                           // 647
  963.     if (3 === orientation){                                                                               // 648
  964.         convex = false;                                                                                   // 649
  965.         break;                                                                                            // 650
  966.     }                                                                                                     // 651
  967.                                                                                                           // 652
  968.     dx0 = dx;                                                                                             // 653
  969.     dy0 = dy;                                                                                             // 654
  970.   }                                                                                                       // 655
  971.                                                                                                           // 656
  972.   return convex;                                                                                          // 657
  973. };                                                                                                        // 658
  974.                                                                                                           // 659
  975. CV.perimeter = function(poly){                                                                            // 660
  976.   var len = poly.length, i = 0, j = len - 1,                                                              // 661
  977.       p = 0.0, dx, dy;                                                                                    // 662
  978.                                                                                                           // 663
  979.   for (; i < len; j = i ++){                                                                              // 664
  980.     dx = poly[i].x - poly[j].x;                                                                           // 665
  981.     dy = poly[i].y - poly[j].y;                                                                           // 666
  982.                                                                                                           // 667
  983.     p += Math.sqrt(dx * dx + dy * dy) ;                                                                   // 668
  984.   }                                                                                                       // 669
  985.                                                                                                           // 670
  986.   return p;                                                                                               // 671
  987. };                                                                                                        // 672
  988.                                                                                                           // 673
  989. CV.minEdgeLength = function(poly){                                                                        // 674
  990.   var len = poly.length, i = 0, j = len - 1,                                                              // 675
  991.       min = Infinity, d, dx, dy;                                                                          // 676
  992.                                                                                                           // 677
  993.   for (; i < len; j = i ++){                                                                              // 678
  994.     dx = poly[i].x - poly[j].x;                                                                           // 679
  995.     dy = poly[i].y - poly[j].y;                                                                           // 680
  996.                                                                                                           // 681
  997.     d = dx * dx + dy * dy;                                                                                // 682
  998.                                                                                                           // 683
  999.     if (d < min){                                                                                         // 684
  1000.       min = d;                                                                                            // 685
  1001.     }                                                                                                     // 686
  1002.   }                                                                                                       // 687
  1003.                                                                                                           // 688
  1004.   return Math.sqrt(min);                                                                                  // 689
  1005. };                                                                                                        // 690
  1006.                                                                                                           // 691
  1007. CV.countNonZero = function(imageSrc, square){                                                             // 692
  1008.   var src = imageSrc.data, height = square.height, width = square.width,                                  // 693
  1009.       pos = square.x + (square.y * imageSrc.width),                                                       // 694
  1010.       span = imageSrc.width - width,                                                                      // 695
  1011.       nz = 0, i, j;                                                                                       // 696
  1012.                                                                                                           // 697
  1013.   for (i = 0; i < height; ++ i){                                                                          // 698
  1014.                                                                                                           // 699
  1015.     for (j = 0; j < width; ++ j){                                                                         // 700
  1016.                                                                                                           // 701
  1017.       if ( 0 !== src[pos ++] ){                                                                           // 702
  1018.         ++ nz;                                                                                            // 703
  1019.       }                                                                                                   // 704
  1020.     }                                                                                                     // 705
  1021.                                                                                                           // 706
  1022.     pos += span;                                                                                          // 707
  1023.   }                                                                                                       // 708
  1024.                                                                                                           // 709
  1025.   return nz;                                                                                              // 710
  1026. };                                                                                                        // 711
  1027.                                                                                                           // 712
  1028. CV.binaryBorder = function(imageSrc, dst){                                                                // 713
  1029.   var src = imageSrc.data, height = imageSrc.height, width = imageSrc.width,                              // 714
  1030.       posSrc = 0, posDst = 0, i, j;                                                                       // 715
  1031.                                                                                                           // 716
  1032.   for (j = -2; j < width; ++ j){                                                                          // 717
  1033.     dst[posDst ++] = 0;                                                                                   // 718
  1034.   }                                                                                                       // 719
  1035.                                                                                                           // 720
  1036.   for (i = 0; i < height; ++ i){                                                                          // 721
  1037.     dst[posDst ++] = 0;                                                                                   // 722
  1038.                                                                                                           // 723
  1039.     for (j = 0; j < width; ++ j){                                                                         // 724
  1040.       dst[posDst ++] = (0 === src[posSrc ++]? 0: 1);                                                      // 725
  1041.     }                                                                                                     // 726
  1042.                                                                                                           // 727
  1043.     dst[posDst ++] = 0;                                                                                   // 728
  1044.   }                                                                                                       // 729
  1045.                                                                                                           // 730
  1046.   for (j = -2; j < width; ++ j){                                                                          // 731
  1047.     dst[posDst ++] = 0;                                                                                   // 732
  1048.   }                                                                                                       // 733
  1049.                                                                                                           // 734
  1050.   return dst;                                                                                             // 735
  1051. };                                                                                                        // 736
  1052.                                                                                                           // 737
  1053. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1054.  
  1055. }).call(this);
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062. (function () {
  1063.  
  1064. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1065. //                                                                                                        //
  1066. // packages/js-aruco/posit1.js                                                                            //
  1067. //                                                                                                        //
  1068. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1069.                                                                                                           //
  1070. /*
  1071.                                                                                                        // 1
  1072. Copyright (c) 2012 Juan Mellado
  1073.                                                                           // 2
  1074.  
  1075.                                                                                                          // 3
  1076. Permission is hereby granted, free of charge, to any person obtaining a copy
  1077.                              // 4
  1078. of this software and associated documentation files (the "Software"), to deal
  1079.                             // 5
  1080. in the Software without restriction, including without limitation the rights
  1081.                              // 6
  1082. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  1083.                                 // 7
  1084. copies of the Software, and to permit persons to whom the Software is
  1085.                                     // 8
  1086. furnished to do so, subject to the following conditions:
  1087.                                                  // 9
  1088.  
  1089.                                                                                                          // 10
  1090. The above copyright notice and this permission notice shall be included in
  1091.                                // 11
  1092. all copies or substantial portions of the Software.
  1093.                                                       // 12
  1094.  
  1095.                                                                                                          // 13
  1096. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1097.                                // 14
  1098. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1099.                                  // 15
  1100. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  1101.                               // 16
  1102. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1103.                                    // 17
  1104. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  1105.                             // 18
  1106. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  1107.                                 // 19
  1108. THE SOFTWARE.
  1109.                                                                                             // 20
  1110. */
  1111.                                                                                                        // 21
  1112.  
  1113.                                                                                                          // 22
  1114. /*
  1115.                                                                                                        // 23
  1116. References:
  1117.                                                                                               // 24
  1118. - "Iterative Pose Estimation using Coplanar Feature Points"
  1119.                                               // 25
  1120.   Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis
  1121.                                                    // 26
  1122.   http://www.cfar.umd.edu/~daniel/daniel_papersfordownload/CoplanarPts.pdf
  1123.                                // 27
  1124. */
  1125.                                                                                                        // 28
  1126.  
  1127.                                                                                                          // 29
  1128. var POS = POS || {};
  1129.                                                                                      // 30
  1130.  
  1131.                                                                                                          // 31
  1132. POS.Posit = function(modelSize, focalLength){
  1133.                                                             // 32
  1134.   this.objectPoints = this.buildModel(modelSize);
  1135.                                                         // 33
  1136.   this.focalLength = focalLength;
  1137.                                                                         // 34
  1138.  
  1139.                                                                                                          // 35
  1140.   this.objectVectors = [];
  1141.                                                                                // 36
  1142.   this.objectNormal = [];
  1143.                                                                                 // 37
  1144.   this.objectMatrix = [[],[],[]];
  1145.                                                                         // 38
  1146.  
  1147.                                                                                                        // 39
  1148.   this.init();
  1149.                                                                                            // 40
  1150. };
  1151.                                                                                                        // 41
  1152.  
  1153.                                                                                                          // 42
  1154. POS.Posit.prototype.buildModel = function(modelSize){
  1155.                                                     // 43
  1156.   var half = modelSize / 2.0;
  1157.                                                                             // 44
  1158.  
  1159.                                                                                                        // 45
  1160.   return [
  1161.                                                                                                // 46
  1162.     [-half,  half, 0.0],
  1163.                                                                                  // 47
  1164.     [ half,  half, 0.0],
  1165.                                                                                  // 48
  1166.     [ half, -half, 0.0],
  1167.                                                                                  // 49
  1168.     [-half, -half, 0.0] ];
  1169.                                                                                // 50
  1170. };
  1171.                                                                                                        // 51
  1172.  
  1173.                                                                                                          // 52
  1174. POS.Posit.prototype.init = function(){
  1175.                                                                    // 53
  1176.   var np = this.objectPoints.length,
  1177.                                                                      // 54
  1178.       vectors = [], n = [], len = 0.0, row = 2, i;
  1179.                                                        // 55
  1180.  
  1181.                                                                                                        // 56
  1182.   for (i = 0; i < np; ++ i){
  1183.                                                                              // 57
  1184.     this.objectVectors[i] = [this.objectPoints[i][0] - this.objectPoints[0][0],
  1185.                           // 58
  1186.                              this.objectPoints[i][1] - this.objectPoints[0][1],
  1187.                           // 59
  1188.                              this.objectPoints[i][2] - this.objectPoints[0][2]];
  1189.                          // 60
  1190.                              
  1191.                                                                             // 61
  1192.     vectors[i] = [this.objectVectors[i][0],
  1193.                                                               // 62
  1194.                   this.objectVectors[i][1],
  1195.                                                               // 63
  1196.                   this.objectVectors[i][2]];
  1197.                                                              // 64
  1198.   }
  1199.                                                                                                       // 65
  1200.  
  1201.                                                                                                          // 66
  1202.   while(0.0 === len){
  1203.                                                                                     // 67
  1204.     n[0] = this.objectVectors[1][1] * this.objectVectors[row][2] -
  1205.                                        // 68
  1206.            this.objectVectors[1][2] * this.objectVectors[row][1];
  1207.                                         // 69
  1208.     n[1] = this.objectVectors[1][2] * this.objectVectors[row][0] -
  1209.                                        // 70
  1210.            this.objectVectors[1][0] * this.objectVectors[row][2];
  1211.                                         // 71
  1212.     n[2] = this.objectVectors[1][0] * this.objectVectors[row][1] -
  1213.                                        // 72
  1214.            this.objectVectors[1][1] * this.objectVectors[row][0];
  1215.                                         // 73
  1216.    
  1217.                                                                                                      // 74
  1218.     len = Math.sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
  1219.                                             // 75
  1220.    
  1221.                                                                                                      // 76
  1222.     ++ row;
  1223.                                                                                               // 77
  1224.   }
  1225.                                                                                                       // 78
  1226.  
  1227.                                                                                                          // 79
  1228.   for (i = 0; i < 3; ++ i){
  1229.                                                                               // 80
  1230.     this.objectNormal[i] = n[i] / len;
  1231.                                                                    // 81
  1232.   }
  1233.                                                                                                       // 82
  1234.  
  1235.                                                                                                          // 83
  1236.   POS.pseudoInverse(vectors, np, this.objectMatrix);
  1237.                                                      // 84
  1238. };
  1239.                                                                                                        // 85
  1240.  
  1241.                                                                                                          // 86
  1242. POS.Posit.prototype.pose = function(imagePoints){
  1243.                                                         // 87
  1244.   var posRotation1 = [[],[],[]], posRotation2 = [[],[],[]], posTranslation = [],
  1245.                          // 88
  1246.       rotation1 = [[],[],[]], rotation2 = [[],[],[]], translation1 = [], translation2 = [],
  1247.               // 89
  1248.       error1, error2, valid1, valid2, i, j;
  1249.                                                               // 90
  1250.  
  1251.                                                                                                          // 91
  1252.   this.pos(imagePoints, posRotation1, posRotation2, posTranslation);
  1253.                                      // 92
  1254.  
  1255.                                                                                                          // 93
  1256.   valid1 = this.isValid(posRotation1, posTranslation);
  1257.                                                    // 94
  1258.   if (valid1){
  1259.                                                                                            // 95
  1260.     error1 = this.iterate(imagePoints, posRotation1, posTranslation, rotation1, translation1);
  1261.            // 96
  1262.   }else{
  1263.                                                                                                  // 97
  1264.     error1 = {euclidean: -1.0, pixels: -1, maximum: -1.0};
  1265.                                                // 98
  1266.   }
  1267.                                                                                                       // 99
  1268.  
  1269.                                                                                                        // 100
  1270.   valid2 = this.isValid(posRotation2, posTranslation);
  1271.                                                    // 101
  1272.   if (valid2){
  1273.                                                                                            // 102
  1274.     error2 = this.iterate(imagePoints, posRotation2, posTranslation, rotation2, translation2);
  1275.            // 103
  1276.   }else{
  1277.                                                                                                  // 104
  1278.     error2 = {euclidean: -1.0, pixels: -1, maximum: -1.0};
  1279.                                                // 105
  1280.   }
  1281.                                                                                                       // 106
  1282.  
  1283.                                                                                                          // 107
  1284.   for (i = 0; i < 3; ++ i){
  1285.                                                                               // 108
  1286.     for (j = 0; j < 3; ++ j){
  1287.                                                                             // 109
  1288.       if (valid1){
  1289.                                                                                        // 110
  1290.         translation1[i] -= rotation1[i][j] * this.objectPoints[0][j];
  1291.                                     // 111
  1292.       }
  1293.                                                                                                   // 112
  1294.       if (valid2){
  1295.                                                                                        // 113
  1296.         translation2[i] -= rotation2[i][j] * this.objectPoints[0][j];
  1297.                                     // 114
  1298.       }
  1299.                                                                                                   // 115
  1300.     }
  1301.                                                                                                     // 116
  1302.   }
  1303.                                                                                                       // 117
  1304.  
  1305.                                                                                                          // 118
  1306.   return error1.euclidean < error2.euclidean?
  1307.                                                             // 119
  1308.     new POS.Pose(error1.pixels, rotation1, translation1, error2.pixels, rotation2, translation2):
  1309.         // 120
  1310.     new POS.Pose(error2.pixels, rotation2, translation2, error1.pixels, rotation1, translation1);
  1311.         // 121
  1312. };
  1313.                                                                                                        // 122
  1314.  
  1315.                                                                                                          // 123
  1316. POS.Posit.prototype.pos = function(imagePoints, rotation1, rotation2, translation){
  1317.                       // 124
  1318.   var np = this.objectPoints.length, imageVectors = [],
  1319.                                                   // 125
  1320.       i0 = [], j0 = [], ivec = [], jvec = [], row1 = [], row2 = [], row3 = [],
  1321.                            // 126
  1322.       i0i0, j0j0, i0j0, delta, q, lambda, mu, scale, i, j;
  1323.                                                // 127
  1324.  
  1325.                                                                                                          // 128
  1326.   for (i = 0; i < np; ++ i){
  1327.                                                                              // 129
  1328.     imageVectors[i] = [imagePoints[i].x - imagePoints[0].x,
  1329.                                               // 130
  1330.                        imagePoints[i].y - imagePoints[0].y];
  1331.                                              // 131
  1332.   }
  1333.                                                                                                       // 132
  1334.  
  1335.                                                                                                          // 133
  1336.   //i0 and j0
  1337.                                                                                             // 134
  1338.   for (i = 0; i < 3; ++ i){
  1339.                                                                               // 135
  1340.     i0[i] = 0.0;
  1341.                                                                                          // 136
  1342.     j0[i] = 0.0;
  1343.                                                                                          // 137
  1344.     for (j = 0; j < np; ++ j){
  1345.                                                                            // 138
  1346.       i0[i] += this.objectMatrix[i][j] * imageVectors[j][0];
  1347.                                              // 139
  1348.       j0[i] += this.objectMatrix[i][j] * imageVectors[j][1];
  1349.                                              // 140
  1350.     }
  1351.                                                                                                     // 141
  1352.   }
  1353.                                                                                                       // 142
  1354.  
  1355.                                                                                                          // 143
  1356.   i0i0 = i0[0] * i0[0] + i0[1] * i0[1] + i0[2] * i0[2];
  1357.                                                   // 144
  1358.   j0j0 = j0[0] * j0[0] + j0[1] * j0[1] + j0[2] * j0[2];
  1359.                                                   // 145
  1360.   i0j0 = i0[0] * j0[0] + i0[1] * j0[1] + i0[2] * j0[2];
  1361.                                                   // 146
  1362.  
  1363.                                                                                                          // 147
  1364.   //Lambda and mu
  1365.                                                                                         // 148
  1366.   delta = (j0j0 - i0i0) * (j0j0 - i0i0) + 4.0 * (i0j0 * i0j0);
  1367.                                            // 149
  1368.  
  1369.                                                                                                        // 150
  1370.   if (j0j0 - i0i0 >= 0.0){
  1371.                                                                                // 151
  1372.     q = (j0j0 - i0i0 + Math.sqrt(delta) ) / 2.0;
  1373.                                                          // 152
  1374.   }else{
  1375.                                                                                                  // 153
  1376.     q = (j0j0 - i0i0 - Math.sqrt(delta) ) / 2.0;
  1377.                                                          // 154
  1378.   }
  1379.                                                                                                       // 155
  1380.  
  1381.                                                                                                        // 156
  1382.   if (q >= 0.0){
  1383.                                                                                          // 157
  1384.     lambda = Math.sqrt(q);
  1385.                                                                                // 158
  1386.     if (0.0 === lambda){
  1387.                                                                                  // 159
  1388.       mu = 0.0;
  1389.                                                                                           // 160
  1390.     }else{
  1391.                                                                                                // 161
  1392.       mu = -i0j0 / lambda;
  1393.                                                                                // 162
  1394.     }
  1395.                                                                                                     // 163
  1396.   }else{
  1397.                                                                                                  // 164
  1398.     lambda = Math.sqrt( -(i0j0 * i0j0) / q);
  1399.                                                              // 165
  1400.     if (0.0 === lambda){
  1401.                                                                                  // 166
  1402.       mu = Math.sqrt(i0i0 - j0j0);
  1403.                                                                        // 167
  1404.     }else{
  1405.                                                                                                // 168
  1406.       mu = -i0j0 / lambda;
  1407.                                                                                // 169
  1408.     }
  1409.                                                                                                     // 170
  1410.   }
  1411.                                                                                                       // 171
  1412.  
  1413.                                                                                                          // 172
  1414.   //First rotation
  1415.                                                                                        // 173
  1416.   for (i = 0; i < 3; ++ i){
  1417.                                                                               // 174
  1418.     ivec[i] = i0[i] + lambda * this.objectNormal[i];
  1419.                                                      // 175
  1420.     jvec[i] = j0[i] + mu * this.objectNormal[i];
  1421.                                                          // 176
  1422.   }
  1423.                                                                                                       // 177
  1424.  
  1425.                                                                                                        // 178
  1426.   scale = Math.sqrt(ivec[0] * ivec[0] + ivec[1] * ivec[1] + ivec[2] * ivec[2]);
  1427.                           // 179
  1428.  
  1429.                                                                                                        // 180
  1430.   for (i = 0; i < 3; ++ i){
  1431.                                                                               // 181
  1432.     row1[i] = ivec[i] / scale;
  1433.                                                                            // 182
  1434.     row2[i] = jvec[i] / scale;
  1435.                                                                            // 183
  1436.   }
  1437.                                                                                                       // 184
  1438.  
  1439.                                                                                                        // 185
  1440.   row3[0] = row1[1] * row2[2] - row1[2] * row2[1];
  1441.                                                        // 186
  1442.   row3[1] = row1[2] * row2[0] - row1[0] * row2[2];
  1443.                                                        // 187
  1444.   row3[2] = row1[0] * row2[1] - row1[1] * row2[0];
  1445.                                                        // 188
  1446.  
  1447.                                                                                                          // 189
  1448.   for (i = 0; i < 3; ++ i){
  1449.                                                                               // 190
  1450.     rotation1[0][i] = row1[i];
  1451.                                                                            // 191
  1452.     rotation1[1][i] = row2[i];
  1453.                                                                            // 192
  1454.     rotation1[2][i] = row3[i];
  1455.                                                                            // 193
  1456.   }
  1457.                                                                                                       // 194
  1458.  
  1459.                                                                                                          // 195
  1460.   //Second rotation
  1461.                                                                                       // 196
  1462.   for (i = 0; i < 3; ++ i){
  1463.                                                                               // 197
  1464.     ivec[i] = i0[i] - lambda * this.objectNormal[i];
  1465.                                                      // 198
  1466.     jvec[i] = j0[i] - mu * this.objectNormal[i];
  1467.                                                          // 199
  1468.   }
  1469.                                                                                                       // 200
  1470.  
  1471.                                                                                                        // 201
  1472.   for (i = 0; i < 3; ++ i){
  1473.                                                                               // 202
  1474.     row1[i] = ivec[i] / scale;
  1475.                                                                            // 203
  1476.     row2[i] = jvec[i] / scale;
  1477.                                                                            // 204
  1478.   }
  1479.                                                                                                       // 205
  1480.  
  1481.                                                                                                        // 206
  1482.   row3[0] = row1[1] * row2[2] - row1[2] * row2[1];
  1483.                                                        // 207
  1484.   row3[1] = row1[2] * row2[0] - row1[0] * row2[2];
  1485.                                                        // 208
  1486.   row3[2] = row1[0] * row2[1] - row1[1] * row2[0];
  1487.                                                        // 209
  1488.  
  1489.                                                                                                        // 210
  1490.   for (i = 0; i < 3; ++ i){
  1491.                                                                               // 211
  1492.     rotation2[0][i] = row1[i];
  1493.                                                                            // 212
  1494.     rotation2[1][i] = row2[i];
  1495.                                                                            // 213
  1496.     rotation2[2][i] = row3[i];
  1497.                                                                            // 214
  1498.   }
  1499.                                                                                                       // 215
  1500.  
  1501.                                                                                                          // 216
  1502.   //Translation
  1503.                                                                                           // 217
  1504.   translation[0] = imagePoints[0].x / scale;
  1505.                                                              // 218
  1506.   translation[1] = imagePoints[0].y / scale;
  1507.                                                              // 219
  1508.   translation[2] = this.focalLength / scale;
  1509.                                                              // 220
  1510. };
  1511.                                                                                                        // 221
  1512.  
  1513.                                                                                                          // 222
  1514. POS.Posit.prototype.isValid = function(rotation, translation){
  1515.                                            // 223
  1516.   var np = this.objectPoints.length, zmin = Infinity, i = 0, zi;
  1517.                                          // 224
  1518.  
  1519.                                                                                                          // 225
  1520.   for (; i < np; ++ i){
  1521.                                                                                   // 226
  1522.     zi = translation[2] +
  1523.                                                                                 // 227
  1524.       (rotation[2][0] * this.objectVectors[i][0] +
  1525.                                                        // 228
  1526.        rotation[2][1] * this.objectVectors[i][1] +
  1527.                                                        // 229
  1528.        rotation[2][2] * this.objectVectors[i][2]);
  1529.                                                        // 230
  1530.     if (zi < zmin){
  1531.                                                                                       // 231
  1532.       zmin = zi;
  1533.                                                                                          // 232
  1534.     }
  1535.                                                                                                     // 233
  1536.   }
  1537.                                                                                                       // 234
  1538.  
  1539.                                                                                                          // 235
  1540.   return zmin >= 0.0;
  1541.                                                                                     // 236
  1542. };
  1543.                                                                                                        // 237
  1544.  
  1545.                                                                                                          // 238
  1546. POS.Posit.prototype.iterate = function(imagePoints, posRotation, posTranslation, rotation, translation){
  1547.  // 239
  1548.   var np = this.objectPoints.length,
  1549.                                                                      // 240
  1550.       oldSopImagePoints = [], sopImagePoints = [],
  1551.                                                        // 241
  1552.       rotation1 = [[],[],[]], rotation2 = [[],[],[]],
  1553.                                                     // 242
  1554.       translation1 = [], translation2 = [],
  1555.                                                               // 243
  1556.       converged = false, iteration = 0,
  1557.                                                                   // 244
  1558.       oldImageDifference, imageDifference, factor,
  1559.                                                        // 245
  1560.       error, error1, error2, delta, i, j;
  1561.                                                                 // 246
  1562.  
  1563.                                                                                                          // 247
  1564.   for (i = 0; i < np; ++ i){
  1565.                                                                              // 248
  1566.     oldSopImagePoints[i] = {x: imagePoints[i].x,
  1567.                                                          // 249
  1568.                             y: imagePoints[i].y};
  1569.                                                         // 250
  1570.   }
  1571.                                                                                                       // 251
  1572.  
  1573.                                                                                                        // 252
  1574.   for (i = 0; i < 3; ++ i){
  1575.                                                                               // 253
  1576.     for (j = 0; j < 3; ++ j){
  1577.                                                                             // 254
  1578.       rotation[i][j] = posRotation[i][j];
  1579.                                                                 // 255
  1580.     }
  1581.                                                                                                     // 256
  1582.     translation[i] = posTranslation[i];
  1583.                                                                   // 257
  1584.   }
  1585.                                                                                                       // 258
  1586.  
  1587.                                                                                                          // 259
  1588.   for (i = 0; i < np; ++ i){
  1589.                                                                              // 260
  1590.     factor = 0.0;
  1591.                                                                                         // 261
  1592.     for (j = 0; j < 3; ++ j){
  1593.                                                                             // 262
  1594.       factor += this.objectVectors[i][j] * rotation[2][j] / translation[2];
  1595.                               // 263
  1596.     }
  1597.                                                                                                     // 264
  1598.     sopImagePoints[i] = {x: (1.0 + factor) * imagePoints[i].x,
  1599.                                            // 265
  1600.                          y: (1.0 + factor) * imagePoints[i].y};
  1601.                                           // 266
  1602.   }
  1603.                                                                                                       // 267
  1604.  
  1605.                                                                                                          // 268
  1606.   imageDifference = 0.0;
  1607.                                                                                  // 269
  1608.  
  1609.                                                                                                        // 270
  1610.   for (i = 0; i < np; ++ i){
  1611.                                                                              // 271
  1612.     imageDifference += Math.abs(sopImagePoints[i].x - oldSopImagePoints[i].x);
  1613.                            // 272
  1614.     imageDifference += Math.abs(sopImagePoints[i].y - oldSopImagePoints[i].y);
  1615.                            // 273
  1616.   }
  1617.                                                                                                       // 274
  1618.  
  1619.                                                                                                          // 275
  1620.   for (i = 0; i < 3; ++ i){
  1621.                                                                               // 276
  1622.     translation1[i] = translation[i] -
  1623.                                                                    // 277
  1624.       (rotation[i][0] * this.objectPoints[0][0] +
  1625.                                                         // 278
  1626.        rotation[i][1] * this.objectPoints[0][1] +
  1627.                                                         // 279
  1628.        rotation[i][2] * this.objectPoints[0][2]);
  1629.                                                         // 280
  1630.   }
  1631.                                                                                                       // 281
  1632.  
  1633.                                                                                                        // 282
  1634.   error1 = this.error(imagePoints, rotation, translation1);
  1635.                                               // 283
  1636.  
  1637.                                                                                                          // 284
  1638.   //Convergence
  1639.                                                                                           // 285
  1640.   converged = (0.0 === error1.pixels) || (imageDifference < 0.01);
  1641.                                        // 286
  1642.  
  1643.                                                                                                        // 287
  1644.   while( iteration ++ < 100 && !converged ){
  1645.                                                              // 288
  1646.  
  1647.                                                                                                        // 289
  1648.     for (i = 0; i < np; ++ i){
  1649.                                                                            // 290
  1650.       oldSopImagePoints[i].x = sopImagePoints[i].x;
  1651.                                                       // 291
  1652.       oldSopImagePoints[i].y = sopImagePoints[i].y;
  1653.                                                       // 292
  1654.     }
  1655.                                                                                                     // 293
  1656.  
  1657.                                                                                                          // 294
  1658.     this.pos(sopImagePoints, rotation1, rotation2, translation);
  1659.                                          // 295
  1660.  
  1661.                                                                                                          // 296
  1662.     for (i = 0; i < 3; ++ i){
  1663.                                                                             // 297
  1664.       translation1[i] = translation[i] -
  1665.                                                                  // 298
  1666.         (rotation1[i][0] * this.objectPoints[0][0] +
  1667.                                                      // 299
  1668.          rotation1[i][1] * this.objectPoints[0][1] +
  1669.                                                      // 300
  1670.          rotation1[i][2] * this.objectPoints[0][2]);
  1671.                                                      // 301
  1672.        
  1673.                                                                                                  // 302
  1674.       translation2[i] = translation[i] -
  1675.                                                                  // 303
  1676.         (rotation2[i][0] * this.objectPoints[0][0] +
  1677.                                                      // 304
  1678.          rotation2[i][1] * this.objectPoints[0][1] +
  1679.                                                      // 305
  1680.          rotation2[i][2] * this.objectPoints[0][2]);
  1681.                                                      // 306
  1682.     }
  1683.                                                                                                     // 307
  1684.  
  1685.                                                                                                          // 308
  1686.     error1 = this.error(imagePoints, rotation1, translation1);
  1687.                                            // 309
  1688.     error2 = this.error(imagePoints, rotation2, translation2);
  1689.                                            // 310
  1690.  
  1691.                                                                                                          // 311
  1692.     if ( (error1.euclidean >= 0.0) && (error2.euclidean >= 0.0) ){
  1693.                                        // 312
  1694.       if (error2.euclidean < error1.euclidean){
  1695.                                                           // 313
  1696.         error = error2;
  1697.                                                                                   // 314
  1698.         for (i = 0; i < 3; ++ i){
  1699.                                                                         // 315
  1700.           for (j = 0; j < 3; ++ j){
  1701.                                                                       // 316
  1702.             rotation[i][j] = rotation2[i][j];
  1703.                                                             // 317
  1704.           }
  1705.                                                                                               // 318
  1706.         }
  1707.                                                                                                 // 319
  1708.       }else{
  1709.                                                                                              // 320
  1710.         error = error1;
  1711.                                                                                   // 321
  1712.         for (i = 0; i < 3; ++ i){
  1713.                                                                         // 322
  1714.           for (j = 0; j < 3; ++ j){
  1715.                                                                       // 323
  1716.             rotation[i][j] = rotation1[i][j];
  1717.                                                             // 324
  1718.           }
  1719.                                                                                               // 325
  1720.         }
  1721.                                                                                                 // 326
  1722.       }
  1723.                                                                                                   // 327
  1724.     }
  1725.                                                                                                     // 328
  1726.  
  1727.                                                                                                          // 329
  1728.     if ( (error1.euclidean < 0.0) && (error2.euclidean >= 0.0) ){
  1729.                                         // 330
  1730.       error = error2;
  1731.                                                                                     // 331
  1732.       for (i = 0; i < 3; ++ i){
  1733.                                                                           // 332
  1734.         for (j = 0; j < 3; ++ j){
  1735.                                                                         // 333
  1736.           rotation[i][j] = rotation2[i][j];
  1737.                                                               // 334
  1738.         }
  1739.                                                                                                 // 335
  1740.       }
  1741.                                                                                                   // 336
  1742.     }
  1743.                                                                                                     // 337
  1744.    
  1745.                                                                                                      // 338
  1746.     if ( (error2.euclidean < 0.0) && (error1.euclidean >= 0.0) ){
  1747.                                         // 339
  1748.       error = error1;
  1749.                                                                                     // 340
  1750.       for (i = 0; i < 3; ++ i){
  1751.                                                                           // 341
  1752.         for (j = 0; j < 3; ++ j){
  1753.                                                                         // 342
  1754.           rotation[i][j] = rotation1[i][j];
  1755.                                                               // 343
  1756.         }
  1757.                                                                                                 // 344
  1758.       }
  1759.                                                                                                   // 345
  1760.     }
  1761.                                                                                                     // 346
  1762.  
  1763.                                                                                                          // 347
  1764.     for (i = 0; i < np; ++ i){
  1765.                                                                            // 348
  1766.       factor = 0.0;
  1767.                                                                                       // 349
  1768.       for (j = 0; j < 3; ++ j){
  1769.                                                                           // 350
  1770.         factor += this.objectVectors[i][j] * rotation[2][j] / translation[2];
  1771.                             // 351
  1772.       }
  1773.                                                                                                   // 352
  1774.       sopImagePoints[i].x = (1.0 + factor) * imagePoints[i].x;
  1775.                                            // 353
  1776.       sopImagePoints[i].y = (1.0 + factor) * imagePoints[i].y;
  1777.                                            // 354
  1778.     }
  1779.                                                                                                     // 355
  1780.  
  1781.                                                                                                          // 356
  1782.     oldImageDifference = imageDifference;
  1783.                                                                 // 357
  1784.     imageDifference = 0.0;
  1785.                                                                                // 358
  1786.    
  1787.                                                                                                      // 359
  1788.     for (i = 0; i < np; ++ i){
  1789.                                                                            // 360
  1790.       imageDifference += Math.abs(sopImagePoints[i].x - oldSopImagePoints[i].x);
  1791.                          // 361
  1792.       imageDifference += Math.abs(sopImagePoints[i].y - oldSopImagePoints[i].y);
  1793.                          // 362
  1794.     }
  1795.                                                                                                     // 363
  1796.  
  1797.                                                                                                          // 364
  1798.     delta = Math.abs(imageDifference - oldImageDifference);
  1799.                                               // 365
  1800.  
  1801.                                                                                                          // 366
  1802.     converged = (0.0 === error.pixels) || (delta < 0.01);
  1803.                                                 // 367
  1804.   }
  1805.                                                                                                       // 368
  1806.  
  1807.                                                                                                        // 369
  1808.   return error;
  1809.                                                                                           // 370
  1810. };
  1811.                                                                                                        // 371
  1812.  
  1813.                                                                                                          // 372
  1814. POS.Posit.prototype.error = function(imagePoints, rotation, translation){
  1815.                                 // 373
  1816.   var np = this.objectPoints.length,
  1817.                                                                      // 374
  1818.       move = [], projection = [], errorvec = [],
  1819.                                                          // 375
  1820.       euclidean = 0.0, pixels = 0.0, maximum = 0.0,
  1821.                                                       // 376
  1822.       i, j, k;
  1823.                                                                                            // 377
  1824.  
  1825.                                                                                                          // 378
  1826.   if ( !this.isValid(rotation, translation) ){
  1827.                                                            // 379
  1828.     return {euclidean: -1.0, pixels: -1, maximum: -1.0};
  1829.                                                  // 380
  1830.   }
  1831.                                                                                                       // 381
  1832.  
  1833.                                                                                                        // 382
  1834.   for (i = 0; i < np; ++ i){
  1835.                                                                              // 383
  1836.     move[i] = [];
  1837.                                                                                         // 384
  1838.     for (j = 0; j < 3; ++ j){
  1839.                                                                             // 385
  1840.       move[i][j] = translation[j];
  1841.                                                                        // 386
  1842.     }
  1843.                                                                                                     // 387
  1844.   }
  1845.                                                                                                       // 388
  1846.  
  1847.                                                                                                        // 389
  1848.   for (i = 0; i < np; ++ i){
  1849.                                                                              // 390
  1850.     for (j = 0; j < 3; ++ j){
  1851.                                                                             // 391
  1852.       for (k = 0; k < 3; ++ k){
  1853.                                                                           // 392
  1854.         move[i][j] += rotation[j][k] * this.objectPoints[i][k];
  1855.                                           // 393
  1856.       }
  1857.                                                                                                   // 394
  1858.     }
  1859.                                                                                                     // 395
  1860.   }
  1861.                                                                                                       // 396
  1862.  
  1863.                                                                                                          // 397
  1864.   for (i = 0; i < np; ++ i){
  1865.                                                                              // 398
  1866.     projection[i] = [];
  1867.                                                                                   // 399
  1868.     for (j = 0; j < 2; ++ j){
  1869.                                                                             // 400
  1870.       projection[i][j] = this.focalLength * move[i][j] / move[i][2];
  1871.                                      // 401
  1872.     }
  1873.                                                                                                     // 402
  1874.   }
  1875.                                                                                                       // 403
  1876.  
  1877.                                                                                                        // 404
  1878.   for (i = 0; i < np; ++ i){
  1879.                                                                              // 405
  1880.     errorvec[i] = [projection[i][0] - imagePoints[i].x,
  1881.                                                   // 406
  1882.                    projection[i][1] - imagePoints[i].y];
  1883.                                                  // 407
  1884.   }
  1885.                                                                                                       // 408
  1886.  
  1887.                                                                                                          // 409
  1888.   for (i = 0; i < np; ++ i){
  1889.                                                                              // 410
  1890.     euclidean += Math.sqrt(errorvec[i][0] * errorvec[i][0] +
  1891.                                              // 411
  1892.                            errorvec[i][1] * errorvec[i][1]);
  1893.                                              // 412
  1894.                        
  1895.                                                                                   // 413
  1896.     pixels += Math.abs( Math.round(projection[i][0]) - Math.round(imagePoints[i].x) ) +
  1897.                   // 414
  1898.               Math.abs( Math.round(projection[i][1]) - Math.round(imagePoints[i].y) );
  1899.                    // 415
  1900.              
  1901.                                                                                            // 416
  1902.     if (Math.abs(errorvec[i][0]) > maximum){
  1903.                                                              // 417
  1904.       maximum = Math.abs(errorvec[i][0]);
  1905.                                                                 // 418
  1906.     }
  1907.                                                                                                     // 419
  1908.     if (Math.abs(errorvec[i][1]) > maximum){
  1909.                                                              // 420
  1910.       maximum = Math.abs(errorvec[i][1]);
  1911.                                                                 // 421
  1912.     }
  1913.                                                                                                     // 422
  1914.   }
  1915.                                                                                                       // 423
  1916.  
  1917.                                                                                                          // 424
  1918.   return {euclidean: euclidean / np, pixels: pixels, maximum: maximum};
  1919.                                   // 425
  1920. };
  1921.                                                                                                        // 426
  1922.  
  1923.                                                                                                          // 427
  1924. POS.pseudoInverse = function(a, n, b){
  1925.                                                                    // 428
  1926.   var w = [], v = [[],[],[]], s = [[],[],[]],
  1927.                                                             // 429
  1928.       wmax = 0.0, cn = 0,
  1929.                                                                                 // 430
  1930.       i, j, k;
  1931.                                                                                            // 431
  1932.  
  1933.                                                                                                          // 432
  1934.   SVD.svdcmp(a, n, 3, w, v);
  1935.                                                                              // 433
  1936.  
  1937.                                                                                                          // 434
  1938.   for (i = 0; i < 3; ++ i){
  1939.                                                                               // 435
  1940.     if (w[i] > wmax){
  1941.                                                                                     // 436
  1942.       wmax = w[i];
  1943.                                                                                        // 437
  1944.     }
  1945.                                                                                                     // 438
  1946.   }
  1947.                                                                                                       // 439
  1948.  
  1949.                                                                                                          // 440
  1950.   wmax *= 0.01;
  1951.                                                                                           // 441
  1952.  
  1953.                                                                                                          // 442
  1954.   for (i = 0; i < 3; ++ i){
  1955.                                                                               // 443
  1956.     if (w[i] < wmax){
  1957.                                                                                     // 444
  1958.       w[i] = 0.0;
  1959.                                                                                         // 445
  1960.     }
  1961.                                                                                                     // 446
  1962.   }
  1963.                                                                                                       // 447
  1964.  
  1965.                                                                                                          // 448
  1966.   for (j = 0; j < 3; ++ j){
  1967.                                                                               // 449
  1968.     if (0.0 === w[j]){
  1969.                                                                                    // 450
  1970.       ++ cn;
  1971.                                                                                              // 451
  1972.       for (k = j; k < 2; ++ k){
  1973.                                                                           // 452
  1974.         for (i = 0; i < n; ++ i){
  1975.                                                                         // 453
  1976.           a[i][k] = a[i][k + 1];
  1977.                                                                          // 454
  1978.         }
  1979.                                                                                                 // 455
  1980.         for (i = 0; i < 3; ++ i){
  1981.                                                                         // 456
  1982.           v[i][k] = v[i][k + 1];
  1983.                                                                          // 457
  1984.         }
  1985.                                                                                                 // 458
  1986.       }
  1987.                                                                                                   // 459
  1988.     }
  1989.                                                                                                     // 460
  1990.   }
  1991.                                                                                                       // 461
  1992.  
  1993.                                                                                                          // 462
  1994.   for (j = 0; j < 2; ++ j){
  1995.                                                                               // 463
  1996.     if (0.0 === w[j]){
  1997.                                                                                    // 464
  1998.       w[j] = w[j + 1];
  1999.                                                                                    // 465
  2000.     }
  2001.                                                                                                     // 466
  2002.   }
  2003.                                                                                                       // 467
  2004.  
  2005.                                                                                                          // 468
  2006.   for (i = 0; i < 3; ++ i){
  2007.                                                                               // 469
  2008.     for (j = 0; j < 3 - cn; ++ j){
  2009.                                                                        // 470
  2010.       s[i][j] = v[i][j] / w[j];
  2011.                                                                           // 471
  2012.     }
  2013.                                                                                                     // 472
  2014.   }
  2015.                                                                                                       // 473
  2016.  
  2017.                                                                                                        // 474
  2018.   for (i = 0; i < 3; ++ i){
  2019.                                                                               // 475
  2020.     for (j = 0; j < n; ++ j){
  2021.                                                                             // 476
  2022.       b[i][j] = 0.0;
  2023.                                                                                      // 477
  2024.       for (k = 0; k < 3 - cn; ++ k){
  2025.                                                                      // 478
  2026.         b[i][j] += s[i][k] * a[j][k];
  2027.                                                                     // 479
  2028.       }
  2029.                                                                                                   // 480
  2030.     }
  2031.                                                                                                     // 481
  2032.   }
  2033.                                                                                                       // 482
  2034. };
  2035.                                                                                                        // 483
  2036.  
  2037.                                                                                                          // 484
  2038. POS.Pose = function(error1, rotation1, translation1, error2, rotation2, translation2){
  2039.                    // 485
  2040.   this.bestError = error1;
  2041.                                                                                // 486
  2042.   this.bestRotation = rotation1;
  2043.                                                                          // 487
  2044.   this.bestTranslation = translation1;
  2045.                                                                    // 488
  2046.   this.alternativeError = error2;
  2047.                                                                         // 489
  2048.   this.alternativeRotation = rotation2;
  2049.                                                                   // 490
  2050.   this.alternativeTranslation = translation2;
  2051.                                                             // 491
  2052. };
  2053.                                                                                                        // 492
  2054.                                                                                                           // 493
  2055. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2056.  
  2057. }).call(this);
  2058.  
  2059.  
  2060.  
  2061.  
  2062.  
  2063.  
  2064. (function () {
  2065.  
  2066. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2067. //                                                                                                        //
  2068. // packages/js-aruco/posit2.js                                                                            //
  2069. //                                                                                                        //
  2070. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2071.                                                                                                           //
  2072. /*
  2073.                                                                                                        // 1
  2074. Copyright (c) 2012 Juan Mellado
  2075.                                                                           // 2
  2076.  
  2077.                                                                                                          // 3
  2078. Permission is hereby granted, free of charge, to any person obtaining a copy
  2079.                              // 4
  2080. of this software and associated documentation files (the "Software"), to deal
  2081.                             // 5
  2082. in the Software without restriction, including without limitation the rights
  2083.                              // 6
  2084. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  2085.                                 // 7
  2086. copies of the Software, and to permit persons to whom the Software is
  2087.                                     // 8
  2088. furnished to do so, subject to the following conditions:
  2089.                                                  // 9
  2090.  
  2091.                                                                                                          // 10
  2092. The above copyright notice and this permission notice shall be included in
  2093.                                // 11
  2094. all copies or substantial portions of the Software.
  2095.                                                       // 12
  2096.  
  2097.                                                                                                          // 13
  2098. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2099.                                // 14
  2100. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2101.                                  // 15
  2102. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2103.                               // 16
  2104. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2105.                                    // 17
  2106. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2107.                             // 18
  2108. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  2109.                                 // 19
  2110. THE SOFTWARE.
  2111.                                                                                             // 20
  2112. */
  2113.                                                                                                        // 21
  2114.  
  2115.                                                                                                          // 22
  2116. /*
  2117.                                                                                                        // 23
  2118. References:
  2119.                                                                                               // 24
  2120. - "3D Pose Estimation"
  2121.                                                                                    // 25
  2122.   Andrew Kirillow
  2123.                                                                                         // 26
  2124.   http://www.aforgenet.com/articles/posit/
  2125.                                                                // 27
  2126. */
  2127.                                                                                                        // 28
  2128.  
  2129.                                                                                                          // 29
  2130. var POS = POS || {};
  2131.                                                                                      // 30
  2132.  
  2133.                                                                                                          // 31
  2134. POS.Posit = function(modelSize, focalLength){
  2135.                                                             // 32
  2136.   this.model = this.buildModel(modelSize);
  2137.                                                                // 33
  2138.   this.focalLength = focalLength;
  2139.                                                                         // 34
  2140.  
  2141.                                                                                                          // 35
  2142.   this.init();
  2143.                                                                                            // 36
  2144. };
  2145.                                                                                                        // 37
  2146.  
  2147.                                                                                                          // 38
  2148. POS.Posit.prototype.buildModel = function(modelSize){
  2149.                                                     // 39
  2150.   var half = modelSize / 2.0;
  2151.                                                                             // 40
  2152.  
  2153.                                                                                                        // 41
  2154.   return [
  2155.                                                                                                // 42
  2156.     new Vec3(-half,  half, 0.0),
  2157.                                                                          // 43
  2158.     new Vec3( half,  half, 0.0),
  2159.                                                                          // 44
  2160.     new Vec3( half, -half, 0.0),
  2161.                                                                          // 45
  2162.     new Vec3(-half, -half, 0.0) ];
  2163.                                                                        // 46
  2164. };
  2165.                                                                                                        // 47
  2166.  
  2167.                                                                                                          // 48
  2168. POS.Posit.prototype.init = function(){
  2169.                                                                    // 49
  2170.   var d = new Vec3(), v = new Mat3(), u;
  2171.                                                                  // 50
  2172.  
  2173.                                                                                                        // 51
  2174.   this.modelVectors = Mat3.fromRows(
  2175.                                                                      // 52
  2176.       Vec3.sub(this.model[1], this.model[0]),
  2177.                                                             // 53
  2178.       Vec3.sub(this.model[2], this.model[0]),
  2179.                                                             // 54
  2180.       Vec3.sub(this.model[3], this.model[0]) );
  2181.                                                           // 55
  2182.  
  2183.                                                                                                          // 56
  2184.   u = Mat3.clone(this.modelVectors);
  2185.                                                                      // 57
  2186.  
  2187.                                                                                                          // 58
  2188.   SVD.svdcmp(u.m, 3, 3, d.v, v.m);
  2189.                                                                        // 59
  2190.  
  2191.                                                                                                          // 60
  2192.   this.modelPseudoInverse = Mat3.mult(
  2193.                                                                    // 61
  2194.     Mat3.mult(v, Mat3.fromDiagonal( Vec3.inverse(d) ) ), Mat3.transpose(u) );
  2195.                             // 62
  2196.  
  2197.                                                                                                        // 63
  2198.   this.modelNormal = v.column( d.minIndex() );
  2199.                                                            // 64
  2200. };
  2201.                                                                                                        // 65
  2202.  
  2203.                                                                                                          // 66
  2204. POS.Posit.prototype.pose = function(points){
  2205.                                                              // 67
  2206.   var eps = new Vec3(1.0, 1.0, 1.0),
  2207.                                                                      // 68
  2208.       rotation1 = new Mat3(), rotation2 = new Mat3(),
  2209.                                                     // 69
  2210.       translation1 = new Vec3(), translation2 = new Vec3(),
  2211.                                               // 70
  2212.       error1, error2;
  2213.                                                                                     // 71
  2214.  
  2215.                                                                                                          // 72
  2216.   this.pos(points, eps, rotation1, rotation2, translation1, translation2);
  2217.                                // 73
  2218.  
  2219.                                                                                                          // 74
  2220.   error1 = this.iterate(points, rotation1, translation1);
  2221.                                                 // 75
  2222.   error2 = this.iterate(points, rotation2, translation2);
  2223.                                                 // 76
  2224.  
  2225.                                                                                                          // 77
  2226.   return error1 < error2?
  2227.                                                                                 // 78
  2228.     new POS.Pose(error1, rotation1.m, translation1.v, error2, rotation2.m, translation2.v):
  2229.               // 79
  2230.     new POS.Pose(error2, rotation2.m, translation2.v, error1, rotation1.m, translation1.v);
  2231.               // 80
  2232. };
  2233.                                                                                                        // 81
  2234.  
  2235.                                                                                                          // 82
  2236. POS.Posit.prototype.pos = function(points, eps, rotation1, rotation2, translation1, translation2){
  2237.        // 83
  2238.   var xi = new Vec3(points[1].x, points[2].x, points[3].x),
  2239.                                               // 84
  2240.       yi = new Vec3(points[1].y, points[2].y, points[3].y),
  2241.                                               // 85
  2242.       xs = Vec3.addScalar( Vec3.mult(xi, eps), -points[0].x),
  2243.                                             // 86
  2244.       ys = Vec3.addScalar( Vec3.mult(yi, eps), -points[0].y),
  2245.                                             // 87
  2246.       i0 = Mat3.multVector(this.modelPseudoInverse, xs),
  2247.                                                  // 88
  2248.       j0 = Mat3.multVector(this.modelPseudoInverse, ys),
  2249.                                                  // 89
  2250.       s = j0.square() - i0.square(),
  2251.                                                                      // 90
  2252.       ij = Vec3.dot(i0, j0),
  2253.                                                                              // 91
  2254.       r = 0.0, theta = 0.0,
  2255.                                                                               // 92
  2256.       i, j, k, inorm, jnorm, scale, temp, lambda, mu;
  2257.                                                     // 93
  2258.  
  2259.                                                                                                          // 94
  2260.   if (0.0 === s){
  2261.                                                                                         // 95
  2262.     r = Math.sqrt( Math.abs(2.0 * ij) );
  2263.                                                                  // 96
  2264.     theta = (-Math.PI / 2.0) * (ij < 0.0? -1: (ij > 0.0? 1.0: 0.0) );
  2265.                                     // 97
  2266.   }else{
  2267.                                                                                                  // 98
  2268.     r = Math.sqrt( Math.sqrt(s * s + 4.0 * ij * ij) );
  2269.                                                    // 99
  2270.     theta = Math.atan(-2.0 * ij / s);
  2271.                                                                     // 100
  2272.     if (s < 0.0){
  2273.                                                                                         // 101
  2274.       theta += Math.PI;
  2275.                                                                                   // 102
  2276.     }
  2277.                                                                                                     // 103
  2278.     theta /= 2.0;
  2279.                                                                                         // 104
  2280.   }
  2281.                                                                                                       // 105
  2282.  
  2283.                                                                                                          // 106
  2284.   lambda = r * Math.cos(theta);
  2285.                                                                           // 107
  2286.   mu = r * Math.sin(theta);
  2287.                                                                               // 108
  2288.  
  2289.                                                                                                          // 109
  2290.   //First possible rotation/translation
  2291.                                                                   // 110
  2292.   i = Vec3.add(i0, Vec3.multScalar(this.modelNormal, lambda) );
  2293.                                           // 111
  2294.   j = Vec3.add(j0, Vec3.multScalar(this.modelNormal, mu) );
  2295.                                               // 112
  2296.   inorm = i.normalize();
  2297.                                                                                  // 113
  2298.   jnorm = j.normalize();
  2299.                                                                                  // 114
  2300.   k = Vec3.cross(i, j);
  2301.                                                                                   // 115
  2302.   rotation1.copy( Mat3.fromRows(i, j, k) );
  2303.                                                               // 116
  2304.  
  2305.                                                                                                        // 117
  2306.   scale = (inorm + jnorm) / 2.0;
  2307.                                                                          // 118
  2308.   temp = Mat3.multVector(rotation1, this.model[0]);
  2309.                                                       // 119
  2310.   translation1.v = [
  2311.                                                                                      // 120
  2312.     points[0].x / scale - temp.v[0],
  2313.                                                                      // 121
  2314.     points[0].y / scale - temp.v[1],
  2315.                                                                      // 122
  2316.     this.focalLength / scale];
  2317.                                                                            // 123
  2318.  
  2319.                                                                                                          // 124
  2320.   //Second possible rotation/translation
  2321.                                                                  // 125
  2322.   i = Vec3.sub(i0, Vec3.multScalar(this.modelNormal, lambda) );
  2323.                                           // 126
  2324.   j = Vec3.sub(j0, Vec3.multScalar(this.modelNormal, mu) );
  2325.                                               // 127
  2326.   inorm = i.normalize();
  2327.                                                                                  // 128
  2328.   jnorm = j.normalize();
  2329.                                                                                  // 129
  2330.   k = Vec3.cross(i, j);
  2331.                                                                                   // 130
  2332.   rotation2.copy( Mat3.fromRows(i, j, k) );
  2333.                                                               // 131
  2334.  
  2335.                                                                                                        // 132
  2336.   scale = (inorm + jnorm) / 2.0;
  2337.                                                                          // 133
  2338.   temp = Mat3.multVector(rotation2, this.model[0]);
  2339.                                                       // 134
  2340.   translation2.v = [
  2341.                                                                                      // 135
  2342.     points[0].x / scale - temp.v[0],
  2343.                                                                      // 136
  2344.     points[0].y / scale - temp.v[1],
  2345.                                                                      // 137
  2346.     this.focalLength / scale];
  2347.                                                                            // 138
  2348. };
  2349.                                                                                                        // 139
  2350.  
  2351.                                                                                                          // 140
  2352. POS.Posit.prototype.iterate = function(points, rotation, translation){
  2353.                                    // 141
  2354.   var prevError = Infinity,
  2355.                                                                               // 142
  2356.       rotation1 = new Mat3(), rotation2 = new Mat3(),
  2357.                                                     // 143
  2358.       translation1 = new Vec3(), translation2 = new Vec3(),
  2359.                                               // 144
  2360.       i = 0, eps, error, error1, error2;
  2361.                                                                  // 145
  2362.  
  2363.                                                                                                          // 146
  2364.   for (; i < 100; ++ i){
  2365.                                                                                  // 147
  2366.     eps = Vec3.addScalar( Vec3.multScalar(
  2367.                                                               // 148
  2368.       Mat3.multVector( this.modelVectors, rotation.row(2) ), 1.0 / translation.v[2]), 1.0);
  2369.               // 149
  2370.  
  2371.                                                                                                          // 150
  2372.     this.pos(points, eps, rotation1, rotation2, translation1, translation2);
  2373.                              // 151
  2374.  
  2375.                                                                                                          // 152
  2376.     error1 = this.getError(points, rotation1, translation1);
  2377.                                              // 153
  2378.     error2 = this.getError(points, rotation2, translation2);
  2379.                                              // 154
  2380.  
  2381.                                                                                                          // 155
  2382.     if (error1 < error2){
  2383.                                                                                 // 156
  2384.       rotation.copy(rotation1);
  2385.                                                                           // 157
  2386.       translation.copy(translation1);
  2387.                                                                     // 158
  2388.       error = error1;
  2389.                                                                                     // 159
  2390.     }else{
  2391.                                                                                                // 160
  2392.       rotation.copy(rotation2);
  2393.                                                                           // 161
  2394.       translation.copy(translation2);
  2395.                                                                     // 162
  2396.       error = error2;
  2397.                                                                                     // 163
  2398.     }
  2399.                                                                                                     // 164
  2400.  
  2401.                                                                                                          // 165
  2402.     if ( (error <= 2.0) || (error > prevError) ){
  2403.                                                         // 166
  2404.       break;
  2405.                                                                                              // 167
  2406.     }
  2407.                                                                                                     // 168
  2408.  
  2409.                                                                                                          // 169
  2410.     prevError = error;
  2411.                                                                                    // 170
  2412.   }
  2413.                                                                                                       // 171
  2414.  
  2415.                                                                                                          // 172
  2416.   return error;
  2417.                                                                                           // 173
  2418. };
  2419.                                                                                                        // 174
  2420.  
  2421.                                                                                                          // 175
  2422. POS.Posit.prototype.getError = function(points, rotation, translation){
  2423.                                   // 176
  2424.   var v1 = Vec3.add( Mat3.multVector(rotation, this.model[0]), translation),
  2425.                              // 177
  2426.       v2 = Vec3.add( Mat3.multVector(rotation, this.model[1]), translation),
  2427.                              // 178
  2428.       v3 = Vec3.add( Mat3.multVector(rotation, this.model[2]), translation),
  2429.                              // 179
  2430.       v4 = Vec3.add( Mat3.multVector(rotation, this.model[3]), translation),
  2431.                              // 180
  2432.       modeled, ia1, ia2, ia3, ia4, ma1, ma2, ma3, ma4;
  2433.                                                    // 181
  2434.  
  2435.                                                                                                        // 182
  2436.   v1 = v1.v; v2 = v2.v; v3 = v3.v; v4 = v4.v;
  2437.                                                             // 183
  2438.  
  2439.                                                                                                        // 184
  2440.   v1[0] *= this.focalLength / v1[2];
  2441.                                                                      // 185
  2442.   v1[1] *= this.focalLength / v1[2];
  2443.                                                                      // 186
  2444.   v2[0] *= this.focalLength / v2[2];
  2445.                                                                      // 187
  2446.   v2[1] *= this.focalLength / v2[2];
  2447.                                                                      // 188
  2448.   v3[0] *= this.focalLength / v3[2];
  2449.                                                                      // 189
  2450.   v3[1] *= this.focalLength / v3[2];
  2451.                                                                      // 190
  2452.   v4[0] *= this.focalLength / v4[2];
  2453.                                                                      // 191
  2454.   v4[1] *= this.focalLength / v4[2];
  2455.                                                                      // 192
  2456.  
  2457.                                                                                                        // 193
  2458.   modeled = [
  2459.                                                                                             // 194
  2460.     {x: v1[0], y: v1[1]},
  2461.                                                                                 // 195
  2462.     {x: v2[0], y: v2[1]},
  2463.                                                                                 // 196
  2464.     {x: v3[0], y: v3[1]},
  2465.                                                                                 // 197
  2466.     {x: v4[0], y: v4[1]}
  2467.                                                                                  // 198
  2468.   ];
  2469.                                                                                                      // 199
  2470.  
  2471.                                                                                                          // 200
  2472.   ia1 = this.angle( points[0], points[1], points[3] );
  2473.                                                    // 201
  2474.   ia2 = this.angle( points[1], points[2], points[0] );
  2475.                                                    // 202
  2476.   ia3 = this.angle( points[2], points[3], points[1] );
  2477.                                                    // 203
  2478.   ia4 = this.angle( points[3], points[0], points[2] );
  2479.                                                    // 204
  2480.  
  2481.                                                                                                          // 205
  2482.   ma1 = this.angle( modeled[0], modeled[1], modeled[3] );
  2483.                                                 // 206
  2484.   ma2 = this.angle( modeled[1], modeled[2], modeled[0] );
  2485.                                                 // 207
  2486.   ma3 = this.angle( modeled[2], modeled[3], modeled[1] );
  2487.                                                 // 208
  2488.   ma4 = this.angle( modeled[3], modeled[0], modeled[2] );
  2489.                                                 // 209
  2490.  
  2491.                                                                                                          // 210
  2492.   return ( Math.abs(ia1 - ma1) +
  2493.                                                                          // 211
  2494.            Math.abs(ia2 - ma2) +
  2495.                                                                          // 212
  2496.            Math.abs(ia3 - ma3) +
  2497.                                                                          // 213
  2498.            Math.abs(ia4 - ma4) ) / 4.0;
  2499.                                                                   // 214
  2500. };
  2501.                                                                                                        // 215
  2502.  
  2503.                                                                                                          // 216
  2504. POS.Posit.prototype.angle = function(a, b, c){
  2505.                                                            // 217
  2506.   var x1 = b.x - a.x, y1 = b.y - a.y,
  2507.                                                                     // 218
  2508.       x2 = c.x - a.x, y2 = c.y - a.y;
  2509.                                                                     // 219
  2510.  
  2511.                                                                                                        // 220
  2512.   return Math.acos( (x1 * x2 + y1 * y2) /
  2513.                                                                // 221
  2514.     (Math.sqrt(x1 * x1 + y1 * y1) * Math.sqrt(x2 * x2 + y2 * y2) ) ) * 180.0 / Math.PI;
  2515.                   // 222
  2516. };
  2517.                                                                                                        // 223
  2518.  
  2519.                                                                                                          // 224
  2520. POS.Pose = function(error1, rotation1, translation1, error2, rotation2, translation2){
  2521.                    // 225
  2522.   this.bestError = error1;
  2523.                                                                                // 226
  2524.   this.bestRotation = rotation1;
  2525.                                                                          // 227
  2526.   this.bestTranslation = translation1;
  2527.                                                                    // 228
  2528.   this.alternativeError = error2;
  2529.                                                                         // 229
  2530.   this.alternativeRotation = rotation2;
  2531.                                                                   // 230
  2532.   this.alternativeTranslation = translation2;
  2533.                                                             // 231
  2534. };
  2535.                                                                                                        // 232
  2536.  
  2537.                                                                                                          // 233
  2538. var Vec3 = function(x, y, z){
  2539.                                                                             // 234
  2540.   this.v = [x || 0.0, y || 0.0, z || 0.0];
  2541.                                                                // 235
  2542. };
  2543.                                                                                                        // 236
  2544.  
  2545.                                                                                                          // 237
  2546. Vec3.prototype.copy = function(a){
  2547.                                                                        // 238
  2548.   var v = this.v;
  2549.                                                                                         // 239
  2550.  
  2551.                                                                                                          // 240
  2552.   a = a.v;
  2553.                                                                                                // 241
  2554.  
  2555.                                                                                                          // 242
  2556.   v[0] = a[0];
  2557.                                                                                            // 243
  2558.   v[1] = a[1];
  2559.                                                                                            // 244
  2560.   v[2] = a[2];
  2561.                                                                                            // 245
  2562.  
  2563.                                                                                                          // 246
  2564.   return this;
  2565.                                                                                            // 247
  2566. };
  2567.                                                                                                        // 248
  2568.  
  2569.                                                                                                          // 249
  2570. Vec3.add = function(a, b){
  2571.                                                                                // 250
  2572.   var vector = new Vec3(), v = vector.v;
  2573.                                                                  // 251
  2574.  
  2575.                                                                                                        // 252
  2576.   a = a.v; b = b.v;
  2577.                                                                                       // 253
  2578.  
  2579.                                                                                                          // 254
  2580.   v[0] = a[0] + b[0];
  2581.                                                                                     // 255
  2582.   v[1] = a[1] + b[1];
  2583.                                                                                     // 256
  2584.   v[2] = a[2] + b[2];
  2585.                                                                                     // 257
  2586.  
  2587.                                                                                                        // 258
  2588.   return vector;
  2589.                                                                                          // 259
  2590. };
  2591.                                                                                                        // 260
  2592.  
  2593.                                                                                                          // 261
  2594. Vec3.sub = function(a, b){
  2595.                                                                                // 262
  2596.   var vector = new Vec3(), v = vector.v;
  2597.                                                                  // 263
  2598.  
  2599.                                                                                                        // 264
  2600.   a = a.v; b = b.v;
  2601.                                                                                       // 265
  2602.  
  2603.                                                                                                          // 266
  2604.   v[0] = a[0] - b[0];
  2605.                                                                                     // 267
  2606.   v[1] = a[1] - b[1];
  2607.                                                                                     // 268
  2608.   v[2] = a[2] - b[2];
  2609.                                                                                     // 269
  2610.  
  2611.                                                                                                        // 270
  2612.   return vector;
  2613.                                                                                          // 271
  2614. };
  2615.                                                                                                        // 272
  2616.  
  2617.                                                                                                          // 273
  2618. Vec3.mult = function(a, b){
  2619.                                                                               // 274
  2620.   var vector = new Vec3(), v = vector.v;
  2621.                                                                  // 275
  2622.  
  2623.                                                                                                        // 276
  2624.   a = a.v; b = b.v;
  2625.                                                                                       // 277
  2626.  
  2627.                                                                                                          // 278
  2628.   v[0] = a[0] * b[0];
  2629.                                                                                     // 279
  2630.   v[1] = a[1] * b[1];
  2631.                                                                                     // 280
  2632.   v[2] = a[2] * b[2];
  2633.                                                                                     // 281
  2634.  
  2635.                                                                                                        // 282
  2636.   return vector;
  2637.                                                                                          // 283
  2638. };
  2639.                                                                                                        // 284
  2640.  
  2641.                                                                                                          // 285
  2642. Vec3.addScalar = function(a, b){
  2643.                                                                          // 286
  2644.   var vector = new Vec3(), v = vector.v;
  2645.                                                                  // 287
  2646.  
  2647.                                                                                                        // 288
  2648.   a = a.v;
  2649.                                                                                                // 289
  2650.  
  2651.                                                                                                          // 290
  2652.   v[0] = a[0] + b;
  2653.                                                                                        // 291
  2654.   v[1] = a[1] + b;
  2655.                                                                                        // 292
  2656.   v[2] = a[2] + b;
  2657.                                                                                        // 293
  2658.  
  2659.                                                                                                        // 294
  2660.   return vector;
  2661.                                                                                          // 295
  2662. };
  2663.                                                                                                        // 296
  2664.  
  2665.                                                                                                          // 297
  2666. Vec3.multScalar = function(a, b){
  2667.                                                                         // 298
  2668.   var vector = new Vec3(), v = vector.v;
  2669.                                                                  // 299
  2670.  
  2671.                                                                                                        // 300
  2672.   a = a.v;
  2673.                                                                                                // 301
  2674.  
  2675.                                                                                                          // 302
  2676.   v[0] = a[0] * b;
  2677.                                                                                        // 303
  2678.   v[1] = a[1] * b;
  2679.                                                                                        // 304
  2680.   v[2] = a[2] * b;
  2681.                                                                                        // 305
  2682.  
  2683.                                                                                                        // 306
  2684.   return vector;
  2685.                                                                                          // 307
  2686. };
  2687.                                                                                                        // 308
  2688.  
  2689.                                                                                                          // 309
  2690. Vec3.dot = function(a, b){
  2691.                                                                                // 310
  2692.   a = a.v; b = b.v;
  2693.                                                                                       // 311
  2694.  
  2695.                                                                                                          // 312
  2696.   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  2697.                                                         // 313
  2698. };
  2699.                                                                                                        // 314
  2700.  
  2701.                                                                                                          // 315
  2702. Vec3.cross = function(a, b){
  2703.                                                                              // 316
  2704.   a = a.v; b = b.v;
  2705.                                                                                       // 317
  2706.  
  2707.                                                                                                          // 318
  2708.  return new Vec3(
  2709.                                                                                         // 319
  2710.     a[1] * b[2] - a[2] * b[1],
  2711.                                                                            // 320
  2712.     a[2] * b[0] - a[0] * b[2],
  2713.                                                                            // 321
  2714.     a[0] * b[1] - a[1] * b[0]);
  2715.                                                                           // 322
  2716. };
  2717.                                                                                                        // 323
  2718.  
  2719.                                                                                                          // 324
  2720. Vec3.prototype.normalize = function(){
  2721.                                                                    // 325
  2722.   var v = this.v,
  2723.                                                                                         // 326
  2724.       len = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  2725.                                           // 327
  2726.      
  2727.                                                                                                    // 328
  2728.   if (len > 0.0){
  2729.                                                                                         // 329
  2730.     v[0] /= len;
  2731.                                                                                          // 330
  2732.     v[1] /= len;
  2733.                                                                                          // 331
  2734.     v[2] /= len;
  2735.                                                                                          // 332
  2736.   }
  2737.                                                                                                       // 333
  2738.  
  2739.                                                                                                          // 334
  2740.   return len;
  2741.                                                                                             // 335
  2742. };
  2743.                                                                                                        // 336
  2744.  
  2745.                                                                                                          // 337
  2746. Vec3.inverse = function(a){
  2747.                                                                               // 338
  2748.   var vector = new Vec3(), v = vector.v;
  2749.                                                                  // 339
  2750.  
  2751.                                                                                                        // 340
  2752.   a = a.v;
  2753.                                                                                                // 341
  2754.  
  2755.                                                                                                        // 342
  2756.   if (a[0] !== 0.0){
  2757.                                                                                      // 343
  2758.     v[0] = 1.0 / a[0];
  2759.                                                                                    // 344
  2760.   }
  2761.                                                                                                       // 345
  2762.   if (a[1] !== 0.0){
  2763.                                                                                      // 346
  2764.     v[1] = 1.0 / a[1];
  2765.                                                                                    // 347
  2766.   }
  2767.                                                                                                       // 348
  2768.   if (a[2] !== 0.0){
  2769.                                                                                      // 349
  2770.     v[2] = 1.0 / a[2];
  2771.                                                                                    // 350
  2772.   }
  2773.                                                                                                       // 351
  2774.  
  2775.                                                                                                        // 352
  2776.   return vector;
  2777.                                                                                          // 353
  2778. };
  2779.                                                                                                        // 354
  2780.  
  2781.                                                                                                          // 355
  2782. Vec3.prototype.square = function(){
  2783.                                                                       // 356
  2784.   var v = this.v;
  2785.                                                                                         // 357
  2786.  
  2787.                                                                                                          // 358
  2788.   return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
  2789.                                                         // 359
  2790. };
  2791.                                                                                                        // 360
  2792.  
  2793.                                                                                                          // 361
  2794. Vec3.prototype.minIndex = function(){
  2795.                                                                     // 362
  2796.   var v = this.v;
  2797.                                                                                         // 363
  2798.  
  2799.                                                                                                          // 364
  2800.   return v[0] < v[1]? (v[0] < v[2]? 0: 2): (v[1] < v[2]? 1: 2);
  2801.                                           // 365
  2802. };
  2803.                                                                                                        // 366
  2804.  
  2805.                                                                                                          // 367
  2806. var Mat3 = function(){
  2807.                                                                                    // 368
  2808.   this.m = [ [0.0, 0.0, 0.0],
  2809.                                                                             // 369
  2810.              [0.0, 0.0, 0.0],
  2811.                                                                             // 370
  2812.              [0.0, 0.0, 0.0] ];
  2813.                                                                           // 371
  2814. };
  2815.                                                                                                        // 372
  2816.  
  2817.                                                                                                          // 373
  2818. Mat3.clone = function(a){
  2819.                                                                                 // 374
  2820.   var matrix = new Mat3(), m = matrix.m;
  2821.                                                                  // 375
  2822.  
  2823.                                                                                                        // 376
  2824.   a = a.m;
  2825.                                                                                                // 377
  2826.  
  2827.                                                                                                          // 378
  2828.   m[0][0] = a[0][0];
  2829.                                                                                      // 379
  2830.   m[0][1] = a[0][1];
  2831.                                                                                      // 380
  2832.   m[0][2] = a[0][2];
  2833.                                                                                      // 381
  2834.   m[1][0] = a[1][0];
  2835.                                                                                      // 382
  2836.   m[1][1] = a[1][1];
  2837.                                                                                      // 383
  2838.   m[1][2] = a[1][2];
  2839.                                                                                      // 384
  2840.   m[2][0] = a[2][0];
  2841.                                                                                      // 385
  2842.   m[2][1] = a[2][1];
  2843.                                                                                      // 386
  2844.   m[2][2] = a[2][2];
  2845.                                                                                      // 387
  2846.  
  2847.                                                                                                        // 388
  2848.   return matrix;
  2849.                                                                                          // 389
  2850. };
  2851.                                                                                                        // 390
  2852.  
  2853.                                                                                                          // 391
  2854. Mat3.prototype.copy = function(a){
  2855.                                                                        // 392
  2856.   var m = this.m;
  2857.                                                                                         // 393
  2858.  
  2859.                                                                                                          // 394
  2860.   a = a.m;
  2861.                                                                                                // 395
  2862.  
  2863.                                                                                                          // 396
  2864.   m[0][0] = a[0][0];
  2865.                                                                                      // 397
  2866.   m[0][1] = a[0][1];
  2867.                                                                                      // 398
  2868.   m[0][2] = a[0][2];
  2869.                                                                                      // 399
  2870.   m[1][0] = a[1][0];
  2871.                                                                                      // 400
  2872.   m[1][1] = a[1][1];
  2873.                                                                                      // 401
  2874.   m[1][2] = a[1][2];
  2875.                                                                                      // 402
  2876.   m[2][0] = a[2][0];
  2877.                                                                                      // 403
  2878.   m[2][1] = a[2][1];
  2879.                                                                                      // 404
  2880.   m[2][2] = a[2][2];
  2881.                                                                                      // 405
  2882.  
  2883.                                                                                                          // 406
  2884.   return this;
  2885.                                                                                            // 407
  2886. };
  2887.                                                                                                        // 408
  2888.  
  2889.                                                                                                          // 409
  2890. Mat3.fromRows = function(a, b, c){
  2891.                                                                        // 410
  2892.   var matrix = new Mat3(), m = matrix.m;
  2893.                                                                  // 411
  2894.  
  2895.                                                                                                        // 412
  2896.   a = a.v; b = b.v; c = c.v;
  2897.                                                                              // 413
  2898.  
  2899.                                                                                                        // 414
  2900.   m[0][0] = a[0];
  2901.                                                                                         // 415
  2902.   m[0][1] = a[1];
  2903.                                                                                         // 416
  2904.   m[0][2] = a[2];
  2905.                                                                                         // 417
  2906.   m[1][0] = b[0];
  2907.                                                                                         // 418
  2908.   m[1][1] = b[1];
  2909.                                                                                         // 419
  2910.   m[1][2] = b[2];
  2911.                                                                                         // 420
  2912.   m[2][0] = c[0];
  2913.                                                                                         // 421
  2914.   m[2][1] = c[1];
  2915.                                                                                         // 422
  2916.   m[2][2] = c[2];
  2917.                                                                                         // 423
  2918.  
  2919.                                                                                                          // 424
  2920.   return matrix;
  2921.                                                                                          // 425
  2922. };
  2923.                                                                                                        // 426
  2924.  
  2925.                                                                                                          // 427
  2926. Mat3.fromDiagonal = function(a){
  2927.                                                                          // 428
  2928.   var matrix = new Mat3(), m = matrix.m;
  2929.                                                                  // 429
  2930.  
  2931.                                                                                                        // 430
  2932.   a = a.v;
  2933.                                                                                                // 431
  2934.  
  2935.                                                                                                        // 432
  2936.   m[0][0] = a[0];
  2937.                                                                                         // 433
  2938.   m[1][1] = a[1];
  2939.                                                                                         // 434
  2940.   m[2][2] = a[2];
  2941.                                                                                         // 435
  2942.  
  2943.                                                                                                        // 436
  2944.   return matrix;
  2945.                                                                                          // 437
  2946. };
  2947.                                                                                                        // 438
  2948.  
  2949.                                                                                                          // 439
  2950. Mat3.transpose = function(a){
  2951.                                                                             // 440
  2952.   var matrix = new Mat3(), m = matrix.m;
  2953.                                                                  // 441
  2954.  
  2955.                                                                                                        // 442
  2956.   a = a.m;
  2957.                                                                                                // 443
  2958.  
  2959.                                                                                                        // 444
  2960.   m[0][0] = a[0][0];
  2961.                                                                                      // 445
  2962.   m[0][1] = a[1][0];
  2963.                                                                                      // 446
  2964.   m[0][2] = a[2][0];
  2965.                                                                                      // 447
  2966.   m[1][0] = a[0][1];
  2967.                                                                                      // 448
  2968.   m[1][1] = a[1][1];
  2969.                                                                                      // 449
  2970.   m[1][2] = a[2][1];
  2971.                                                                                      // 450
  2972.   m[2][0] = a[0][2];
  2973.                                                                                      // 451
  2974.   m[2][1] = a[1][2];
  2975.                                                                                      // 452
  2976.   m[2][2] = a[2][2];
  2977.                                                                                      // 453
  2978.            
  2979.                                                                                              // 454
  2980.   return matrix;
  2981.                                                                                          // 455
  2982. };
  2983.                                                                                                        // 456
  2984.  
  2985.                                                                                                          // 457
  2986. Mat3.mult = function(a, b){
  2987.                                                                               // 458
  2988.   var matrix = new Mat3(), m = matrix.m;
  2989.                                                                  // 459
  2990.  
  2991.                                                                                                        // 460
  2992.   a = a.m; b = b.m;
  2993.                                                                                       // 461
  2994.  
  2995.                                                                                                          // 462
  2996.   m[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0];
  2997.                                    // 463
  2998.   m[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1];
  2999.                                    // 464
  3000.   m[0][2] = a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2];
  3001.                                    // 465
  3002.   m[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0];
  3003.                                    // 466
  3004.   m[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1];
  3005.                                    // 467
  3006.   m[1][2] = a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2];
  3007.                                    // 468
  3008.   m[2][0] = a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0];
  3009.                                    // 469
  3010.   m[2][1] = a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1];
  3011.                                    // 470
  3012.   m[2][2] = a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2];
  3013.                                    // 471
  3014.  
  3015.                                                                                                          // 472
  3016.   return matrix;
  3017.                                                                                          // 473
  3018. };
  3019.                                                                                                        // 474
  3020.  
  3021.                                                                                                          // 475
  3022. Mat3.multVector = function(m, a){
  3023.                                                                         // 476
  3024.   m = m.m; a = a.v;
  3025.                                                                                       // 477
  3026.  
  3027.                                                                                                        // 478
  3028.   return new Vec3(
  3029.                                                                                        // 479
  3030.     m[0][0] * a[0] + m[0][1] * a[1] + m[0][2] * a[2],
  3031.                                                     // 480
  3032.     m[1][0] * a[0] + m[1][1] * a[1] + m[1][2] * a[2],
  3033.                                                     // 481
  3034.     m[2][0] * a[0] + m[2][1] * a[1] + m[2][2] * a[2]);
  3035.                                                    // 482
  3036. };
  3037.                                                                                                        // 483
  3038.  
  3039.                                                                                                          // 484
  3040. Mat3.prototype.column = function(index){
  3041.                                                                  // 485
  3042.   var m = this.m;
  3043.                                                                                         // 486
  3044.  
  3045.                                                                                                        // 487
  3046.   return new Vec3( m[0][index], m[1][index], m[2][index] );
  3047.                                               // 488
  3048. };
  3049.                                                                                                        // 489
  3050.  
  3051.                                                                                                          // 490
  3052. Mat3.prototype.row = function(index){
  3053.                                                                     // 491
  3054.   var m = this.m;
  3055.                                                                                         // 492
  3056.  
  3057.                                                                                                        // 493
  3058.   return new Vec3( m[index][0], m[index][1], m[index][2] );
  3059.                                               // 494
  3060. };
  3061.                                                                                                        // 495
  3062.                                                                                                           // 496
  3063. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3064.  
  3065. }).call(this);
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072. (function () {
  3073.  
  3074. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3075. //                                                                                                        //
  3076. // packages/js-aruco/svd.js                                                                               //
  3077. //                                                                                                        //
  3078. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3079.                                                                                                           //
  3080. /*
  3081.                                                                                                        // 1
  3082. Copyright (c) 2012 Juan Mellado
  3083.                                                                           // 2
  3084.  
  3085.                                                                                                          // 3
  3086. Permission is hereby granted, free of charge, to any person obtaining a copy
  3087.                              // 4
  3088. of this software and associated documentation files (the "Software"), to deal
  3089.                             // 5
  3090. in the Software without restriction, including without limitation the rights
  3091.                              // 6
  3092. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  3093.                                 // 7
  3094. copies of the Software, and to permit persons to whom the Software is
  3095.                                     // 8
  3096. furnished to do so, subject to the following conditions:
  3097.                                                  // 9
  3098.  
  3099.                                                                                                          // 10
  3100. The above copyright notice and this permission notice shall be included in
  3101.                                // 11
  3102. all copies or substantial portions of the Software.
  3103.                                                       // 12
  3104.  
  3105.                                                                                                          // 13
  3106. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3107.                                // 14
  3108. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3109.                                  // 15
  3110. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3111.                               // 16
  3112. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  3113.                                    // 17
  3114. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  3115.                             // 18
  3116. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  3117.                                 // 19
  3118. THE SOFTWARE.
  3119.                                                                                             // 20
  3120. */
  3121.                                                                                                        // 21
  3122.  
  3123.                                                                                                          // 22
  3124. /*
  3125.                                                                                                        // 23
  3126. References:
  3127.                                                                                               // 24
  3128. - "Numerical Recipes in C - Second Edition"
  3129.                                                               // 25
  3130.   http://www.nr.com/
  3131.                                                                                      // 26
  3132. */
  3133.                                                                                                        // 27
  3134.  
  3135.                                                                                                          // 28
  3136. var SVD = SVD || {};
  3137.                                                                                      // 29
  3138.  
  3139.                                                                                                          // 30
  3140. SVD.svdcmp = function(a, m, n, w, v){
  3141.                                                                     // 31
  3142.   var flag, i, its, j, jj, k, l, nm,
  3143.                                                                      // 32
  3144.       anorm = 0.0, c, f, g = 0.0, h, s, scale = 0.0, x, y, z, rv1 = [];
  3145.                                   // 33
  3146.      
  3147.                                                                                                    // 34
  3148.   //Householder reduction to bidiagonal form
  3149.                                                              // 35
  3150.   for (i = 0; i < n; ++ i){
  3151.                                                                               // 36
  3152.     l = i + 1;
  3153.                                                                                            // 37
  3154.     rv1[i] = scale * g;
  3155.                                                                                   // 38
  3156.     g = s = scale = 0.0;
  3157.                                                                                  // 39
  3158.     if (i < m){
  3159.                                                                                           // 40
  3160.       for (k = i; k < m; ++ k){
  3161.                                                                           // 41
  3162.         scale += Math.abs( a[k][i] );
  3163.                                                                     // 42
  3164.       }
  3165.                                                                                                   // 43
  3166.       if (0.0 !== scale){
  3167.                                                                                 // 44
  3168.         for (k = i; k < m; ++ k){
  3169.                                                                         // 45
  3170.           a[k][i] /= scale;
  3171.                                                                               // 46
  3172.           s += a[k][i] * a[k][i];
  3173.                                                                         // 47
  3174.         }
  3175.                                                                                                 // 48
  3176.         f = a[i][i];
  3177.                                                                                      // 49
  3178.         g = -SVD.sign( Math.sqrt(s), f );
  3179.                                                                 // 50
  3180.         h = f * g - s;
  3181.                                                                                    // 51
  3182.         a[i][i] = f - g;
  3183.                                                                                  // 52
  3184.         for (j = l; j < n; ++ j){
  3185.                                                                         // 53
  3186.           for (s = 0.0, k = i; k < m; ++ k){
  3187.                                                              // 54
  3188.             s += a[k][i] * a[k][j];
  3189.                                                                       // 55
  3190.           }
  3191.                                                                                               // 56
  3192.           f = s / h;
  3193.                                                                                      // 57
  3194.           for (k = i; k < m; ++ k){
  3195.                                                                       // 58
  3196.             a[k][j] += f * a[k][i];
  3197.                                                                       // 59
  3198.           }
  3199.                                                                                               // 60
  3200.         }
  3201.                                                                                                 // 61
  3202.         for (k = i; k < m; ++ k){
  3203.                                                                         // 62
  3204.           a[k][i] *= scale;
  3205.                                                                               // 63
  3206.         }
  3207.                                                                                                 // 64
  3208.       }
  3209.                                                                                                   // 65
  3210.     }
  3211.                                                                                                     // 66
  3212.     w[i] = scale * g;
  3213.                                                                                     // 67
  3214.     g = s = scale = 0.0;
  3215.                                                                                  // 68
  3216.     if ( (i < m) && (i !== n - 1) ){
  3217.                                                                      // 69
  3218.       for (k = l; k < n; ++ k){
  3219.                                                                           // 70
  3220.         scale += Math.abs( a[i][k] );
  3221.                                                                     // 71
  3222.       }
  3223.                                                                                                   // 72
  3224.       if (0.0 !== scale){
  3225.                                                                                 // 73
  3226.         for (k = l; k < n; ++ k){
  3227.                                                                         // 74
  3228.           a[i][k] /= scale;
  3229.                                                                               // 75
  3230.           s += a[i][k] * a[i][k];
  3231.                                                                         // 76
  3232.         }
  3233.                                                                                                 // 77
  3234.         f = a[i][l];
  3235.                                                                                      // 78
  3236.         g = -SVD.sign( Math.sqrt(s), f );
  3237.                                                                 // 79
  3238.         h = f * g - s;
  3239.                                                                                    // 80
  3240.         a[i][l] = f - g;
  3241.                                                                                  // 81
  3242.         for (k = l; k < n; ++ k){
  3243.                                                                         // 82
  3244.           rv1[k] = a[i][k] / h;
  3245.                                                                           // 83
  3246.         }
  3247.                                                                                                 // 84
  3248.         for (j = l; j < m; ++ j){
  3249.                                                                         // 85
  3250.           for (s = 0.0, k = l; k < n; ++ k){
  3251.                                                              // 86
  3252.             s += a[j][k] * a[i][k];
  3253.                                                                       // 87
  3254.           }
  3255.                                                                                               // 88
  3256.           for (k = l; k < n; ++ k){
  3257.                                                                       // 89
  3258.             a[j][k] += s * rv1[k];
  3259.                                                                        // 90
  3260.           }
  3261.                                                                                               // 91
  3262.         }
  3263.                                                                                                 // 92
  3264.         for (k = l; k < n; ++ k){
  3265.                                                                         // 93
  3266.           a[i][k] *= scale;
  3267.                                                                               // 94
  3268.         }
  3269.                                                                                                 // 95
  3270.       }
  3271.                                                                                                   // 96
  3272.     }
  3273.                                                                                                     // 97
  3274.     anorm = Math.max(anorm, ( Math.abs( w[i] ) + Math.abs( rv1[i] ) ) );
  3275.                                  // 98
  3276.   }
  3277.                                                                                                       // 99
  3278.  
  3279.                                                                                                          // 100
  3280.   //Acumulation of right-hand transformation
  3281.                                                              // 101
  3282.   for (i = n - 1; i >= 0; -- i){
  3283.                                                                          // 102
  3284.     if (i < n - 1){
  3285.                                                                                       // 103
  3286.       if (0.0 !== g){
  3287.                                                                                     // 104
  3288.         for (j = l; j < n; ++ j){
  3289.                                                                         // 105
  3290.           v[j][i] = ( a[i][j] / a[i][l] ) / g;
  3291.                                                            // 106
  3292.         }
  3293.                                                                                                 // 107
  3294.         for (j = l; j < n; ++ j){
  3295.                                                                         // 108
  3296.           for (s = 0.0, k = l; k < n; ++ k){
  3297.                                                              // 109
  3298.             s += a[i][k] * v[k][j];
  3299.                                                                       // 110
  3300.           }
  3301.                                                                                               // 111
  3302.           for (k = l; k < n; ++ k){
  3303.                                                                       // 112
  3304.             v[k][j] += s * v[k][i];
  3305.                                                                       // 113
  3306.           }
  3307.                                                                                               // 114
  3308.         }
  3309.                                                                                                 // 115
  3310.       }
  3311.                                                                                                   // 116
  3312.       for (j = l; j < n; ++ j){
  3313.                                                                           // 117
  3314.         v[i][j] = v[j][i] = 0.0;
  3315.                                                                          // 118
  3316.       }
  3317.                                                                                                   // 119
  3318.     }
  3319.                                                                                                     // 120
  3320.     v[i][i] = 1.0;
  3321.                                                                                        // 121
  3322.     g = rv1[i];
  3323.                                                                                           // 122
  3324.     l = i;
  3325.                                                                                                // 123
  3326.   }
  3327.                                                                                                       // 124
  3328.  
  3329.                                                                                                          // 125
  3330.   //Acumulation of left-hand transformation
  3331.                                                               // 126
  3332.   for (i = Math.min(n, m) - 1; i >= 0; -- i){
  3333.                                                             // 127
  3334.     l = i + 1;
  3335.                                                                                            // 128
  3336.     g = w[i];
  3337.                                                                                             // 129
  3338.     for (j = l; j < n; ++ j){
  3339.                                                                             // 130
  3340.       a[i][j] = 0.0;
  3341.                                                                                      // 131
  3342.     }
  3343.                                                                                                     // 132
  3344.     if (0.0 !== g){
  3345.                                                                                       // 133
  3346.       g = 1.0 / g;
  3347.                                                                                        // 134
  3348.       for (j = l; j < n; ++ j){
  3349.                                                                           // 135
  3350.         for (s = 0.0, k = l; k < m; ++ k){
  3351.                                                                // 136
  3352.           s += a[k][i] * a[k][j];
  3353.                                                                         // 137
  3354.         }
  3355.                                                                                                 // 138
  3356.         f = (s / a[i][i]) * g;
  3357.                                                                            // 139
  3358.         for (k = i; k < m; ++ k){
  3359.                                                                         // 140
  3360.           a[k][j] += f * a[k][i];
  3361.                                                                         // 141
  3362.         }
  3363.                                                                                                 // 142
  3364.       }
  3365.                                                                                                   // 143
  3366.       for (j = i; j < m; ++ j){
  3367.                                                                           // 144
  3368.         a[j][i] *= g;
  3369.                                                                                     // 145
  3370.       }
  3371.                                                                                                   // 146
  3372.     }else{
  3373.                                                                                                // 147
  3374.         for (j = i; j < m; ++ j){
  3375.                                                                         // 148
  3376.           a[j][i] = 0.0;
  3377.                                                                                  // 149
  3378.         }
  3379.                                                                                                 // 150
  3380.     }
  3381.                                                                                                     // 151
  3382.     ++ a[i][i];
  3383.                                                                                           // 152
  3384.   }
  3385.                                                                                                       // 153
  3386.  
  3387.                                                                                                          // 154
  3388.   //Diagonalization of the bidiagonal form
  3389.                                                                // 155
  3390.   for (k = n - 1; k >= 0; -- k){
  3391.                                                                          // 156
  3392.     for (its = 1; its <= 30; ++ its){
  3393.                                                                     // 157
  3394.       flag = true;
  3395.                                                                                        // 158
  3396.       for (l = k; l >= 0; -- l){
  3397.                                                                          // 159
  3398.         nm = l - 1;
  3399.                                                                                       // 160
  3400.         if ( Math.abs( rv1[l] ) + anorm === anorm ){
  3401.                                                      // 161
  3402.           flag = false;
  3403.                                                                                   // 162
  3404.           break;
  3405.                                                                                          // 163
  3406.         }
  3407.                                                                                                 // 164
  3408.         if ( Math.abs( w[nm] ) + anorm === anorm ){
  3409.                                                       // 165
  3410.           break;
  3411.                                                                                          // 166
  3412.         }
  3413.                                                                                                 // 167
  3414.       }
  3415.                                                                                                   // 168
  3416.       if (flag){
  3417.                                                                                          // 169
  3418.         c = 0.0;
  3419.                                                                                          // 170
  3420.         s = 1.0;
  3421.                                                                                          // 171
  3422.         for (i = l; i <= k; ++ i){
  3423.                                                                        // 172
  3424.           f = s * rv1[i];
  3425.                                                                                 // 173
  3426.           if ( Math.abs(f) + anorm === anorm ){
  3427.                                                           // 174
  3428.             break;
  3429.                                                                                        // 175
  3430.           }
  3431.                                                                                               // 176
  3432.           g = w[i];
  3433.                                                                                       // 177
  3434.           h = SVD.pythag(f, g);
  3435.                                                                           // 178
  3436.           w[i] = h;
  3437.                                                                                       // 179
  3438.           h = 1.0 / h;
  3439.                                                                                    // 180
  3440.           c = g * h;
  3441.                                                                                      // 181
  3442.           s = -f * h;
  3443.                                                                                     // 182
  3444.           for (j = 1; j <= m; ++ j){
  3445.                                                                      // 183
  3446.             y = a[j][nm];
  3447.                                                                                 // 184
  3448.             z = a[j][i];
  3449.                                                                                  // 185
  3450.             a[j][nm] = y * c + z * s;
  3451.                                                                     // 186
  3452.             a[j][i] = z * c - y * s;
  3453.                                                                      // 187
  3454.           }
  3455.                                                                                               // 188
  3456.         }
  3457.                                                                                                 // 189
  3458.       }
  3459.                                                                                                   // 190
  3460.  
  3461.                                                                                                          // 191
  3462.       //Convergence
  3463.                                                                                       // 192
  3464.       z = w[k];
  3465.                                                                                           // 193
  3466.       if (l === k){
  3467.                                                                                       // 194
  3468.         if (z < 0.0){
  3469.                                                                                     // 195
  3470.           w[k] = -z;
  3471.                                                                                      // 196
  3472.           for (j = 0; j < n; ++ j){
  3473.                                                                       // 197
  3474.             v[j][k] = -v[j][k];
  3475.                                                                           // 198
  3476.           }
  3477.                                                                                               // 199
  3478.         }
  3479.                                                                                                 // 200
  3480.         break;
  3481.                                                                                            // 201
  3482.       }
  3483.                                                                                                   // 202
  3484.  
  3485.                                                                                                          // 203
  3486.       if (30 === its){
  3487.                                                                                    // 204
  3488.         return false;
  3489.                                                                                     // 205
  3490.       }
  3491.                                                                                                   // 206
  3492.  
  3493.                                                                                                          // 207
  3494.       //Shift from bottom 2-by-2 minor
  3495.                                                                    // 208
  3496.       x = w[l];
  3497.                                                                                           // 209
  3498.       nm = k - 1;
  3499.                                                                                         // 210
  3500.       y = w[nm];
  3501.                                                                                          // 211
  3502.       g = rv1[nm];
  3503.                                                                                        // 212
  3504.       h = rv1[k];
  3505.                                                                                         // 213
  3506.       f = ( (y - z) * (y + z) + (g - h) * (g + h) ) / (2.0 * h * y);
  3507.                                      // 214
  3508.       g = SVD.pythag( f, 1.0 );
  3509.                                                                           // 215
  3510.       f = ( (x - z) * (x + z) + h * ( (y / (f + SVD.sign(g, f) ) ) - h) ) / x;
  3511.                            // 216
  3512.  
  3513.                                                                                                          // 217
  3514.       //Next QR transformation
  3515.                                                                            // 218
  3516.       c = s = 1.0;
  3517.                                                                                        // 219
  3518.       for (j = l; j <= nm; ++ j){
  3519.                                                                         // 220
  3520.         i = j + 1;
  3521.                                                                                        // 221
  3522.         g = rv1[i];
  3523.                                                                                       // 222
  3524.         y = w[i];
  3525.                                                                                         // 223
  3526.         h = s * g;
  3527.                                                                                        // 224
  3528.         g = c * g;
  3529.                                                                                        // 225
  3530.         z = SVD.pythag(f, h);
  3531.                                                                             // 226
  3532.         rv1[j] = z;
  3533.                                                                                       // 227
  3534.         c = f / z;
  3535.                                                                                        // 228
  3536.         s = h / z;
  3537.                                                                                        // 229
  3538.         f = x * c + g * s;
  3539.                                                                                // 230
  3540.         g = g * c - x * s;
  3541.                                                                                // 231
  3542.         h = y * s;
  3543.                                                                                        // 232
  3544.         y *= c;
  3545.                                                                                           // 233
  3546.         for (jj = 0; jj < n; ++ jj){
  3547.                                                                      // 234
  3548.           x = v[jj][j];
  3549.                                                                                   // 235
  3550.           z = v[jj][i];
  3551.                                                                                   // 236
  3552.           v[jj][j] = x * c + z * s;
  3553.                                                                       // 237
  3554.           v[jj][i] = z * c - x * s;
  3555.                                                                       // 238
  3556.         }
  3557.                                                                                                 // 239
  3558.         z = SVD.pythag(f, h);
  3559.                                                                             // 240
  3560.         w[j] = z;
  3561.                                                                                         // 241
  3562.         if (0.0 !== z){
  3563.                                                                                   // 242
  3564.           z = 1.0 / z;
  3565.                                                                                    // 243
  3566.           c = f * z;
  3567.                                                                                      // 244
  3568.           s = h * z;
  3569.                                                                                      // 245
  3570.         }
  3571.                                                                                                 // 246
  3572.         f = c * g + s * y;
  3573.                                                                                // 247
  3574.         x = c * y - s * g;
  3575.                                                                                // 248
  3576.         for (jj = 0; jj < m; ++ jj){
  3577.                                                                      // 249
  3578.           y = a[jj][j];
  3579.                                                                                   // 250
  3580.           z = a[jj][i];
  3581.                                                                                   // 251
  3582.           a[jj][j] = y * c + z * s;
  3583.                                                                       // 252
  3584.           a[jj][i] = z * c - y * s;
  3585.                                                                       // 253
  3586.         }
  3587.                                                                                                 // 254
  3588.       }
  3589.                                                                                                   // 255
  3590.       rv1[l] = 0.0;
  3591.                                                                                       // 256
  3592.       rv1[k] = f;
  3593.                                                                                         // 257
  3594.       w[k] = x;
  3595.                                                                                           // 258
  3596.     }
  3597.                                                                                                     // 259
  3598.   }
  3599.                                                                                                       // 260
  3600.  
  3601.                                                                                                          // 261
  3602.   return true;
  3603.                                                                                            // 262
  3604. };
  3605.                                                                                                        // 263
  3606.  
  3607.                                                                                                          // 264
  3608. SVD.pythag = function(a, b){
  3609.                                                                              // 265
  3610.   var at = Math.abs(a), bt = Math.abs(b), ct;
  3611.                                                             // 266
  3612.  
  3613.                                                                                                          // 267
  3614.   if (at > bt){
  3615.                                                                                           // 268
  3616.     ct = bt / at;
  3617.                                                                                         // 269
  3618.     return at * Math.sqrt(1.0 + ct * ct);
  3619.                                                                 // 270
  3620.   }
  3621.                                                                                                       // 271
  3622.    
  3623.                                                                                                      // 272
  3624.   if (0.0 === bt){
  3625.                                                                                        // 273
  3626.     return 0.0;
  3627.                                                                                           // 274
  3628.   }
  3629.                                                                                                       // 275
  3630.  
  3631.                                                                                                          // 276
  3632.   ct = at / bt;
  3633.                                                                                           // 277
  3634.   return bt * Math.sqrt(1.0 + ct * ct);
  3635.                                                                   // 278
  3636. };
  3637.                                                                                                        // 279
  3638.  
  3639.                                                                                                          // 280
  3640. SVD.sign = function(a, b){
  3641.                                                                                // 281
  3642.   return b >= 0.0? Math.abs(a): -Math.abs(a);
  3643.                                                             // 282
  3644. };
  3645.                                                                                                        // 283
  3646.                                                                                                           // 284
  3647. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3648.  
  3649. }).call(this);
  3650.  
  3651.  
  3652. /* Exports */
  3653. if (typeof Package === 'undefined') Package = {};
  3654. Package['js-aruco'] = {};
  3655.  
  3656. })();
Add Comment
Please, Sign In to add comment