BVB Source Codes

jsfeat Show jsfeat_bbf.js Source code

Return Download jsfeat: download jsfeat_bbf.js Source code - Download jsfeat Source code - Type:.js
  1. /**
  2.  * BBF: Brightness Binary Feature
  3.  *
  4.  * @author Eugene Zatepyakin / http://inspirit.ru/
  5.  *
  6.  * this code is a rewrite from https://github.com/liuliu/ccv implementation
  7.  * @author Liu Liu / http://liuliu.me/
  8.  *
  9.  * The original paper refers to: YEF鈭 Real-Time Object Detection, Yotam Abramson and Bruno Steux
  10.  */
  11.  
  12. (function(global) {
  13.     "use strict";
  14.     //
  15.     var bbf = (function() {
  16.  
  17.         var _group_func = function(r1, r2) {
  18.             var distance = (r1.width * 0.25 + 0.5)|0;
  19.  
  20.             return r2.x <= r1.x + distance &&
  21.                    r2.x >= r1.x - distance &&
  22.                    r2.y <= r1.y + distance &&
  23.                    r2.y >= r1.y - distance &&
  24.                    r2.width <= (r1.width * 1.5 + 0.5)|0 &&
  25.                    (r2.width * 1.5 + 0.5)|0 >= r1.width;
  26.         }
  27.  
  28.         var img_pyr = new jsfeat.pyramid_t(1);
  29.  
  30.         return {
  31.  
  32.             interval: 4,
  33.             scale: 1.1486,
  34.             next: 5,
  35.             scale_to: 1,
  36.  
  37.             // make features local copy
  38.             // to avoid array allocation with each scale
  39.             // this is strange but array works faster than Int32 version???
  40.             prepare_cascade: function(cascade) {
  41.                 var sn = cascade.stage_classifier.length;
  42.                 for (var j = 0; j < sn; j++) {
  43.                     var orig_feature = cascade.stage_classifier[j].feature;
  44.                     var f_cnt = cascade.stage_classifier[j].count;
  45.                     var feature = cascade.stage_classifier[j]._feature = new Array(f_cnt);
  46.                     for (var k = 0; k < f_cnt; k++) {
  47.                         feature[k] = {"size" : orig_feature[k].size,
  48.                                       "px" : new Array(orig_feature[k].size),
  49.                                       "pz" : new Array(orig_feature[k].size),
  50.                                       "nx" : new Array(orig_feature[k].size),
  51.                                       "nz" : new Array(orig_feature[k].size)};
  52.                     }
  53.                 }
  54.             },
  55.  
  56.             build_pyramid: function(src, min_width, min_height, interval) {
  57.                 if (typeof interval === "undefined") { interval = 4; }
  58.  
  59.                 var sw=src.cols,sh=src.rows;
  60.                 var i=0,nw=0,nh=0;
  61.                 var new_pyr=false;
  62.                 var src0=src,src1=src;
  63.                 var data_type = jsfeat.U8_t | jsfeat.C1_t;
  64.  
  65.                 this.interval = interval;
  66.                 this.scale = Math.pow(2, 1 / (this.interval + 1));
  67.                 this.next = (this.interval + 1)|0;
  68.                 this.scale_to = (Math.log(Math.min(sw / min_width, sh / min_height)) / Math.log(this.scale))|0;
  69.  
  70.                 var pyr_l = ((this.scale_to + this.next * 2) * 4) | 0;
  71.                 if(img_pyr.levels != pyr_l) {
  72.                     img_pyr.levels = pyr_l;
  73.                     img_pyr.data = new Array(pyr_l);
  74.                     new_pyr = true;
  75.                     img_pyr.data[0] = src; // first is src
  76.                 }
  77.  
  78.                 for (i = 1; i <= this.interval; ++i) {
  79.                     nw = (sw / Math.pow(this.scale, i))|0;
  80.                     nh = (sh / Math.pow(this.scale, i))|0;
  81.                     src0 = img_pyr.data[i<<2];
  82.                     if(new_pyr || nw != src0.cols || nh != src0.rows) {
  83.                         img_pyr.data[i<<2] = new jsfeat.matrix_t(nw, nh, data_type);
  84.                         src0 = img_pyr.data[i<<2];
  85.                     }
  86.                     jsfeat.imgproc.resample(src, src0, nw, nh);
  87.                 }
  88.                 for (i = this.next; i < this.scale_to + this.next * 2; ++i) {
  89.                     src1 = img_pyr.data[(i << 2) - (this.next << 2)];
  90.                     src0 = img_pyr.data[i<<2];
  91.                     nw = src1.cols >> 1;
  92.                     nh = src1.rows >> 1;
  93.                     if(new_pyr || nw != src0.cols || nh != src0.rows) {
  94.                         img_pyr.data[i<<2] = new jsfeat.matrix_t(nw, nh, data_type);
  95.                         src0 = img_pyr.data[i<<2];
  96.                     }
  97.                     jsfeat.imgproc.pyrdown(src1, src0);
  98.                 }
  99.                 for (i = this.next * 2; i < this.scale_to + this.next * 2; ++i) {
  100.                     src1 = img_pyr.data[(i << 2) - (this.next << 2)];
  101.                     nw = src1.cols >> 1;
  102.                     nh = src1.rows >> 1;
  103.                     src0 = img_pyr.data[(i<<2)+1];
  104.                     if(new_pyr || nw != src0.cols || nh != src0.rows) {
  105.                         img_pyr.data[(i<<2)+1] = new jsfeat.matrix_t(nw, nh, data_type);
  106.                         src0 = img_pyr.data[(i<<2)+1];
  107.                     }
  108.                     jsfeat.imgproc.pyrdown(src1, src0, 1, 0);
  109.                     //
  110.                     src0 = img_pyr.data[(i<<2)+2];
  111.                     if(new_pyr || nw != src0.cols || nh != src0.rows) {
  112.                         img_pyr.data[(i<<2)+2] = new jsfeat.matrix_t(nw, nh, data_type);
  113.                         src0 = img_pyr.data[(i<<2)+2];
  114.                     }
  115.                     jsfeat.imgproc.pyrdown(src1, src0, 0, 1);
  116.                     //
  117.                     src0 = img_pyr.data[(i<<2)+3];
  118.                     if(new_pyr || nw != src0.cols || nh != src0.rows) {
  119.                         img_pyr.data[(i<<2)+3] = new jsfeat.matrix_t(nw, nh, data_type);
  120.                         src0 = img_pyr.data[(i<<2)+3];
  121.                     }
  122.                     jsfeat.imgproc.pyrdown(src1, src0, 1, 1);
  123.                 }
  124.                 return img_pyr;
  125.             },
  126.  
  127.             detect: function(pyramid, cascade) {
  128.                 var interval = this.interval;
  129.                 var scale = this.scale;
  130.                 var next = this.next;
  131.                 var scale_upto = this.scale_to;
  132.                 var i=0,j=0,k=0,n=0,x=0,y=0,q=0,sn=0,f_cnt=0,q_cnt=0,p=0,pmin=0,nmax=0,f=0,i4=0,qw=0,qh=0;
  133.                 var sum=0.0, alpha, feature, orig_feature, feature_k, feature_o, flag = true, shortcut=true;
  134.                 var scale_x = 1.0, scale_y = 1.0;
  135.                 var dx = [0, 1, 0, 1];
  136.                 var dy = [0, 0, 1, 1];
  137.                 var seq = [];
  138.                 var pyr=pyramid.data, bpp = 1, bpp2 = 2, bpp4 = 4;
  139.  
  140.                 var u8 = [], u8o = [0,0,0];
  141.                 var step = [0,0,0];
  142.                 var paddings = [0,0,0];
  143.  
  144.                 for (i = 0; i < scale_upto; i++) {
  145.                     i4 = (i<<2);
  146.                     qw = pyr[i4 + (next << 3)].cols - (cascade.width >> 2);
  147.                     qh = pyr[i4 + (next << 3)].rows - (cascade.height >> 2);
  148.                     step[0] = pyr[i4].cols * bpp;
  149.                     step[1] = pyr[i4 + (next << 2)].cols * bpp;
  150.                     step[2] = pyr[i4 + (next << 3)].cols * bpp;
  151.                     paddings[0] = (pyr[i4].cols * bpp4) - (qw * bpp4);
  152.                     paddings[1] = (pyr[i4 + (next << 2)].cols * bpp2) - (qw * bpp2);
  153.                     paddings[2] = (pyr[i4 + (next << 3)].cols * bpp) - (qw * bpp);
  154.                     sn = cascade.stage_classifier.length;
  155.                     for (j = 0; j < sn; j++) {
  156.                         orig_feature = cascade.stage_classifier[j].feature;
  157.                         feature = cascade.stage_classifier[j]._feature;
  158.                         f_cnt = cascade.stage_classifier[j].count;
  159.                         for (k = 0; k < f_cnt; k++) {
  160.                             feature_k = feature[k];
  161.                             feature_o = orig_feature[k];
  162.                             q_cnt = feature_o.size|0;
  163.                             for (q = 0; q < q_cnt; q++) {
  164.                                 feature_k.px[q] = (feature_o.px[q] * bpp) + feature_o.py[q] * step[feature_o.pz[q]];
  165.                                 feature_k.pz[q] = feature_o.pz[q];
  166.                                 feature_k.nx[q] = (feature_o.nx[q] * bpp) + feature_o.ny[q] * step[feature_o.nz[q]];
  167.                                 feature_k.nz[q] = feature_o.nz[q];
  168.                             }
  169.                         }
  170.                     }
  171.                     u8[0] = pyr[i4].data; u8[1] = pyr[i4 + (next<<2)].data;
  172.                     for (q = 0; q < 4; q++) {
  173.                         u8[2] = pyr[i4 + (next<<3) + q].data;
  174.                         u8o[0] = (dx[q]*bpp2) + dy[q] * (pyr[i4].cols*bpp2);
  175.                         u8o[1] = (dx[q]*bpp) + dy[q] * (pyr[i4 + (next<<2)].cols*bpp);
  176.                         u8o[2] = 0;
  177.                         for (y = 0; y < qh; y++) {
  178.                             for (x = 0; x < qw; x++) {
  179.                                 sum = 0;
  180.                                 flag = true;
  181.                                 sn = cascade.stage_classifier.length;
  182.                                 for (j = 0; j < sn; j++) {
  183.                                     sum = 0;
  184.                                     alpha = cascade.stage_classifier[j].alpha;
  185.                                     feature = cascade.stage_classifier[j]._feature;
  186.                                     f_cnt = cascade.stage_classifier[j].count;
  187.                                     for (k = 0; k < f_cnt; k++) {
  188.                                         feature_k = feature[k];
  189.                                         pmin = u8[feature_k.pz[0]][u8o[feature_k.pz[0]] + feature_k.px[0]];
  190.                                         nmax = u8[feature_k.nz[0]][u8o[feature_k.nz[0]] + feature_k.nx[0]];
  191.                                         if (pmin <= nmax) {
  192.                                             sum += alpha[k << 1];
  193.                                         } else {
  194.                                             shortcut = true;
  195.                                             q_cnt = feature_k.size;
  196.                                             for (f = 1; f < q_cnt; f++) {
  197.                                                 if (feature_k.pz[f] >= 0) {
  198.                                                     p = u8[feature_k.pz[f]][u8o[feature_k.pz[f]] + feature_k.px[f]];
  199.                                                     if (p < pmin) {
  200.                                                         if (p <= nmax) {
  201.                                                             shortcut = false;
  202.                                                             break;
  203.                                                         }
  204.                                                         pmin = p;
  205.                                                     }
  206.                                                 }
  207.                                                 if (feature_k.nz[f] >= 0) {
  208.                                                     n = u8[feature_k.nz[f]][u8o[feature_k.nz[f]] + feature_k.nx[f]];
  209.                                                     if (n > nmax) {
  210.                                                         if (pmin <= n) {
  211.                                                             shortcut = false;
  212.                                                             break;
  213.                                                         }
  214.                                                         nmax = n;
  215.                                                     }
  216.                                                 }
  217.                                             }
  218.                                             sum += (shortcut) ? alpha[(k << 1) + 1] : alpha[k << 1];
  219.                                         }
  220.                                     }
  221.                                     if (sum < cascade.stage_classifier[j].threshold) {
  222.                                         flag = false;
  223.                                         break;
  224.                                     }
  225.                                 }
  226.                                 if (flag) {
  227.                                     seq.push({"x" : (x * 4 + dx[q] * 2) * scale_x,
  228.                                               "y" : (y * 4 + dy[q] * 2) * scale_y,
  229.                                               "width" : cascade.width * scale_x,
  230.                                               "height" : cascade.height * scale_y,
  231.                                               "neighbor" : 1,
  232.                                               "confidence" : sum});
  233.                                     ++x;
  234.                                     u8o[0] += bpp4;
  235.                                     u8o[1] += bpp2;
  236.                                     u8o[2] += bpp;
  237.                                 }
  238.                                 u8o[0] += bpp4;
  239.                                 u8o[1] += bpp2;
  240.                                 u8o[2] += bpp;
  241.                             }
  242.                             u8o[0] += paddings[0];
  243.                             u8o[1] += paddings[1];
  244.                             u8o[2] += paddings[2];
  245.                         }
  246.                     }
  247.                     scale_x *= scale;
  248.                     scale_y *= scale;
  249.                 }
  250.  
  251.                 return seq;
  252.             },
  253.  
  254.             // OpenCV method to group detected rectangles
  255.             group_rectangles: function(rects, min_neighbors) {
  256.                 if (typeof min_neighbors === "undefined") { min_neighbors = 1; }
  257.                 var i, j, n = rects.length;
  258.                 var node = [];
  259.                 for (i = 0; i < n; ++i) {
  260.                     node[i] = {"parent" : -1,
  261.                                "element" : rects[i],
  262.                                "rank" : 0};
  263.                 }
  264.                 for (i = 0; i < n; ++i) {
  265.                     if (!node[i].element)
  266.                         continue;
  267.                     var root = i;
  268.                     while (node[root].parent != -1)
  269.                         root = node[root].parent;
  270.                     for (j = 0; j < n; ++j) {
  271.                         if( i != j && node[j].element && _group_func(node[i].element, node[j].element)) {
  272.                             var root2 = j;
  273.  
  274.                             while (node[root2].parent != -1)
  275.                                 root2 = node[root2].parent;
  276.  
  277.                             if(root2 != root) {
  278.                                 if(node[root].rank > node[root2].rank)
  279.                                     node[root2].parent = root;
  280.                                 else {
  281.                                     node[root].parent = root2;
  282.                                     if (node[root].rank == node[root2].rank)
  283.                                     node[root2].rank++;
  284.                                     root = root2;
  285.                                 }
  286.  
  287.                                 /* compress path from node2 to the root: */
  288.                                 var temp, node2 = j;
  289.                                 while (node[node2].parent != -1) {
  290.                                     temp = node2;
  291.                                     node2 = node[node2].parent;
  292.                                     node[temp].parent = root;
  293.                                 }
  294.  
  295.                                 /* compress path from node to the root: */
  296.                                 node2 = i;
  297.                                 while (node[node2].parent != -1) {
  298.                                     temp = node2;
  299.                                     node2 = node[node2].parent;
  300.                                     node[temp].parent = root;
  301.                                 }
  302.                             }
  303.                         }
  304.                     }
  305.                 }
  306.                 var idx_seq = [];
  307.                 var class_idx = 0;
  308.                 for(i = 0; i < n; i++) {
  309.                     j = -1;
  310.                     var node1 = i;
  311.                     if(node[node1].element) {
  312.                         while (node[node1].parent != -1)
  313.                             node1 = node[node1].parent;
  314.                         if(node[node1].rank >= 0)
  315.                             node[node1].rank = ~class_idx++;
  316.                         j = ~node[node1].rank;
  317.                     }
  318.                     idx_seq[i] = j;
  319.                 }
  320.                
  321.                 var comps = [];
  322.                 for (i = 0; i < class_idx+1; ++i) {
  323.                     comps[i] = {"neighbors" : 0,
  324.                                 "x" : 0,
  325.                                 "y" : 0,
  326.                                 "width" : 0,
  327.                                 "height" : 0,
  328.                                 "confidence" : 0};
  329.                 }
  330.  
  331.                 // count number of neighbors
  332.                 for(i = 0; i < n; ++i) {
  333.                     var r1 = rects[i];
  334.                     var idx = idx_seq[i];
  335.  
  336.                     if (comps[idx].neighbors == 0)
  337.                         comps[idx].confidence = r1.confidence;
  338.  
  339.                     ++comps[idx].neighbors;
  340.  
  341.                     comps[idx].x += r1.x;
  342.                     comps[idx].y += r1.y;
  343.                     comps[idx].width += r1.width;
  344.                     comps[idx].height += r1.height;
  345.                     comps[idx].confidence = Math.max(comps[idx].confidence, r1.confidence);
  346.                 }
  347.  
  348.                 var seq2 = [];
  349.                 // calculate average bounding box
  350.                 for(i = 0; i < class_idx; ++i) {
  351.                     n = comps[i].neighbors;
  352.                     if (n >= min_neighbors)
  353.                         seq2.push({"x" : (comps[i].x * 2 + n) / (2 * n),
  354.                                    "y" : (comps[i].y * 2 + n) / (2 * n),
  355.                                    "width" : (comps[i].width * 2 + n) / (2 * n),
  356.                                    "height" : (comps[i].height * 2 + n) / (2 * n),
  357.                                    "neighbors" : comps[i].neighbors,
  358.                                    "confidence" : comps[i].confidence});
  359.                 }
  360.  
  361.                 var result_seq = [];
  362.                 n = seq2.length;
  363.                 // filter out small face rectangles inside large face rectangles
  364.                 for(i = 0; i < n; ++i) {
  365.                     var r1 = seq2[i];
  366.                     var flag = true;
  367.                     for(j = 0; j < n; ++j) {
  368.                         var r2 = seq2[j];
  369.                         var distance = (r2.width * 0.25 + 0.5)|0;
  370.  
  371.                         if(i != j &&
  372.                            r1.x >= r2.x - distance &&
  373.                            r1.y >= r2.y - distance &&
  374.                            r1.x + r1.width <= r2.x + r2.width + distance &&
  375.                            r1.y + r1.height <= r2.y + r2.height + distance &&
  376.                            (r2.neighbors > Math.max(3, r1.neighbors) || r1.neighbors < 3)) {
  377.                             flag = false;
  378.                             break;
  379.                         }
  380.                     }
  381.  
  382.                     if(flag)
  383.                         result_seq.push(r1);
  384.                 }
  385.                 return result_seq;
  386.             }
  387.  
  388.         };
  389.  
  390.     })();
  391.  
  392.     global.bbf = bbf;
  393.  
  394. })(jsfeat);
  395.  
downloadjsfeat_bbf.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