Advertisement
Guest User

Untitled

a guest
Dec 15th, 2015
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function() {
  2.   /**
  3.    * Face Alignment via Regressing Local Binary Features (LBF)
  4.    * This approach has two components: a set of local binary features and
  5.    * a locality principle for learning those features.
  6.    * The locality principle is used to guide the learning of a set of highly
  7.    * discriminative local binary features for each landmark independently.
  8.    * The obtained local binary features are used to learn a linear regression
  9.    * that later will be used to guide the landmarks in the alignment phase.
  10.    *
  11.    * @authors: VoxarLabs Team (http://cin.ufpe.br/~voxarlabs)
  12.    *           Lucas Figueiredo <lsf@cin.ufpe.br>, Thiago Menezes <tmc2@cin.ufpe.br>,
  13.    *           Thiago Domingues <tald@cin.ufpe.br>, Rafael Roberto <rar3@cin.ufpe.br>,
  14.    *           Thulio Araujo <tlsa@cin.ufpe.br>, Joao Victor <jvfl@cin.ufpe.br>,
  15.    *           Tomer Simis <tls@cin.ufpe.br>)
  16.    */
  17.  
  18.   /**
  19.    * Holds the maximum number of stages that will be used in the alignment algorithm.
  20.    * Each stage contains a different set of random forests and retrieves the binary
  21.    * code from a more "specialized" (i.e. smaller) region around the landmarks.
  22.    * @type {number}
  23.    * @static
  24.    */
  25.   tracking.LBF.maxNumStages = 4;
  26.  
  27.   /**
  28.    * Holds the regressor that will be responsible for extracting the local features from
  29.    * the image and guide the landmarks using the training data.
  30.    * @type {object}
  31.    * @protected
  32.    * @static
  33.    */
  34.   tracking.LBF.regressor_ = null;
  35.  
  36.   /**
  37.    * Generates a set of landmarks for a set of faces
  38.    * @param {pixels} pixels The pixels in a linear [r,g,b,a,...] array.
  39.    * @param {number} width The image width.
  40.    * @param {number} height The image height.
  41.    * @param {array} faces The list of faces detected in the image
  42.    * @return {array} The aligned landmarks, each set of landmarks corresponding
  43.    *     to a specific face.
  44.    * @static
  45.    */
  46.   tracking.LBF.align = function(pixels, width, height, faces){
  47.  
  48.     if(tracking.LBF.regressor_ == null){
  49.       tracking.LBF.regressor_ = new tracking.LBF.Regressor(
  50.         tracking.LBF.maxNumStages
  51.       );
  52.     }
  53.  
  54.     pixels = tracking.Image.grayscale(pixels, width, height, false);
  55.  
  56.     pixels = tracking.Image.equalizeHist(pixels, width, height);
  57.  
  58.     var shapes = new Array(faces.length);
  59.  
  60.     for(var i in faces){
  61.  
  62.       faces[i].height = faces[i].width;
  63.  
  64.       var boundingBox = {};
  65.       boundingBox.startX = faces[i].x;
  66.       boundingBox.startY = faces[i].y;
  67.       boundingBox.width = faces[i].width;
  68.       boundingBox.height = faces[i].height;
  69.  
  70.       shapes[i] = tracking.LBF.regressor_.predict(pixels, width, height, boundingBox);
  71.     }
  72.  
  73.     return shapes;
  74.   }
  75.  
  76.   /**
  77.    * Unprojects the landmarks shape from the bounding box.
  78.    * @param {matrix} shape The landmarks shape.
  79.    * @param {matrix} boudingBox The bounding box.
  80.    * @return {matrix} The landmarks shape projected into the bounding box.
  81.    * @static
  82.    * @protected
  83.    */
  84.   tracking.LBF.unprojectShapeToBoundingBox_ = function(shape, boundingBox){
  85.     var temp = new Array(shape.length);
  86.     for(var i=0; i < shape.length; i++){
  87.       temp[i] = [
  88.         (shape[i][0] - boundingBox.startX) / boundingBox.width,
  89.         (shape[i][1] - boundingBox.startY) / boundingBox.height
  90.       ];
  91.     }
  92.     return temp;
  93.   }
  94.  
  95.   /**
  96.    * Projects the landmarks shape into the bounding box. The landmarks shape has
  97.    * normalized coordinates, so it is necessary to map these coordinates into
  98.    * the bounding box coordinates.
  99.    * @param {matrix} shape The landmarks shape.
  100.    * @param {matrix} boudingBox The bounding box.
  101.    * @return {matrix} The landmarks shape.
  102.    * @static
  103.    * @protected
  104.    */
  105.   tracking.LBF.projectShapeToBoundingBox_ = function(shape, boundingBox){
  106.     var temp = new Array(shape.length);
  107.     for(var i=0; i < shape.length; i++){
  108.       temp[i] = [
  109.         shape[i][0] * boundingBox.width + boundingBox.startX,
  110.         shape[i][1] * boundingBox.height + boundingBox.startY
  111.       ];
  112.     }
  113.     return temp;
  114.   }
  115.  
  116.   /**
  117.    * Calculates the rotation and scale necessary to transform shape1 into shape2.
  118.    * @param {matrix} shape1 The shape to be transformed.
  119.    * @param {matrix} shape2 The shape to be transformed in.
  120.    * @return {[matrix, scalar]} The rotation matrix and scale that applied to shape1
  121.    *     results in shape2.
  122.    * @static
  123.    * @protected
  124.    */
  125.   tracking.LBF.similarityTransform_ = function(shape1, shape2){
  126.  
  127.     var center1 = [0,0];
  128.     var center2 = [0,0];
  129.     for (var i = 0; i < shape1.length; i++) {
  130.       center1[0] += shape1[i][0];
  131.       center1[1] += shape1[i][1];
  132.       center2[0] += shape2[i][0];
  133.       center2[1] += shape2[i][1];
  134.     }
  135.     center1[0] /= shape1.length;
  136.     center1[1] /= shape1.length;
  137.     center2[0] /= shape2.length;
  138.     center2[1] /= shape2.length;
  139.  
  140.     var temp1 = tracking.Matrix.clone(shape1);
  141.     var temp2 = tracking.Matrix.clone(shape2);
  142.     for(var i=0; i < shape1.length; i++){
  143.       temp1[i][0] -= center1[0];
  144.       temp1[i][1] -= center1[1];
  145.       temp2[i][0] -= center2[0];
  146.       temp2[i][1] -= center2[1];
  147.     }
  148.  
  149.     var covariance1, covariance2;
  150.     var mean1, mean2;
  151.  
  152.     var t = tracking.Matrix.calcCovarMatrix(temp1);
  153.     covariance1 = t[0];
  154.     mean1 = t[1];
  155.  
  156.     t = tracking.Matrix.calcCovarMatrix(temp2);
  157.     covariance2 = t[0];
  158.     mean2 = t[1];
  159.  
  160.     var s1 = Math.sqrt(tracking.Matrix.norm(covariance1));
  161.     var s2 = Math.sqrt(tracking.Matrix.norm(covariance2));
  162.  
  163.     var scale = s1/s2;
  164.     temp1 = tracking.Matrix.mulScalar(1.0/s1, temp1);
  165.     temp2 = tracking.Matrix.mulScalar(1.0/s2, temp2);
  166.  
  167.     var num = 0, den = 0;
  168.     for (var i = 0; i < shape1.length; i++) {
  169.       num = num + temp1[i][1] * temp2[i][0] - temp1[i][0] * temp2[i][1];
  170.       den = den + temp1[i][0] * temp2[i][0] + temp1[i][1] * temp2[i][1];
  171.     }
  172.  
  173.     var norm = Math.sqrt(num*num + den*den);
  174.     var sin_theta = num/norm;
  175.     var cos_theta = den/norm;
  176.     var rotation = [
  177.       [cos_theta, -sin_theta],
  178.       [sin_theta, cos_theta]
  179.     ];
  180.  
  181.     return [rotation, scale];
  182.   }
  183.  
  184.   /**
  185.    * LBF Random Forest data structure.
  186.    * @static
  187.    * @constructor
  188.    */
  189.   tracking.LBF.RandomForest = function(forestIndex){
  190.     this.maxNumTrees = tracking.LBF.RegressorData[forestIndex].max_numtrees;
  191.     this.landmarkNum = tracking.LBF.RegressorData[forestIndex].num_landmark;
  192.     this.maxDepth = tracking.LBF.RegressorData[forestIndex].max_depth;
  193.     this.stages = tracking.LBF.RegressorData[forestIndex].stages;
  194.  
  195.     this.rfs = new Array(this.landmarkNum);
  196.     for(var i=0; i < this.landmarkNum; i++){
  197.       this.rfs[i] = new Array(this.maxNumTrees);
  198.       for(var j=0; j < this.maxNumTrees; j++){
  199.         this.rfs[i][j] = new tracking.LBF.Tree(forestIndex, i, j);
  200.       }
  201.     }
  202.   }
  203.  
  204.   /**
  205.    * LBF Tree data structure.
  206.    * @static
  207.    * @constructor
  208.    */
  209.   tracking.LBF.Tree = function(forestIndex, landmarkIndex, treeIndex){
  210.     var data = tracking.LBF.RegressorData[forestIndex].landmarks[landmarkIndex][treeIndex];
  211.     this.maxDepth = data.max_depth;
  212.     this.maxNumNodes = data.max_numnodes;
  213.     this.nodes = data.nodes;
  214.     this.landmarkID = data.landmark_id;
  215.     this.numLeafnodes = data.num_leafnodes;
  216.     this.numNodes = data.num_nodes;
  217.     this.maxNumFeats = data.max_numfeats;
  218.     this.maxRadioRadius = data.max_radio_radius;
  219.     this.leafnodes = data.id_leafnodes;
  220.   }
  221.  
  222. }());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement