BVB Source Codes

jsfeat Show jsfeat_motion_estimator.js Source code

Return Download jsfeat: download jsfeat_motion_estimator.js Source code - Download jsfeat Source code - Type:.js
  1. /**
  2.  * @author Eugene Zatepyakin / http://inspirit.ru/
  3.  *
  4.  */
  5.  
  6. (function(global) {
  7.     "use strict";
  8.     //
  9.  
  10.     var motion_model = (function() {
  11.  
  12.         var sqr = function(x) {
  13.                 return x*x;
  14.         }
  15.  
  16.         // does isotropic normalization
  17.         var iso_normalize_points = function(from, to, T0, T1, count) {
  18.                         var i=0;
  19.                     var cx0=0.0, cy0=0.0, d0=0.0, s0=0.0;
  20.                     var cx1=0.0, cy1=0.0, d1=0.0, s1=0.0;
  21.                     var dx=0.0,dy=0.0;
  22.  
  23.                     for (; i < count; ++i) {
  24.                         cx0 += from[i].x;
  25.                         cy0 += from[i].y;
  26.                         cx1 += to[i].x;
  27.                         cy1 += to[i].y;
  28.                     }
  29.  
  30.                     cx0 /= count; cy0 /= count;
  31.                     cx1 /= count; cy1 /= count;
  32.  
  33.                     for (i = 0; i < count; ++i) {
  34.                         dx = from[i].x - cx0;
  35.                         dy = from[i].y - cy0;
  36.                         d0 += Math.sqrt(dx*dx + dy*dy);
  37.                         dx = to[i].x - cx1;
  38.                         dy = to[i].y - cy1;
  39.                         d1 += Math.sqrt(dx*dx + dy*dy);
  40.                     }
  41.  
  42.                     d0 /= count; d1 /= count;
  43.  
  44.                     s0 = Math.SQRT2 / d0; s1 = Math.SQRT2 / d1;
  45.  
  46.                     T0[0] = T0[4] = s0;
  47.                     T0[2] = -cx0*s0;
  48.                     T0[5] = -cy0*s0;
  49.                     T0[1] = T0[3] = T0[6] = T0[7] = 0.0;
  50.                     T0[8] = 1.0;
  51.  
  52.                     T1[0] = T1[4] = s1;
  53.                     T1[2] = -cx1*s1;
  54.                     T1[5] = -cy1*s1;
  55.                     T1[1] = T1[3] = T1[6] = T1[7] = 0.0;
  56.                     T1[8] = 1.0;
  57.                 }
  58.  
  59.                 var have_collinear_points = function(points, count) {
  60.                     var j=0,k=0,i=(count-1)|0;
  61.                     var dx1=0.0,dy1=0.0,dx2=0.0,dy2=0.0;
  62.  
  63.                     // check that the i-th selected point does not belong
  64.                     // to a line connecting some previously selected points
  65.                     for(; j < i; ++j) {
  66.                         dx1 = points[j].x - points[i].x;
  67.                         dy1 = points[j].y - points[i].y;
  68.                         for(k = 0; k < j; ++k) {
  69.                             dx2 = points[k].x - points[i].x;
  70.                             dy2 = points[k].y - points[i].y;
  71.                             if( Math.abs(dx2*dy1 - dy2*dx1) <= jsfeat.EPSILON*(Math.abs(dx1) + Math.abs(dy1) + Math.abs(dx2) + Math.abs(dy2)))
  72.                                 return true;
  73.                         }
  74.                     }
  75.                     return false;
  76.                 }
  77.  
  78.                 var T0 = new jsfeat.matrix_t(3, 3, jsfeat.F32_t|jsfeat.C1_t);
  79.         var T1 = new jsfeat.matrix_t(3, 3, jsfeat.F32_t|jsfeat.C1_t);
  80.         var AtA = new jsfeat.matrix_t(6, 6, jsfeat.F32_t|jsfeat.C1_t);
  81.         var AtB = new jsfeat.matrix_t(6, 1, jsfeat.F32_t|jsfeat.C1_t);
  82.        
  83.         var affine2d = (function () {
  84.  
  85.                 function affine2d() {
  86.                         // empty constructor
  87.                 }
  88.  
  89.                 affine2d.prototype.run = function(from, to, model, count) {
  90.                         var i=0,j=0;
  91.                         var dt=model.type|jsfeat.C1_t;
  92.                         var md=model.data, t0d=T0.data, t1d=T1.data;
  93.                         var pt0,pt1,px=0.0,py=0.0;
  94.  
  95.                     iso_normalize_points(from, to, t0d, t1d, count);
  96.  
  97.                     var a_buff = jsfeat.cache.get_buffer((2*count*6)<<3);
  98.                 var b_buff = jsfeat.cache.get_buffer((2*count)<<3);
  99.  
  100.                 var a_mt = new jsfeat.matrix_t(6, 2*count, dt, a_buff.data);
  101.                 var b_mt = new jsfeat.matrix_t(1, 2*count, dt, b_buff.data);
  102.                 var ad=a_mt.data, bd=b_mt.data;
  103.  
  104.                             for (; i < count; ++i) {
  105.                                 pt0 = from[i];
  106.                                 pt1 = to[i];
  107.  
  108.                                 px = t0d[0]*pt0.x + t0d[1]*pt0.y + t0d[2];
  109.                                 py = t0d[3]*pt0.x + t0d[4]*pt0.y + t0d[5];
  110.  
  111.                                 j = i*2*6;
  112.                                 ad[j]=px, ad[j+1]=py, ad[j+2]=1.0, ad[j+3]=0.0, ad[j+4]=0.0, ad[j+5]=0.0;
  113.  
  114.                                 j += 6;
  115.                                 ad[j]=0.0, ad[j+1]=0.0, ad[j+2]=0.0, ad[j+3]=px, ad[j+4]=py, ad[j+5]=1.0;
  116.  
  117.                                 bd[i<<1] = t1d[0]*pt1.x + t1d[1]*pt1.y + t1d[2];
  118.                                 bd[(i<<1)+1] = t1d[3]*pt1.x + t1d[4]*pt1.y + t1d[5];
  119.                             }
  120.  
  121.                             jsfeat.matmath.multiply_AtA(AtA, a_mt);
  122.                             jsfeat.matmath.multiply_AtB(AtB, a_mt, b_mt);
  123.  
  124.                             jsfeat.linalg.lu_solve(AtA, AtB);
  125.  
  126.                             md[0] = AtB.data[0], md[1]=AtB.data[1], md[2]=AtB.data[2];
  127.                             md[3] = AtB.data[3], md[4]=AtB.data[4], md[5]=AtB.data[5];
  128.                             md[6] = 0.0, md[7] = 0.0, md[8] = 1.0; // fill last row
  129.  
  130.                             // denormalize
  131.                             jsfeat.matmath.invert_3x3(T1, T1);
  132.                             jsfeat.matmath.multiply_3x3(model, T1, model);
  133.                             jsfeat.matmath.multiply_3x3(model, model, T0);
  134.  
  135.                             // free buffer
  136.                             jsfeat.cache.put_buffer(a_buff);
  137.                             jsfeat.cache.put_buffer(b_buff);
  138.  
  139.                             return 1;
  140.                 }
  141.  
  142.                 affine2d.prototype.error = function(from, to, model, err, count) {
  143.                         var i=0;
  144.                         var pt0,pt1;
  145.                         var m=model.data;
  146.  
  147.                             for (; i < count; ++i) {
  148.                                 pt0 = from[i];
  149.                                 pt1 = to[i];
  150.  
  151.                                 err[i] = sqr(pt1.x - m[0]*pt0.x - m[1]*pt0.y - m[2]) +
  152.                                          sqr(pt1.y - m[3]*pt0.x - m[4]*pt0.y - m[5]);
  153.                             }
  154.                 }
  155.  
  156.                 affine2d.prototype.check_subset = function(from, to, count) {
  157.                     return true; // all good
  158.                 }
  159.  
  160.                 return affine2d;
  161.             })();
  162.  
  163.             var mLtL = new jsfeat.matrix_t(9, 9, jsfeat.F32_t|jsfeat.C1_t);
  164.             var Evec = new jsfeat.matrix_t(9, 9, jsfeat.F32_t|jsfeat.C1_t);
  165.  
  166.             var homography2d = (function () {
  167.  
  168.                 function homography2d() {
  169.                         // empty constructor
  170.                         //this.T0 = new jsfeat.matrix_t(3, 3, jsfeat.F32_t|jsfeat.C1_t);
  171.                         //this.T1 = new jsfeat.matrix_t(3, 3, jsfeat.F32_t|jsfeat.C1_t);
  172.                         //this.mLtL = new jsfeat.matrix_t(9, 9, jsfeat.F32_t|jsfeat.C1_t);
  173.                         //this.Evec = new jsfeat.matrix_t(9, 9, jsfeat.F32_t|jsfeat.C1_t);
  174.                 }
  175.  
  176.                 homography2d.prototype.run = function(from, to, model, count) {
  177.                         var i=0,j=0;
  178.                         var md=model.data, t0d=T0.data, t1d=T1.data;
  179.                         var LtL=mLtL.data, evd=Evec.data;
  180.                         var x=0.0,y=0.0,X=0.0,Y=0.0;
  181.  
  182.                             // norm
  183.                                 var smx=0.0, smy=0.0, cmx=0.0, cmy=0.0, sMx=0.0, sMy=0.0, cMx=0.0, cMy=0.0;
  184.  
  185.                                 for(; i < count; ++i) {
  186.                                     cmx += to[i].x;
  187.                                     cmy += to[i].y;
  188.                                     cMx += from[i].x;
  189.                                     cMy += from[i].y;
  190.                                 }
  191.  
  192.                             cmx /= count; cmy /= count;
  193.                             cMx /= count; cMy /= count;
  194.  
  195.                             for(i = 0; i < count; ++i)
  196.                             {
  197.                                     smx += Math.abs(to[i].x - cmx);
  198.                                     smy += Math.abs(to[i].y - cmy);
  199.                                     sMx += Math.abs(from[i].x - cMx);
  200.                                     sMy += Math.abs(from[i].y - cMy);
  201.                                 }
  202.  
  203.                             if( Math.abs(smx) < jsfeat.EPSILON
  204.                                 || Math.abs(smy) < jsfeat.EPSILON
  205.                                 || Math.abs(sMx) < jsfeat.EPSILON
  206.                                 || Math.abs(sMy) < jsfeat.EPSILON ) return 0;
  207.  
  208.                             smx = count/smx; smy = count/smy;
  209.                             sMx = count/sMx; sMy = count/sMy;
  210.  
  211.                             t0d[0] = sMx;       t0d[1] = 0;     t0d[2] = -cMx*sMx;
  212.                             t0d[3] = 0;         t0d[4] = sMy;   t0d[5] = -cMy*sMy;
  213.                             t0d[6] = 0;         t0d[7] = 0;     t0d[8] = 1;
  214.  
  215.                                 t1d[0] = 1.0/smx;       t1d[1] = 0;             t1d[2] = cmx;
  216.                                 t1d[3] = 0;             t1d[4] = 1.0/smy;       t1d[5] = cmy;
  217.                                 t1d[6] = 0;             t1d[7] = 0;             t1d[8] = 1;
  218.                                 //
  219.  
  220.                                 // construct system
  221.                                 i = 81;
  222.                                 while(--i >= 0) {
  223.                                         LtL[i] = 0.0;
  224.                                 }
  225.                                 for(i = 0; i < count; ++i) {
  226.                                         x = (to[i].x - cmx) * smx;
  227.                                         y = (to[i].y - cmy) * smy;
  228.                                         X = (from[i].x - cMx) * sMx;
  229.                                         Y = (from[i].y - cMy) * sMy;
  230.  
  231.                                         LtL[0] += X*X;
  232.                                         LtL[1] += X*Y;
  233.                                         LtL[2] += X;
  234.  
  235.                                         LtL[6] += X*-x*X;
  236.                                         LtL[7] += X*-x*Y;
  237.                                         LtL[8] += X*-x;
  238.                                         LtL[10] += Y*Y;
  239.                                         LtL[11] += Y;
  240.  
  241.                                         LtL[15] += Y*-x*X;
  242.                                         LtL[16] += Y*-x*Y;
  243.                                         LtL[17] += Y*-x;
  244.                                         LtL[20] += 1.0;
  245.  
  246.                                         LtL[24] += -x*X;
  247.                                         LtL[25] += -x*Y;
  248.                                         LtL[26] += -x;
  249.                                         LtL[30] += X*X;
  250.                                         LtL[31] += X*Y;
  251.                                         LtL[32] += X;
  252.                                         LtL[33] += X*-y*X;
  253.                                         LtL[34] += X*-y*Y;
  254.                                         LtL[35] += X*-y;
  255.                                         LtL[40] += Y*Y;
  256.                                         LtL[41] += Y;
  257.                                         LtL[42] += Y*-y*X;
  258.                                         LtL[43] += Y*-y*Y;
  259.                                         LtL[44] += Y*-y;
  260.                                         LtL[50] += 1.0;
  261.                                         LtL[51] += -y*X;
  262.                                         LtL[52] += -y*Y;
  263.                                         LtL[53] += -y;
  264.                                         LtL[60] += -x*X*-x*X + -y*X*-y*X;
  265.                                         LtL[61] += -x*X*-x*Y + -y*X*-y*Y;
  266.                                         LtL[62] += -x*X*-x + -y*X*-y;
  267.                                         LtL[70] += -x*Y*-x*Y + -y*Y*-y*Y;
  268.                                         LtL[71] += -x*Y*-x + -y*Y*-y;
  269.                                         LtL[80] += -x*-x + -y*-y;
  270.                                 }
  271.                                 //
  272.  
  273.                                 // symmetry
  274.                             for(i = 0; i < 9; ++i) {
  275.                                 for(j = 0; j < i; ++j)
  276.                                     LtL[i*9+j] = LtL[j*9+i];
  277.                             }
  278.  
  279.                                 jsfeat.linalg.eigenVV(mLtL, Evec);
  280.  
  281.                                 md[0]=evd[72], md[1]=evd[73], md[2]=evd[74];
  282.                             md[3]=evd[75], md[4]=evd[76], md[5]=evd[77];
  283.                             md[6]=evd[78], md[7]=evd[79], md[8]=evd[80];
  284.  
  285.                                 // denormalize
  286.                             jsfeat.matmath.multiply_3x3(model, T1, model);
  287.                             jsfeat.matmath.multiply_3x3(model, model, T0);
  288.  
  289.                             // set bottom right to 1.0
  290.                             x = 1.0/md[8];
  291.                             md[0] *= x; md[1] *= x; md[2] *= x;
  292.                             md[3] *= x; md[4] *= x; md[5] *= x;
  293.                             md[6] *= x; md[7] *= x; md[8] = 1.0;
  294.  
  295.                             return 1;
  296.                 }
  297.  
  298.                 homography2d.prototype.error = function(from, to, model, err, count) {
  299.                         var i=0;
  300.                         var pt0,pt1,ww=0.0,dx=0.0,dy=0.0;
  301.                         var m=model.data;
  302.  
  303.                             for (; i < count; ++i) {
  304.                                 pt0 = from[i];
  305.                                 pt1 = to[i];
  306.  
  307.                                 ww = 1.0/(m[6]*pt0.x + m[7]*pt0.y + 1.0);
  308.                                 dx = (m[0]*pt0.x + m[1]*pt0.y + m[2])*ww - pt1.x;
  309.                                 dy = (m[3]*pt0.x + m[4]*pt0.y + m[5])*ww - pt1.y;
  310.                                 err[i] = (dx*dx + dy*dy);
  311.                             }
  312.                 }
  313.  
  314.                 homography2d.prototype.check_subset = function(from, to, count) {
  315.                         // seems to reject good subsets actually
  316.                         //if( have_collinear_points(from, count) || have_collinear_points(to, count) ) {
  317.                                 //return false;
  318.                         //}
  319.                         if( count == 4 ) {
  320.                                 var negative = 0;
  321.  
  322.                                 var fp0=from[0],fp1=from[1],fp2=from[2],fp3=from[3];
  323.                                 var tp0=to[0],tp1=to[1],tp2=to[2],tp3=to[3];
  324.  
  325.                                 // set1
  326.                                 var A11=fp0.x, A12=fp0.y, A13=1.0;
  327.                                 var A21=fp1.x, A22=fp1.y, A23=1.0;
  328.                                 var A31=fp2.x, A32=fp2.y, A33=1.0;
  329.  
  330.                                 var B11=tp0.x, B12=tp0.y, B13=1.0;
  331.                                 var B21=tp1.x, B22=tp1.y, B23=1.0;
  332.                                 var B31=tp2.x, B32=tp2.y, B33=1.0;
  333.  
  334.                                 var detA = jsfeat.matmath.determinant_3x3(A11,A12,A13, A21,A22,A23, A31,A32,A33);
  335.                                         var detB = jsfeat.matmath.determinant_3x3(B11,B12,B13, B21,B22,B23, B31,B32,B33);
  336.  
  337.                                         if(detA*detB < 0) negative++;
  338.  
  339.                                         // set2
  340.                                         A11=fp1.x, A12=fp1.y;
  341.                                 A21=fp2.x, A22=fp2.y;
  342.                                 A31=fp3.x, A32=fp3.y;
  343.  
  344.                                 B11=tp1.x, B12=tp1.y;
  345.                                 B21=tp2.x, B22=tp2.y;
  346.                                 B31=tp3.x, B32=tp3.y;
  347.  
  348.                                 detA = jsfeat.matmath.determinant_3x3(A11,A12,A13, A21,A22,A23, A31,A32,A33);
  349.                                         detB = jsfeat.matmath.determinant_3x3(B11,B12,B13, B21,B22,B23, B31,B32,B33);
  350.  
  351.                                         if(detA*detB < 0) negative++;
  352.  
  353.                                         // set3
  354.                                         A11=fp0.x, A12=fp0.y;
  355.                                 A21=fp2.x, A22=fp2.y;
  356.                                 A31=fp3.x, A32=fp3.y;
  357.  
  358.                                 B11=tp0.x, B12=tp0.y;
  359.                                 B21=tp2.x, B22=tp2.y;
  360.                                 B31=tp3.x, B32=tp3.y;
  361.  
  362.                                 detA = jsfeat.matmath.determinant_3x3(A11,A12,A13, A21,A22,A23, A31,A32,A33);
  363.                                         detB = jsfeat.matmath.determinant_3x3(B11,B12,B13, B21,B22,B23, B31,B32,B33);
  364.  
  365.                                         if(detA*detB < 0) negative++;
  366.  
  367.                                         // set4
  368.                                         A11=fp0.x, A12=fp0.y;
  369.                                 A21=fp1.x, A22=fp1.y;
  370.                                 A31=fp3.x, A32=fp3.y;
  371.  
  372.                                 B11=tp0.x, B12=tp0.y;
  373.                                 B21=tp1.x, B22=tp1.y;
  374.                                 B31=tp3.x, B32=tp3.y;
  375.  
  376.                                 detA = jsfeat.matmath.determinant_3x3(A11,A12,A13, A21,A22,A23, A31,A32,A33);
  377.                                         detB = jsfeat.matmath.determinant_3x3(B11,B12,B13, B21,B22,B23, B31,B32,B33);
  378.  
  379.                                         if(detA*detB < 0) negative++;
  380.  
  381.                                 if(negative != 0 && negative != 4) {
  382.                                         return false;
  383.                                 }
  384.                             }
  385.                     return true; // all good
  386.                 }
  387.  
  388.                 return homography2d;
  389.             })();
  390.  
  391.             return {
  392.  
  393.                 affine2d:affine2d,
  394.                 homography2d:homography2d
  395.  
  396.         };
  397.  
  398.     })();
  399.  
  400.     var ransac_params_t = (function () {
  401.         function ransac_params_t(size, thresh, eps, prob) {
  402.             if (typeof size === "undefined") { size=0; }
  403.             if (typeof thresh === "undefined") { thresh=0.5; }
  404.             if (typeof eps === "undefined") { eps=0.5; }
  405.             if (typeof prob === "undefined") { prob=0.99; }
  406.  
  407.             this.size = size;
  408.             this.thresh = thresh;
  409.             this.eps = eps;
  410.             this.prob = prob;
  411.         };
  412.         ransac_params_t.prototype.update_iters = function(_eps, max_iters) {
  413.                 var num = Math.log(1 - this.prob);
  414.                 var denom = Math.log(1 - Math.pow(1 - _eps, this.size));
  415.                 return (denom >= 0 || -num >= max_iters*(-denom) ? max_iters : Math.round(num/denom))|0;
  416.         };
  417.         return ransac_params_t;
  418.     })();
  419.  
  420.     var motion_estimator = (function() {
  421.  
  422.         var get_subset = function(kernel, from, to, need_cnt, max_cnt, from_sub, to_sub) {
  423.                 var max_try = 1000;
  424.                 var indices = [];
  425.                     var i=0, j=0, ssiter=0, idx_i=0, ok=false;
  426.                     for(; ssiter < max_try; ++ssiter)  {
  427.                         i = 0;
  428.                         for (; i < need_cnt && ssiter < max_try;) {
  429.                             ok = false;
  430.                             idx_i = 0;
  431.                             while (!ok) {
  432.                                 ok = true;
  433.                                 idx_i = indices[i] = Math.floor(Math.random() * max_cnt)|0;
  434.                                 for (j = 0; j < i; ++j) {
  435.                                     if (idx_i == indices[j])
  436.                                     { ok = false; break; }
  437.                                 }
  438.                             }
  439.                             from_sub[i] = from[idx_i];
  440.                             to_sub[i] = to[idx_i];
  441.                             if( !kernel.check_subset( from_sub, to_sub, i+1 ) ) {
  442.                                 ssiter++;
  443.                                 continue;
  444.                             }
  445.                             ++i;
  446.                         }
  447.                         break;
  448.                     }
  449.  
  450.                     return (i == need_cnt && ssiter < max_try);
  451.         }
  452.  
  453.         var find_inliers = function(kernel, model, from, to, count, thresh, err, mask) {
  454.                 var numinliers = 0, i=0, f=0;
  455.                 var t = thresh*thresh;
  456.  
  457.                 kernel.error(from, to, model, err, count);
  458.  
  459.                     for(; i < count; ++i) {
  460.                         f = err[i] <= t;
  461.                         mask[i] = f;
  462.                         numinliers += f;
  463.                     }
  464.                     return numinliers;
  465.         }
  466.  
  467.         return {
  468.  
  469.                 ransac: function(params, kernel, from, to, count, model, mask, max_iters) {
  470.                         if (typeof max_iters === "undefined") { max_iters=1000; }
  471.  
  472.                         if(count < params.size) return false;
  473.  
  474.                         var model_points = params.size;
  475.                             var niters = max_iters, iter=0;
  476.                             var result = false;
  477.  
  478.                             var subset0 = [];
  479.                             var subset1 = [];
  480.                             var found = false;
  481.  
  482.                             var mc=model.cols,mr=model.rows;
  483.                 var dt = model.type | jsfeat.C1_t;
  484.  
  485.                             var m_buff = jsfeat.cache.get_buffer((mc*mr)<<3);
  486.                             var ms_buff = jsfeat.cache.get_buffer(count);
  487.                             var err_buff = jsfeat.cache.get_buffer(count<<2);
  488.                             var M = new jsfeat.matrix_t(mc, mr, dt, m_buff.data);
  489.                             var curr_mask = new jsfeat.matrix_t(count, 1, jsfeat.U8C1_t, ms_buff.data);
  490.  
  491.                             var inliers_max = -1, numinliers=0;
  492.                             var nmodels = 0;
  493.  
  494.                             var err = err_buff.f32;
  495.  
  496.                             // special case
  497.                             if(count == model_points) {
  498.                                 if(kernel.run(from, to, M, count) <= 0) {
  499.                                         jsfeat.cache.put_buffer(m_buff);
  500.                                         jsfeat.cache.put_buffer(ms_buff);
  501.                                         jsfeat.cache.put_buffer(err_buff);
  502.                                         return false;
  503.                                 }
  504.  
  505.                                 M.copy_to(model);
  506.                                 if(mask) {
  507.                                         while(--count >= 0) {
  508.                                                 mask.data[count] = 1;
  509.                                         }
  510.                                 }
  511.                                 jsfeat.cache.put_buffer(m_buff);
  512.                                 jsfeat.cache.put_buffer(ms_buff);
  513.                                 jsfeat.cache.put_buffer(err_buff);
  514.                                 return true;
  515.                             }
  516.  
  517.                             for (; iter < niters; ++iter) {
  518.                                 // generate subset
  519.                                 found = get_subset(kernel, from, to, model_points, count, subset0, subset1);
  520.                                 if(!found) {
  521.                                     if(iter == 0) {
  522.                                         jsfeat.cache.put_buffer(m_buff);
  523.                                         jsfeat.cache.put_buffer(ms_buff);
  524.                                         jsfeat.cache.put_buffer(err_buff);
  525.                                         return false;
  526.                                     }
  527.                                     break;
  528.                                 }
  529.  
  530.                                 nmodels = kernel.run( subset0, subset1, M, model_points );
  531.                                 if(nmodels <= 0)
  532.                                     continue;
  533.  
  534.                                 // TODO handle multimodel output
  535.  
  536.                                 numinliers = find_inliers(kernel, M, from, to, count, params.thresh, err, curr_mask.data);
  537.  
  538.                                 if( numinliers > Math.max(inliers_max, model_points-1) ) {
  539.                                     M.copy_to(model);
  540.                                     inliers_max = numinliers;
  541.                                     if(mask) curr_mask.copy_to(mask);
  542.                                     niters = params.update_iters((count - numinliers)/count, niters);
  543.                                     result = true;
  544.                                 }
  545.                             }
  546.  
  547.                             jsfeat.cache.put_buffer(m_buff);
  548.                             jsfeat.cache.put_buffer(ms_buff);
  549.                             jsfeat.cache.put_buffer(err_buff);
  550.  
  551.                             return result;
  552.                 },
  553.  
  554.                 lmeds: function(params, kernel, from, to, count, model, mask, max_iters) {
  555.                         if (typeof max_iters === "undefined") { max_iters=1000; }
  556.  
  557.                         if(count < params.size) return false;
  558.  
  559.                         var model_points = params.size;
  560.                             var niters = max_iters, iter=0;
  561.                             var result = false;
  562.  
  563.                             var subset0 = [];
  564.                             var subset1 = [];
  565.                             var found = false;
  566.  
  567.                             var mc=model.cols,mr=model.rows;
  568.                 var dt = model.type | jsfeat.C1_t;
  569.  
  570.                             var m_buff = jsfeat.cache.get_buffer((mc*mr)<<3);
  571.                             var ms_buff = jsfeat.cache.get_buffer(count);
  572.                             var err_buff = jsfeat.cache.get_buffer(count<<2);
  573.                             var M = new jsfeat.matrix_t(mc, mr, dt, m_buff.data);
  574.                             var curr_mask = new jsfeat.matrix_t(count, 1, jsfeat.U8_t|jsfeat.C1_t, ms_buff.data);
  575.  
  576.                             var numinliers=0;
  577.                             var nmodels = 0;
  578.  
  579.                             var err = err_buff.f32;
  580.                             var min_median = 1000000000.0, sigma=0.0, median=0.0;
  581.  
  582.                             params.eps = 0.45;
  583.                             niters = params.update_iters(params.eps, niters);
  584.  
  585.                             // special case
  586.                             if(count == model_points) {
  587.                                 if(kernel.run(from, to, M, count) <= 0) {
  588.                                         jsfeat.cache.put_buffer(m_buff);
  589.                                         jsfeat.cache.put_buffer(ms_buff);
  590.                                         jsfeat.cache.put_buffer(err_buff);
  591.                                         return false;
  592.                                 }
  593.  
  594.                                 M.copy_to(model);
  595.                                 if(mask) {
  596.                                         while(--count >= 0) {
  597.                                                 mask.data[count] = 1;
  598.                                         }
  599.                                 }
  600.                                 jsfeat.cache.put_buffer(m_buff);
  601.                                 jsfeat.cache.put_buffer(ms_buff);
  602.                                 jsfeat.cache.put_buffer(err_buff);
  603.                                 return true;
  604.                             }
  605.  
  606.                             for (; iter < niters; ++iter) {
  607.                                 // generate subset
  608.                                 found = get_subset(kernel, from, to, model_points, count, subset0, subset1);
  609.                                 if(!found) {
  610.                                     if(iter == 0) {
  611.                                         jsfeat.cache.put_buffer(m_buff);
  612.                                         jsfeat.cache.put_buffer(ms_buff);
  613.                                         jsfeat.cache.put_buffer(err_buff);
  614.                                         return false;
  615.                                     }
  616.                                     break;
  617.                                 }
  618.  
  619.                                 nmodels = kernel.run( subset0, subset1, M, model_points );
  620.                                 if(nmodels <= 0)
  621.                                     continue;
  622.  
  623.                                 // TODO handle multimodel output
  624.  
  625.                                 kernel.error(from, to, M, err, count);
  626.                                 median = jsfeat.math.median(err, 0, count-1);
  627.  
  628.                                 if(median < min_median) {
  629.                                     min_median = median;
  630.                                     M.copy_to(model);
  631.                                     result = true;
  632.                                 }
  633.                             }
  634.  
  635.                             if(result) {
  636.                                 sigma = 2.5*1.4826*(1 + 5.0/(count - model_points))*Math.sqrt(min_median);
  637.                                 sigma = Math.max(sigma, 0.001);
  638.  
  639.                                 numinliers = find_inliers(kernel, model, from, to, count, sigma, err, curr_mask.data);
  640.                                 if(mask) curr_mask.copy_to(mask);
  641.                                
  642.                                 result = numinliers >= model_points;
  643.                             }
  644.  
  645.                             jsfeat.cache.put_buffer(m_buff);
  646.                             jsfeat.cache.put_buffer(ms_buff);
  647.                             jsfeat.cache.put_buffer(err_buff);
  648.  
  649.                             return result;
  650.                 }
  651.  
  652.         };
  653.  
  654.     })();
  655.  
  656.     global.ransac_params_t = ransac_params_t;
  657.     global.motion_model = motion_model;
  658.     global.motion_estimator = motion_estimator;
  659.  
  660. })(jsfeat);
  661.  
