UNPKG

jsfeat

Version:

JavaScript Computer Vision library

415 lines (378 loc) 18.4 kB
/** * @author Eugene Zatepyakin / http://inspirit.ru/ */ (function(global) { "use strict"; // var math = (function() { var qsort_stack = new Int32Array(48*2); return { get_gaussian_kernel: function(size, sigma, kernel, data_type) { var i=0,x=0.0,t=0.0,sigma_x=0.0,scale_2x=0.0; var sum = 0.0; var kern_node = jsfeat.cache.get_buffer(size<<2); var _kernel = kern_node.f32;//new Float32Array(size); if((size&1) == 1 && size <= 7 && sigma <= 0) { switch(size>>1) { case 0: _kernel[0] = 1.0; sum = 1.0; break; case 1: _kernel[0] = 0.25, _kernel[1] = 0.5, _kernel[2] = 0.25; sum = 0.25+0.5+0.25; break; case 2: _kernel[0] = 0.0625, _kernel[1] = 0.25, _kernel[2] = 0.375, _kernel[3] = 0.25, _kernel[4] = 0.0625; sum = 0.0625+0.25+0.375+0.25+0.0625; break; case 3: _kernel[0] = 0.03125, _kernel[1] = 0.109375, _kernel[2] = 0.21875, _kernel[3] = 0.28125, _kernel[4] = 0.21875, _kernel[5] = 0.109375, _kernel[6] = 0.03125; sum = 0.03125+0.109375+0.21875+0.28125+0.21875+0.109375+0.03125; break; } } else { sigma_x = sigma > 0 ? sigma : ((size-1)*0.5 - 1.0)*0.3 + 0.8; scale_2x = -0.5/(sigma_x*sigma_x); for( ; i < size; ++i ) { x = i - (size-1)*0.5; t = Math.exp(scale_2x*x*x); _kernel[i] = t; sum += t; } } if(data_type & jsfeat.U8_t) { // int based kernel sum = 256.0/sum; for (i = 0; i < size; ++i) { kernel[i] = (_kernel[i] * sum + 0.5)|0; } } else { // classic kernel sum = 1.0/sum; for (i = 0; i < size; ++i) { kernel[i] = _kernel[i] * sum; } } jsfeat.cache.put_buffer(kern_node); }, // model is 3x3 matrix_t perspective_4point_transform: function(model, src_x0, src_y0, dst_x0, dst_y0, src_x1, src_y1, dst_x1, dst_y1, src_x2, src_y2, dst_x2, dst_y2, src_x3, src_y3, dst_x3, dst_y3) { var t1 = src_x0; var t2 = src_x2; var t4 = src_y1; var t5 = t1 * t2 * t4; var t6 = src_y3; var t7 = t1 * t6; var t8 = t2 * t7; var t9 = src_y2; var t10 = t1 * t9; var t11 = src_x1; var t14 = src_y0; var t15 = src_x3; var t16 = t14 * t15; var t18 = t16 * t11; var t20 = t15 * t11 * t9; var t21 = t15 * t4; var t24 = t15 * t9; var t25 = t2 * t4; var t26 = t6 * t2; var t27 = t6 * t11; var t28 = t9 * t11; var t30 = 1.0 / (t21-t24 - t25 + t26 - t27 + t28); var t32 = t1 * t15; var t35 = t14 * t11; var t41 = t4 * t1; var t42 = t6 * t41; var t43 = t14 * t2; var t46 = t16 * t9; var t48 = t14 * t9 * t11; var t51 = t4 * t6 * t2; var t55 = t6 * t14; var Hr0 = -(t8-t5 + t10 * t11 - t11 * t7 - t16 * t2 + t18 - t20 + t21 * t2) * t30; var Hr1 = (t5 - t8 - t32 * t4 + t32 * t9 + t18 - t2 * t35 + t27 * t2 - t20) * t30; var Hr2 = t1; var Hr3 = (-t9 * t7 + t42 + t43 * t4 - t16 * t4 + t46 - t48 + t27 * t9 - t51) * t30; var Hr4 = (-t42 + t41 * t9 - t55 * t2 + t46 - t48 + t55 * t11 + t51 - t21 * t9) * t30; var Hr5 = t14; var Hr6 = (-t10 + t41 + t43 - t35 + t24 - t21 - t26 + t27) * t30; var Hr7 = (-t7 + t10 + t16 - t43 + t27 - t28 - t21 + t25) * t30; t1 = dst_x0; t2 = dst_x2; t4 = dst_y1; t5 = t1 * t2 * t4; t6 = dst_y3; t7 = t1 * t6; t8 = t2 * t7; t9 = dst_y2; t10 = t1 * t9; t11 = dst_x1; t14 = dst_y0; t15 = dst_x3; t16 = t14 * t15; t18 = t16 * t11; t20 = t15 * t11 * t9; t21 = t15 * t4; t24 = t15 * t9; t25 = t2 * t4; t26 = t6 * t2; t27 = t6 * t11; t28 = t9 * t11; t30 = 1.0 / (t21-t24 - t25 + t26 - t27 + t28); t32 = t1 * t15; t35 = t14 * t11; t41 = t4 * t1; t42 = t6 * t41; t43 = t14 * t2; t46 = t16 * t9; t48 = t14 * t9 * t11; t51 = t4 * t6 * t2; t55 = t6 * t14; var Hl0 = -(t8-t5 + t10 * t11 - t11 * t7 - t16 * t2 + t18 - t20 + t21 * t2) * t30; var Hl1 = (t5 - t8 - t32 * t4 + t32 * t9 + t18 - t2 * t35 + t27 * t2 - t20) * t30; var Hl2 = t1; var Hl3 = (-t9 * t7 + t42 + t43 * t4 - t16 * t4 + t46 - t48 + t27 * t9 - t51) * t30; var Hl4 = (-t42 + t41 * t9 - t55 * t2 + t46 - t48 + t55 * t11 + t51 - t21 * t9) * t30; var Hl5 = t14; var Hl6 = (-t10 + t41 + t43 - t35 + t24 - t21 - t26 + t27) * t30; var Hl7 = (-t7 + t10 + t16 - t43 + t27 - t28 - t21 + t25) * t30; // the following code computes R = Hl * inverse Hr t2 = Hr4-Hr7*Hr5; t4 = Hr0*Hr4; t5 = Hr0*Hr5; t7 = Hr3*Hr1; t8 = Hr2*Hr3; t10 = Hr1*Hr6; var t12 = Hr2*Hr6; t15 = 1.0 / (t4-t5*Hr7-t7+t8*Hr7+t10*Hr5-t12*Hr4); t18 = -Hr3+Hr5*Hr6; var t23 = -Hr3*Hr7+Hr4*Hr6; t28 = -Hr1+Hr2*Hr7; var t31 = Hr0-t12; t35 = Hr0*Hr7-t10; t41 = -Hr1*Hr5+Hr2*Hr4; var t44 = t5-t8; var t47 = t4-t7; t48 = t2*t15; var t49 = t28*t15; var t50 = t41*t15; var mat = model.data; mat[0] = Hl0*t48+Hl1*(t18*t15)-Hl2*(t23*t15); mat[1] = Hl0*t49+Hl1*(t31*t15)-Hl2*(t35*t15); mat[2] = -Hl0*t50-Hl1*(t44*t15)+Hl2*(t47*t15); mat[3] = Hl3*t48+Hl4*(t18*t15)-Hl5*(t23*t15); mat[4] = Hl3*t49+Hl4*(t31*t15)-Hl5*(t35*t15); mat[5] = -Hl3*t50-Hl4*(t44*t15)+Hl5*(t47*t15); mat[6] = Hl6*t48+Hl7*(t18*t15)-t23*t15; mat[7] = Hl6*t49+Hl7*(t31*t15)-t35*t15; mat[8] = -Hl6*t50-Hl7*(t44*t15)+t47*t15; }, // The current implementation was derived from *BSD system qsort(): // Copyright (c) 1992, 1993 // The Regents of the University of California. All rights reserved. qsort: function(array, low, high, cmp) { var isort_thresh = 7; var t,ta,tb,tc; var sp = 0,left=0,right=0,i=0,n=0,m=0,ptr=0,ptr2=0,d=0; var left0=0,left1=0,right0=0,right1=0,pivot=0,a=0,b=0,c=0,swap_cnt=0; var stack = qsort_stack; if( (high-low+1) <= 1 ) return; stack[0] = low; stack[1] = high; while( sp >= 0 ) { left = stack[sp<<1]; right = stack[(sp<<1)+1]; sp--; for(;;) { n = (right - left) + 1; if( n <= isort_thresh ) { //insert_sort: for( ptr = left + 1; ptr <= right; ptr++ ) { for( ptr2 = ptr; ptr2 > left && cmp(array[ptr2],array[ptr2-1]); ptr2--) { t = array[ptr2]; array[ptr2] = array[ptr2-1]; array[ptr2-1] = t; } } break; } else { swap_cnt = 0; left0 = left; right0 = right; pivot = left + (n>>1); if( n > 40 ) { d = n >> 3; a = left, b = left + d, c = left + (d<<1); ta = array[a],tb = array[b],tc = array[c]; left = cmp(ta, tb) ? (cmp(tb, tc) ? b : (cmp(ta, tc) ? c : a)) : (cmp(tc, tb) ? b : (cmp(ta, tc) ? a : c)); a = pivot - d, b = pivot, c = pivot + d; ta = array[a],tb = array[b],tc = array[c]; pivot = cmp(ta, tb) ? (cmp(tb, tc) ? b : (cmp(ta, tc) ? c : a)) : (cmp(tc, tb) ? b : (cmp(ta, tc) ? a : c)); a = right - (d<<1), b = right - d, c = right; ta = array[a],tb = array[b],tc = array[c]; right = cmp(ta, tb) ? (cmp(tb, tc) ? b : (cmp(ta, tc) ? c : a)) : (cmp(tc, tb) ? b : (cmp(ta, tc) ? a : c)); } a = left, b = pivot, c = right; ta = array[a],tb = array[b],tc = array[c]; pivot = cmp(ta, tb) ? (cmp(tb, tc) ? b : (cmp(ta, tc) ? c : a)) : (cmp(tc, tb) ? b : (cmp(ta, tc) ? a : c)); if( pivot != left0 ) { t = array[pivot]; array[pivot] = array[left0]; array[left0] = t; pivot = left0; } left = left1 = left0 + 1; right = right1 = right0; ta = array[pivot]; for(;;) { while( left <= right && !cmp(ta, array[left]) ) { if( !cmp(array[left], ta) ) { if( left > left1 ) { t = array[left1]; array[left1] = array[left]; array[left] = t; } swap_cnt = 1; left1++; } left++; } while( left <= right && !cmp(array[right], ta) ) { if( !cmp(ta, array[right]) ) { if( right < right1 ) { t = array[right1]; array[right1] = array[right]; array[right] = t; } swap_cnt = 1; right1--; } right--; } if( left > right ) break; t = array[left]; array[left] = array[right]; array[right] = t; swap_cnt = 1; left++; right--; } if( swap_cnt == 0 ) { left = left0, right = right0; //goto insert_sort; for( ptr = left + 1; ptr <= right; ptr++ ) { for( ptr2 = ptr; ptr2 > left && cmp(array[ptr2],array[ptr2-1]); ptr2--) { t = array[ptr2]; array[ptr2] = array[ptr2-1]; array[ptr2-1] = t; } } break; } n = Math.min( (left1 - left0), (left - left1) ); m = (left-n)|0; for( i = 0; i < n; ++i,++m ) { t = array[left0+i]; array[left0+i] = array[m]; array[m] = t; } n = Math.min( (right0 - right1), (right1 - right) ); m = (right0-n+1)|0; for( i = 0; i < n; ++i,++m ) { t = array[left+i]; array[left+i] = array[m]; array[m] = t; } n = (left - left1); m = (right1 - right); if( n > 1 ) { if( m > 1 ) { if( n > m ) { ++sp; stack[sp<<1] = left0; stack[(sp<<1)+1] = left0 + n - 1; left = right0 - m + 1, right = right0; } else { ++sp; stack[sp<<1] = right0 - m + 1; stack[(sp<<1)+1] = right0; left = left0, right = left0 + n - 1; } } else { left = left0, right = left0 + n - 1; } } else if( m > 1 ) left = right0 - m + 1, right = right0; else break; } } } }, median: function(array, low, high) { var w; var middle=0,ll=0,hh=0,median=(low+high)>>1; for (;;) { if (high <= low) return array[median]; if (high == (low + 1)) { if (array[low] > array[high]) { w = array[low]; array[low] = array[high]; array[high] = w; } return array[median]; } middle = ((low + high) >> 1); if (array[middle] > array[high]) { w = array[middle]; array[middle] = array[high]; array[high] = w; } if (array[low] > array[high]) { w = array[low]; array[low] = array[high]; array[high] = w; } if (array[middle] > array[low]) { w = array[middle]; array[middle] = array[low]; array[low] = w; } ll = (low + 1); w = array[middle]; array[middle] = array[ll]; array[ll] = w; hh = high; for (;;) { do ++ll; while (array[low] > array[ll]); do --hh; while (array[hh] > array[low]); if (hh < ll) break; w = array[ll]; array[ll] = array[hh]; array[hh] = w; } w = array[low]; array[low] = array[hh]; array[hh] = w; if (hh <= median) low = ll; else if (hh >= median) high = (hh - 1); } return 0; } }; })(); global.math = math; })(jsfeat);