downloadjsfeat_motion_estimator.js Source code - Download jsfeat Source code
Related Source Codes/Software:
flakes - Flakes is an Admin Template Framework. A combinati... 2017-04-15
capstone - Capstone disassembly/disassembler framework: Core ... 2017-04-15
nginx-resources - A collection of resources covering Nginx, Nginx + ... 2017-04-15
utron - A lightweight MVC framework for Go(Golang) 2017-04-15
cfssl - CFSSL: Cloudflare's PKI and TLS toolkit ... 2017-04-15
MLeaksFinder - Find memory leaks in your iOS app at develop time. 2017-04-16
qt - Qt binding for Go (Golang) which supports Windows ... 2017-04-16
rainloop-webmail - Simple, modern & fast web-based email client ... 2017-04-16
pencil - Multiplatform GUI Prototyping/Wireframing 2017-04-16
x64dbg - An open-source x64/x32 debugger for windows. ... 2017-04-16
Toucan - Fabulous Image Processing in Swift 2017-04-23
CoffeeScriptRedux - 2017-04-23
breakpoint - Really simple media queries in Sa 2017-04-23
libsvm - 2017-04-22
grr - GRR Rapid Response: remote live forensics for inci... 2017-04-22
grit - **Grit is no longer maintained. Check out libgit2/... 2017-04-22
guard-livereload - Guard::LiveReload automatically reload your browse... 2017-04-22
Begin-Latex-in-minutes - Brief Intro to LaTeX for beginners that helps you ... 2017-04-22
wicked - Use wicked to turn your controller into a wizard ... 2017-04-22
flexboxfroggy - A game for learning CSS flexbox ... 2017-04-22

 Back to top