block by dribnet 547506869d1051ffb76b380c141932a1

2020 MDDN342 Assignment 3: Face Mappings

Full Screen

2020 MDDN342 Assignment 3: Face Mappings

Animating eyebrows and mouth based on relationship between face points.

index.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js"></script>
    <script src="https://d3js.org/d3-random.v1.min.js"></script>
    <script src="z_clmtrackr.js"></script>
    <script src="z_model_pca_20_svm.js"></script>
    <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
    <script language="javascript" type="text/javascript" src="z_focused_random.js"></script>
    <script language="javascript" type="text/javascript" src="z_face_system.js"></script>
    <script language="javascript" type="text/javascript" src="z_kdTree.js"></script>
    <script language="javascript" type="text/javascript" src="z_face-api.js"></script>
    <script language="javascript" type="text/javascript" src="z_training_images.js"></script>
    <script language="javascript" type="text/javascript" src="z_testing_images.js"></script>
    <script language="javascript" type="text/javascript" src="face.js"></script>
    <script language="javascript" type="text/javascript" src="system_runner.js"></script>

    <style>
        body   { padding: 0; margin: 0; }
        .inner { position: absolute; }
        #controls {
            font: 300 12px "Helvetica Neue";
            padding: 5;
            margin: 5;
            background: #f0f0f0;
            opacity: 0.0;
            -webkit-transition: opacity 0.2s ease;
            -moz-transition: opacity 0.2s ease;
            -o-transition: opacity 0.2s ease;
            -ms-transition: opacity 0.2s ease;
        }
        #controls:hover { opacity: 0.9; }
    </style>

</head>
<body style="background-color:white">
    <div class="outer">
        <div class="inner" id="controls" height="500">
            <table>
                <tr>
                    <td>setting 1</td>
                    <td id="slider1Container"></td>
                </tr>
                <tr>
                    <td>setting 2</td>
                    <td id="slider2Container"></td>
                </tr>
                <tr>
                    <td>setting 3</td>
                    <td id="slider3Container"></td>
                </tr>
                <tr>
                    <td>setting 4</td>
                    <td id="slider4Container"></td>
                </tr>
                <tr>
                    <td>setting 5</td>
                    <td id="slider5Container"></td>
                </tr>
                <tr>
                    <td>setting 6</td>
                    <td id="slider6Container"></td>
                </tr>
                <tr>
                    <td>setting 7</td>
                    <td id="slider7Container"></td>
                </tr>
                <tr>
                    <td>setting 8</td>
                    <td id="slider8Container"></td>
                </tr>
                <!-- YOU CAN ADD MORE SLIDERS HERE, LIKE THIS
                <tr>
                    <td>setting 9</td>
                    <td id="slider9Container"></td>
                </tr>
                <tr>
                    <td>setting 10</td>
                    <td id="slider10Container"></td>
                </tr>
                <tr>
                    <td>setting 11</td>
                    <td id="slider11Container"></td>
                </tr>
                <tr>
                    <td>setting 12</td>
                    <td id="slider12Container"></td>
                </tr>
                ... AND KEEP GOING
                 -->
                <tr>
                </tr>
                <tr>
                    <td>show target</td>
                    <td id="sliderTintContainer"></td>
                </tr>
                <tr>
                    <td>Draw function</td>
                    <td id="selector1Container"></td>
                </tr>
                <tr>
                    <td>Face Draw</td>
                    <td id="checkbox1Container"></td>
                </tr>
                <tr>
                    <td>Face Targets</td>
                    <td id="checkbox2Container"></td>
                </tr>
                <tr>
                    <td>Face Points</td>
                    <td id="checkbox3Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="button1Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="button2Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="button3Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="button4Container"></td>
                </tr>
            </table>
        </div>
        <div>
            <div id="canvasContainer"></div>
<a href="face.js">face code</a><br>
<a href="sketch.html">sketches</a>
        </div>
    </div>
    <pre>
        <p id="output">
        </p>
    </pre>
</body>

face.js

/*
 * FaceMap class - holds all informaiton about one mapped
 * face and is able to draw itself.
 */  

// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;

// this can be used to set the number of sliders to show
var NUM_SLIDERS = 8;

// other variables can be in here too
// these control the colors used
const bg_color = [225, 206, 187];
const fg_color = [151, 102, 52];
const stroke_color = [95, 52, 8];

function Face() {

  // these are state variables for a face
  // (your variables may be different)
  this.bread = 3;    // 1-5
  this.jam = 5;      // 0-10

  /*
   * Draw a face with position lists that include:
   *    chin, right_eye, left_eye, right_eyebrow, left_eyebrow
   *    bottom_lip, top_lip, nose_tip, nose_bridge, 
   */  
  this.draw = function(positions) {

    // let bread = int(map(s1, 0, 100, 1, 5));
    // let mouth = map(s2, 0, 100, 0, 10);
    // let blush = map(s3, 0, 100, 0, 10);
    // let jam = map(s4, 0, 100, 0, 10);
    // let jam_col = map(s5, 0, 100, 0, 10);
    // let jam_size = int(map(s6, 0, 100, 0, 10));
    // let eyebrows_rotate = map(s7, 0, 100, 0, 20);
    // let glasses = int(map(s8, 0, 100, 0, 10));
    // let pupil = int(map(s9, 0, 100, 1, 10));

      let bread = this.bread;
      let mouth = 5;
      let blush = 5;
      let jam = this.jam;
      let jam_col = 5;
      let jam_size = 5;
      let eyebrows_rotate=10;
      let glasses = 5;
      let pupil = 5;

      // Colour Sets
      let bread1 = '#fffaf5';
      let bread2 = '#f5f2ea'; 
      let bread3 = '#dbb58c';
      let bread4 = '#c48d52';
      let bread5 = '#36210d';

      let breadColour;

      let left_eye = average_point(positions.left_eye);
      let right_eye = average_point(positions.right_eye);
      let left_eyebrow = average_point(positions.left_eyebrow);
      let right_eyebrow = average_point(positions.right_eyebrow);

      let left_d = dist(left_eye[0], left_eye[1], left_eyebrow[0], left_eyebrow[1]);
      let right_d = dist(right_eye[0], right_eye[1], right_eyebrow[0], right_eyebrow[1]);
      let left_eb_move = map(left_d, 0.4, 0.7, 0, 2, true);
      let right_eb_move = map(right_d, 0.4, 0.7, 0, 2, true);
      // print(left_d); 

      left_eye[0] *= 3;
      left_eye[1] *= 3;
      right_eye[0] *= 3;
      right_eye[1] *= 3;

      push();
      scale(0.33);

      // Bread (Brown)
      fill(221,168,128);
      strokeWeight(0.3);
      stroke(0);
      beginShape();
      vertex(-6.45, -5);
      quadraticVertex(-4, -8, -0.5, -6);
      quadraticVertex(3.5, -9, 6.5, -5.6);
      quadraticVertex(7.8, -3.8, 6.5, -1.5);
      quadraticVertex(6.8, 3, 6.3, 5.5);
      quadraticVertex(6, 6, 5.1, 6.5);
      endShape();

    // Bread Colour
      if(bread == 1){
        breadColour = bread1; //***ALMOST WHITE***//

      }else if (bread == 2){
        breadColour = bread2; //***IVORY***//

      }else if (bread == 3){
        breadColour = bread3; //***WELL DONE***//

      }else if (bread == 4){
        breadColour = bread4; //***OVERCOOKED***//

      }else{
        breadColour = bread5; //***BURNT***//
      }

      fill(breadColour);
      strokeWeight(0.3);
      stroke(0);
      rect(-6, -4.5, 11, 11);
      push();
      angleMode(RADIANS);
      arc(-3.9, -3, 6.8, 6, -4, -0.4);
      arc(2.4, -3.2, 6.8, 6, -2.8, 0.65);
      pop();

      // Jam (Colour, Spread)
      let amount = map(jam_col, 0, 10, 0, 1);
      let colourPink = color('#ed3267');
      let colourPurple = color('#edd532');
      let jamColour = lerpColor(colourPink, colourPurple, amount);

      let jamSpread = map(jam, 0, 100, 0, 100);

      let jamS = map(jam_size, 0, 100, 1.3, 15);

      strokeWeight(jamS);
      stroke(jamColour);

      if (jamSpread == 0){
      }

      if (jamSpread >= 2){
        line(-3.5, -2, 2.5, -3);
      }
      if (jamSpread >=4){
        line(2.5, -3, -3, 1);
      }
      if (jamSpread >=6){
      line(-3, 1, 2, 0);
      }
      if (jamSpread >=8){
      line(2, 0, -3.5, 4);
      }
      if (jamSpread >=10){
      line(-3.5, 4, 2.5, 3);
      }

      // Mouth
      strokeWeight(0.4);
      stroke(0);
      line(-1.55, -1, -0.05, -1); 

      let top_lip_point = positions.top_lip[9];
      let bottom_lip_point = positions.bottom_lip[9];
      // fill(255, 0, 0);
      let d = dist(top_lip_point[0], top_lip_point[1], bottom_lip_point[0], bottom_lip_point[1])
      // print(d);

      // Mouth Open
      if(d < 0.1) {
        d = 0;
      }
      mouth = map(d, 0, 0.5, 0, 10);
      let mouth_size = map(mouth, 0, 10, 0, 3.5);
      strokeWeight(0.3);
      fill('#fffcf7');
      rect(-1.6, -1, 1.6, mouth_size, 0.08);

      /*
      push();
      scale(5);
      noStroke();
      textSize(0.2);
      for (let i=0; i<positions.bottom_lip.length; i++) {
        let p = positions.bottom_lip[i]
        fill(255, 0, 0);
        ellipse(p[0], p[1], 0.2);
        fill(0);
        text(i, p[0], p[1]);
      }
      pop();

      push();
      scale(5);
      noStroke();
      textSize(0.2);
      for (let i=0; i<positions.top_lip.length; i++) {
        let p = positions.top_lip[i]
        fill(0, 0, 255);
        ellipse(p[0], p[1], 0.2);
        fill(0);
        text(i, p[0], p[1]);
      }
      pop();
      */

      // Blush
      noStroke();
      if (blush > 3 && blush < 6){ //***PINK BLUSH***//
      fill('#ff87b1');
      ellipse(-2.6, -1.1, 1.5, 0.8);
      ellipse(1.1, -1.1, 1.5, 0.8);
      }
      else if (blush > 5 && blush <= 8){ //***RED BLUSH***//
      stroke('#bf304d');
      strokeWeight(0.2);
      line(-3.5, -0.9, -3.2, -1.2); //***LEFT***//
      line(-2.9, -0.9, -2.6, -1.2);
      line(-2.3, -0.9, -2, -1.2);

      line(0.5, -0.9, 0.8, -1.2); //***RIGHT***//
      line(1.1, -0.9, 1.4, -1.2);
      line(1.7, -0.9, 2, -1.2);
      }
      else if (blush >7 && blush <= 10){ //***TEARS***//
      noStroke();
      fill('#49a3e6');
      triangle(-3.3, -1.19, -2.9, -0.85, -2.75, -1.55);
      ellipse(-3.2, -0.9, 0.6, 0.6);
      triangle(1.81, -1.24, 1.36, -0.87, 1.2, -1.7);
      ellipse(1.65, -1, 0.6, 0.6);
      }

      // Eyes
      noStroke();
      fill(0);
      // ellipse(-2.2, -2, 1.1, 1.1);
      // ellipse(0.5, -2, 1.1, 1.1);
      ellipse(left_eye[0], left_eye[1], 1.1, 1.1);
      ellipse(right_eye[0], right_eye[1], 1.1, 1.1);

      // Pupil
      if (pupil > 3 && pupil < 6) {
      fill('black');
        ellipse(left_eye[0]-0.1, left_eye[1]-0.1, 0.3, 0.3); //***LEFT TOP***//
        ellipse(left_eye[0]+0.15, left_eye[1]+0.1, 0.2, 0.2); //***LEFT BOTTOM***//
        ellipse(left_eye[0]-0.1, left_eye[1]-0.1, 0.3, 0.3); //***RIGHT TOP***//
        ellipse(left_eye[0]+0.15, left_eye[1]+0.1, 0.2, 0.2); //***RIGHT BOTTOM***//
        // ellipse(-2.3, -2.1, 0.3, 0.3); //***LEFT TOP***//
        // ellipse(-2.05, -1.9, 0.2, 0.2); //***LEFT BOTTOM***//
        // ellipse(0.4, -2.1, 0.3, 0.3); //***RIGHT TOP***//
        // ellipse(0.65, -1.9, 0.2, 0.2); //***RIGHT BOTTOM***//
      }
      else if (pupil > 5 && pupil <= 10) {
        // fill('white');
        // ellipse(-2.3, -2.1, 0.3, 0.3); //***LEFT TOP***//
        // ellipse(-2.05, -1.9, 0.2, 0.2); //***LEFT BOTTOM***//
        // ellipse(0.4, -2.1, 0.3, 0.3); //***RIGHT TOP***//
        // ellipse(0.65, -1.9, 0.2, 0.2); //***RIGHT BOTTOM***//
      }

      // Eyebrows
      strokeWeight(0.4);
      stroke(0);

      push();
      angleMode(DEGREES);
      translate(left_eye[0]-0.1, left_eye[1]-1);
      translate(0, -left_eb_move);
      rotate(eyebrows_rotate);
      line(-0.3, 0, 0.5, 0);
      pop();

      push();
      angleMode(DEGREES);
      translate(right_eye[0]-0.2, right_eye[1]-1);
      translate(0, -right_eb_move);
      rotate(-eyebrows_rotate);
      line(-0.3, 0, 0.5, 0);
      pop();

      // Glasses
       if (glasses > 5 && glasses < 8){
      stroke(0);
      strokeWeight(0.35);
      noFill();
      ellipse(-2.3, -2.4, 2.6, 2.6);
      ellipse(0.6, -2.4, 2.6, 2.6);
      }

      // Sunglasses
      else if (glasses > 7 && glasses <= 10){
        stroke(0);
        strokeWeight(0.3);
        fill('white');
        ellipse(-2.6, -2.4, 3, 2.6);
        ellipse(1, -2.4, 3, 2.6);
        noStroke();
        fill('black');
        ellipse(-2.6, -2.37, 2.4, 2);
        ellipse(1, -2.37, 2.4, 2);
        stroke(0);
        strokeWeight(0.3);
        line(-1.1, -2.5, -0.65, -2.5);
    }
    pop();
  }

  /* set internal properties based on list numbers 0-100 */
  this.setProperties = function(settings) {
    this.bread = int(map(settings[0], 0, 100, 1, 5));
    this.jam = int(map(settings[1], 0, 100, 0, 10));
  }

  /* get internal properties as list of numbers 0-100 */
  this.getProperties = function() {
    let settings = new Array(2);
    settings[0] = map(this.bread, 1, 5, 0, 100);
    settings[1] = map(this.jam, 0, 10, 0, 100);
    return settings;
  }
}

// given an array of [x,y] points, return the average
function average_point(list) {
  var sum_x = 0;
  var sum_y = 0;
  var num_points = 0;
  for(var i=0; i<list.length; i++) {
    sum_x += list[i][0];
    sum_y += list[i][1];
    num_points += 1; 
  }
  return [sum_x / num_points, sum_y / num_points];
}

sample_images.json

[
	"five_faces.jpg",
	"williams.jpg",
	"oscar_selfie.jpg"
]

sketch.html

<head>
    <style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="same_pose.jpg" width="960" height="500"/><br>
Same Pose
<hr>
<img src="same_subject.jpg" width="960" height="500"/><br>
Same Subject
<p>
<a href="index.html">program</a>
</body>

training_values.json

{
  "000001": [
    0,
    100
  ],
  "000002": [
    0,
    100
  ],
  "000005": [
    0,
    100
  ],
  "000006": [
    50,
    100
  ],
  "000007": [
    25,
    0
  ],
  "000009": [
    25,
    100
  ],
  "000010": [
    25,
    100
  ],
  "000013": [
    25,
    0
  ],
  "000014": [
    75,
    100
  ],
  "000015": [
    25,
    0
  ],
  "000016": [
    25,
    0
  ],
  "000018": [
    25,
    100
  ],
  "000020": [
    25,
    0
  ],
  "000023": [
    25,
    0
  ],
  "000025": [
    25,
    0
  ],
  "000028": [
    25,
    100
  ],
  "000029": [
    25,
    100
  ],
  "000030": [
    25,
    0
  ],
  "000031": [
    0,
    100
  ],
  "000032": [
    0,
    0
  ],
  "000035": [
    0,
    100
  ],
  "000037": [
    50,
    0
  ],
  "000038": [
    0,
    0
  ],
  "000040": [
    0,
    90
  ],
  "000041": [
    0,
    0
  ],
  "000042": [
    0,
    100
  ],
  "000043": [
    0,
    100
  ],
  "000044": [
    50,
    100
  ],
  "000045": [
    0,
    100
  ],
  "000047": [
    50,
    100
  ],
  "000048": [
    0,
    0
  ],
  "000050": [
    0,
    0
  ],
  "000051": [
    0,
    0
  ],
  "000052": [
    0,
    0
  ],
  "000054": [
    0,
    100
  ],
  "000055": [
    0,
    0
  ],
  "000056": [
    0,
    100
  ],
  "000058": [
    0,
    100
  ],
  "000060": [
    100,
    0
  ],
  "000064": [
    0,
    0
  ],
  "000065": [
    50,
    0
  ],
  "000068": [
    0,
    0
  ],
  "000069": [
    0,
    0
  ],
  "000071": [
    0,
    100
  ],
  "000073": [
    0,
    100
  ],
  "000076": [
    0,
    0
  ],
  "000077": [
    0,
    100
  ],
  "000078": [
    50,
    100
  ],
  "000079": [
    0,
    0
  ],
  "000080": [
    0,
    0
  ],
  "000081": [
    0,
    0
  ],
  "000083": [
    0,
    100
  ],
  "000085": [
    0,
    100
  ],
  "000086": [
    25,
    100
  ],
  "000088": [
    0,
    100
  ],
  "000091": [
    0,
    0
  ],
  "000092": [
    0,
    100
  ],
  "000096": [
    0,
    100
  ],
  "000097": [
    0,
    100
  ],
  "000099": [
    25,
    100
  ],
  "000100": [
    0,
    100
  ],
  "000103": [
    25,
    100
  ],
  "000104": [
    25,
    0
  ],
  "000106": [
    25,
    0
  ],
  "000108": [
    25,
    100
  ],
  "000109": [
    0,
    0
  ],
  "000110": [
    25,
    100
  ],
  "000111": [
    50,
    100
  ],
  "000114": [
    0,
    0
  ],
  "000115": [
    25,
    0
  ],
  "000116": [
    0,
    0
  ],
  "000117": [
    100,
    100
  ],
  "000118": [
    25,
    100
  ],
  "000121": [
    25,
    100
  ],
  "000122": [
    0,
    100
  ],
  "000125": [
    0,
    0
  ],
  "000126": [
    0,
    100
  ],
  "000129": [
    0,
    0
  ],
  "000131": [
    25,
    100
  ],
  "000132": [
    50,
    100
  ],
  "000133": [
    0,
    100
  ],
  "000134": [
    100,
    0
  ],
  "000135": [
    75,
    0
  ],
  "000137": [
    0,
    0
  ],
  "000140": [
    0,
    100
  ],
  "000142": [
    0,
    100
  ],
  "000143": [
    0,
    0
  ],
  "000145": [
    0,
    100
  ],
  "000146": [
    0,
    100
  ],
  "000147": [
    0,
    100
  ],
  "000148": [
    0,
    100
  ],
  "000150": [
    0,
    0
  ],
  "000151": [
    50,
    70
  ],
  "000152": [
    0,
    0
  ],
  "000153": [
    0,
    0
  ],
  "000155": [
    25,
    100
  ],
  "000156": [
    0,
    100
  ],
  "000157": [
    0,
    100
  ],
  "000160": [
    0,
    0
  ],
  "000161": [
    0,
    90
  ]
}

z_face_landmark_68_model-weights_manifest.json

[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004853619781194949,"min":-0.5872879935245888}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004396426443960153,"min":-0.7298067896973853}},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00635151559231328,"min":-0.5589333721235686}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009354315552057004,"min":-1.2628325995276957}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029380727048013726,"min":-0.5846764682554731}},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0049374802439820535,"min":-0.6171850304977566}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009941946758943446,"min":-1.3421628124573652}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030300481062309416,"min":-0.5272283704841838}},{"name":"dense0/conv3/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005672684837790097,"min":-0.7431217137505026}},{"name":"dense0/conv3/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010712201455060173,"min":-1.5639814124387852}},{"name":"dense0/conv3/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030966934035806097,"min":-0.3839899820439956}},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0039155554537679636,"min":-0.48161332081345953}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01023082966898002,"min":-1.094698774580862}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0027264176630506327,"min":-0.3871513081531898}},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004583378632863362,"min":-0.5454220573107401}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00915846403907327,"min":-1.117332612766939}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003091680419211294,"min":-0.5966943209077797}},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005407439727409214,"min":-0.708374604290607}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00946493943532308,"min":-1.2399070660273235}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004409168514550901,"min":-0.9788354102303}},{"name":"dense1/conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004478132958505668,"min":-0.6493292789833219}},{"name":"dense1/conv3/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011063695888893277,"min":-1.2501976354449402}},{"name":"dense1/conv3/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003909627596537272,"min":-0.6646366914113363}},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003213915404151468,"min":-0.3374611174359041}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010917326048308728,"min":-1.4520043644250609}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002800439152063108,"min":-0.38085972468058266}},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0050568851770139206,"min":-0.6927932692509071}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01074961213504567,"min":-1.3222022926106174}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030654204242369708,"min":-0.5487102559384177}},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00591809165244009,"min":-0.917304206128214}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01092823346455892,"min":-1.366029183069865}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002681120470458386,"min":-0.36463238398234055}},{"name":"dense2/conv3/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0048311497650894465,"min":-0.5797379718107336}},{"name":"dense2/conv3/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011227761062921263,"min":-1.4483811771168429}},{"name":"dense2/conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0034643323982463162,"min":-0.3360402426298927}},{"name":"dense3/conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394978887894574,"min":-0.49227193874471326}},{"name":"dense3/conv0/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010051267287310432,"min":-1.2765109454884247}},{"name":"dense3/conv0/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003142924752889895,"min":-0.4588670139219247}},{"name":"dense3/conv1/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00448304671867221,"min":-0.5872791201460595}},{"name":"dense3/conv1/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016063522357566685,"min":-2.3613377865623026}},{"name":"dense3/conv1/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00287135781026354,"min":-0.47664539650374765}},{"name":"dense3/conv2/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006002906724518421,"min":-0.7923836876364315}},{"name":"dense3/conv2/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.017087187019048954,"min":-1.6061955797906016}},{"name":"dense3/conv2/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003124481205846749,"min":-0.46242321846531886}},{"name":"dense3/conv3/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006576311588287353,"min":-1.0193282961845398}},{"name":"dense3/conv3/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015590153955945782,"min":-1.99553970636106}},{"name":"dense3/conv3/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004453541601405424,"min":-0.6546706154065973}},{"name":"fc/weights","shape":[256,136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010417488509533453,"min":-1.500118345372817}},{"name":"fc/bias","shape":[136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0025084222648658005,"min":0.07683877646923065}}],"paths":["z_face_landmark_68_model-shard1"]}]

z_face_recognition_model-weights_manifest.json

[{"weights":[{"name":"conv32_down/conv/filters","shape":[7,7,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0005260649557207145,"min":-0.07101876902229645}},{"name":"conv32_down/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":8.471445956577858e-7,"min":-0.00014740315964445472}},{"name":"conv32_down/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.06814416062598135,"min":5.788674831390381}},{"name":"conv32_down/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008471635042452345,"min":-0.931879854669758}},{"name":"conv32_1/conv1/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0007328585666768691,"min":-0.0974701893680236}},{"name":"conv32_1/conv1/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.5952091238361e-8,"min":-0.000001978059313556764}},{"name":"conv32_1/conv1/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.02146628510718252,"min":3.1103382110595703}},{"name":"conv32_1/conv1/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0194976619645661,"min":-2.3787147596770644}},{"name":"conv32_1/conv2/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0004114975824075587,"min":-0.05267169054816751}},{"name":"conv32_1/conv2/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.600177166424806e-9,"min":-5.70421968636676e-7}},{"name":"conv32_1/conv2/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03400764932819441,"min":2.1677730083465576}},{"name":"conv32_1/conv2/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010974494616190593,"min":-1.240117891629537}},{"name":"conv32_2/conv1/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0005358753251094444,"min":-0.0760942961655411}},{"name":"conv32_2/conv1/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":5.9886454383719385e-9,"min":-7.366033889197485e-7}},{"name":"conv32_2/conv1/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014633869657329485,"min":2.769575357437134}},{"name":"conv32_2/conv1/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.022131107367721257,"min":-2.5229462399202234}},{"name":"conv32_2/conv2/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00030145110452876373,"min":-0.03949009469326805}},{"name":"conv32_2/conv2/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":6.8779549306497095e-9,"min":-9.010120959151119e-7}},{"name":"conv32_2/conv2/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03929369870354148,"min":4.8010945320129395}},{"name":"conv32_2/conv2/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010553357180427103,"min":-1.2452961472903983}},{"name":"conv32_3/conv1/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0003133527642371608,"min":-0.040735859350830905}},{"name":"conv32_3/conv1/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.1064200719547974e-9,"min":-3.0387508532465503e-7}},{"name":"conv32_3/conv1/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009252088210161994,"min":2.333256721496582}},{"name":"conv32_3/conv1/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007104101251153385,"min":-0.34810096130651585}},{"name":"conv32_3/conv2/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00029995629892629733,"min":-0.031195455088334923}},{"name":"conv32_3/conv2/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":5.62726418316814e-9,"min":-6.921534945296811e-7}},{"name":"conv32_3/conv2/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0467432975769043,"min":5.362040996551514}},{"name":"conv32_3/conv2/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010314425300149357,"min":-1.268674311918371}},{"name":"conv64_down/conv1/conv/filters","shape":[3,3,32,64],"dtype":"float32"},{"name":"conv64_down/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":8.373908033218849e-10,"min":-1.172347124650639e-7}},{"name":"conv64_down/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0066875364266189875,"min":2.5088400840759277}},{"name":"conv64_down/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01691421620986041,"min":-2.0973628100226906}},{"name":"conv64_down/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_down/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.3252014483766877e-9,"min":-2.673981665633191e-7}},{"name":"conv64_down/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.032557439804077146,"min":2.6351239681243896}},{"name":"conv64_down/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015429047509735706,"min":-1.5429047509735707}},{"name":"conv64_1/conv1/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_1/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.1319172039756998e-9,"min":-1.4941307092479238e-7}},{"name":"conv64_1/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007802607031429515,"min":3.401733160018921}},{"name":"conv64_1/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01425027146058924,"min":-0.6982633015688727}},{"name":"conv64_1/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_1/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.5635019893325435e-9,"min":-2.717312108692496e-7}},{"name":"conv64_1/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04062801716374416,"min":3.542381525039673}},{"name":"conv64_1/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007973166306813557,"min":-0.7415044665336609}},{"name":"conv64_2/conv1/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_2/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.2535732661062331e-9,"min":-1.8302169685151004e-7}},{"name":"conv64_2/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005631206549850164,"min":2.9051668643951416}},{"name":"conv64_2/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01859012585060269,"min":-2.3795361088771445}},{"name":"conv64_2/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_2/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.486726369919351e-9,"min":-3.5311514452854786e-7}},{"name":"conv64_2/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03740917467603497,"min":5.571568965911865}},{"name":"conv64_2/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006418555858088475,"min":-0.5263215803632549}},{"name":"conv64_3/conv1/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_3/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":7.432564576875473e-10,"min":-8.47312361763804e-8}},{"name":"conv64_3/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006400122362024644,"min":2.268010377883911}},{"name":"conv64_3/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010945847922680425,"min":-1.3353934465670119}},{"name":"conv64_3/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_3/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.278228722014533e-9,"min":-3.212302498040492e-7}},{"name":"conv64_3/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.029840927498013366,"min":7.038398265838623}},{"name":"conv64_3/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010651412197187834,"min":-1.161003929493474}},{"name":"conv128_down/conv1/conv/filters","shape":[3,3,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00020040544662989823,"min":-0.022245004575918704}},{"name":"conv128_down/conv1/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.3550543563576545e-10,"min":-4.311503812794078e-8}},{"name":"conv128_down/conv1/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007448580685783835,"min":2.830846071243286}},{"name":"conv128_down/conv1/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01211262824488621,"min":-1.6957679542840696}},{"name":"conv128_down/conv2/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00022380277514457702,"min":-0.02484210804104805}},{"name":"conv128_down/conv2/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":9.031058637304466e-10,"min":-1.1650065642122761e-7}},{"name":"conv128_down/conv2/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.027663578706629135,"min":3.1111555099487305}},{"name":"conv128_down/conv2/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008878476946961646,"min":-1.029903325847551}},{"name":"conv128_1/conv1/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00022380667574265425,"min":-0.032899581334170175}},{"name":"conv128_1/conv1/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.4147297756478345e-10,"min":-5.253528433020923e-8}},{"name":"conv128_1/conv1/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013599334978589825,"min":3.634530782699585}},{"name":"conv128_1/conv1/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014059314073300829,"min":-1.4059314073300828}},{"name":"conv128_1/conv2/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00021715293474057143,"min":-0.02909849325523657}},{"name":"conv128_1/conv2/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":9.887046963276768e-10,"min":-1.1370104007768284e-7}},{"name":"conv128_1/conv2/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.029993299409454943,"min":3.630716562271118}},{"name":"conv128_1/conv2/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00782704236460667,"min":-0.7200878975438136}},{"name":"conv128_2/conv1/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00017718105923895743,"min":-0.022324813464108636}},{"name":"conv128_2/conv1/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":3.567012027797675e-10,"min":-5.243507680862582e-8}},{"name":"conv128_2/conv1/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007940645778880399,"min":4.927767753601074}},{"name":"conv128_2/conv1/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015933452867994122,"min":-1.5614783810634238}},{"name":"conv128_2/conv2/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0001451439717236687,"min":-0.01712698866339291}},{"name":"conv128_2/conv2/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.0383988570966347e-9,"min":-1.2356946399449953e-7}},{"name":"conv128_2/conv2/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.02892604528688917,"min":4.750600814819336}},{"name":"conv128_2/conv2/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00797275748907351,"min":-0.7414664464838364}},{"name":"conv256_down/conv1/conv/filters","shape":[3,3,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0002698827827093648,"min":-0.03994265184098599}},{"name":"conv256_down/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":5.036909834755123e-10,"min":-6.396875490139006e-8}},{"name":"conv256_down/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014870181738161573,"min":4.269900798797607}},{"name":"conv256_down/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.022031106200872685,"min":-3.1063859743230484}},{"name":"conv256_down/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00046430734150549946,"min":-0.03946612402796745}},{"name":"conv256_down/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":6.693064577513153e-10,"min":-7.630093618364995e-8}},{"name":"conv256_down/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03475512242784687,"min":3.608360528945923}},{"name":"conv256_down/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01290142021927179,"min":-1.1482263995151893}},{"name":"conv256_1/conv1/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00037147209924810076,"min":-0.04234781931428348}},{"name":"conv256_1/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":3.2105515457510146e-10,"min":-3.467395669411096e-8}},{"name":"conv256_1/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.043242172166412955,"min":5.28542947769165}},{"name":"conv256_1/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01643658619300992,"min":-1.3149268954407936}},{"name":"conv256_1/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0003289232651392619,"min":-0.041773254672686264}},{"name":"conv256_1/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":9.13591691187321e-10,"min":-1.2333487831028833e-7}},{"name":"conv256_1/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0573908618852204,"min":4.360693454742432}},{"name":"conv256_1/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0164216583850337,"min":-1.3958409627278647}},{"name":"conv256_2/conv1/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00010476927912118389,"min":-0.015610622589056398}},{"name":"conv256_2/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.418552539068639e-10,"min":-2.539480166022071e-8}},{"name":"conv256_2/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.06024209564807368,"min":6.598613739013672}},{"name":"conv256_2/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01578534350675695,"min":-1.1049740454729864}},{"name":"conv256_2/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00005543030908002573,"min":-0.007427661416723448}},{"name":"conv256_2/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.0822061852320308e-9,"min":-1.515088659324843e-7}},{"name":"conv256_2/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04302893993901272,"min":2.2855491638183594}},{"name":"conv256_2/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006792667566561232,"min":-0.8083274404207865}},{"name":"conv256_down_out/conv1/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.000568966465253456,"min":-0.05632768006009214}},{"name":"conv256_down_out/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.5347887884881677e-10,"min":-6.530095855422961e-8}},{"name":"conv256_down_out/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.017565592597512638,"min":4.594101905822754}},{"name":"conv256_down_out/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04850864223405427,"min":-6.306123490427055}},{"name":"conv256_down_out/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0003739110687199761,"min":-0.06954745878191555}},{"name":"conv256_down_out/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.2668428328152895e-9,"min":-2.2549802424112154e-7}},{"name":"conv256_down_out/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04351314469879749,"min":4.31956672668457}},{"name":"conv256_down_out/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021499746921015722,"min":-1.2039858275768804}},{"name":"fc","shape":[256,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.000357687911566566,"min":-0.04578405268052045}}],"paths":["z_face_recognition_model-shard1","z_face_recognition_model-shard2"]}]

z_face_system.js

// Arithmetic mean
let getMean = function (data) {
    return data.reduce(function (a, b) {
        return Number(a) + Number(b);
    }) / data.length;
};

// Standard deviation
let getSD = function (data) {
    let m = getMean(data);
    return Math.sqrt(data.reduce(function (sq, n) {
            return sq + Math.pow(n - m, 2);
        }, 0) / (data.length - 1));
};

const LM_LEN = 68;
const LM_parts = ['chin', 'left_eyebrow', 'right_eyebrow',
'nose_bridge', 'nose_tip', 'left_eye', 'right_eye',
'top_lip', 'bottom_lip'];
const LM_names = [
'chin', 'chin', 'chin', 'chin', 'chin',
'chin', 'chin', 'chin', 'chin', 'chin',
'chin', 'chin', 'chin', 'chin', 'chin',
'chin', 'chin',
'left_eyebrow', 'left_eyebrow', 'left_eyebrow', 'left_eyebrow', 'left_eyebrow',
'right_eyebrow', 'right_eyebrow', 'right_eyebrow', 'right_eyebrow', 'right_eyebrow',
'nose_bridge', 'nose_bridge', 'nose_bridge', 'nose_bridge',
'nose_tip', 'nose_tip', 'nose_tip', 'nose_tip', 'nose_tip',
'left_eye', 'left_eye', 'left_eye', 'left_eye', 'left_eye', 'left_eye',
'right_eye', 'right_eye', 'right_eye', 'right_eye', 'right_eye', 'right_eye',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip'
]
// https://github.com/ageitgey/face_recognition/blob/d34c622bf42e2c619505a4884017051ecf61ac77/face_recognition/api.py#L190
const top_lip_indices =    [48, 49, 50, 51, 52, 53, 54, 64, 63, 62, 61, 60];
const bottom_lip_indices = [54, 55, 56, 57, 58, 59, 48, 60, 67, 66, 65, 64];

function get_landmarks(faceDescriptions) {
  let landmarks = []
  for(let i=0; i<faceDescriptions.length; i++) {
    let curLM = {
      'chin': [],
      'left_eyebrow': [],
      'right_eyebrow': [],
      'nose_bridge': [],
      'nose_tip': [],
      'left_eye': [],
      'right_eye': [],
      'top_lip': [],
      'bottom_lip': []
    };
    let lm = faceDescriptions[i].landmarks;
    let lpts = lm.positions;
    let x_points = [];
    let y_points = [];
    // print(lpts.length)
    for(let j=0; j<LM_LEN; j++) {
      x_points.push(lpts[j].x)
      y_points.push(lpts[j].y)
    }
    let mean_x = getMean(x_points);
    let mean_y = getMean(y_points);
    for(let j=0; j<LM_LEN; j++) {
      x_points[j] = x_points[j] - mean_x;
      y_points[j] = y_points[j] - mean_y;
    }
    let sdev_x = getSD(x_points);
    let sdev_y = getSD(y_points);
    let sdev = sdev_x > sdev_y ? sdev_x : sdev_y;
    // let p1 = lpts[27]
    // let p2 = lpts[28]
    // EYES VERSION
    // let p1 = lpts[36];
    // let p2 = lpts[42];
    // EARS VERSION
    let p1 = lpts[2];
    let p2 = lpts[14];
    let xd = p1.x - p2.x;
    let yd = p1.y - p2.y;
    let angle = Math.atan2(-yd, -xd);
    let s_a = Math.sin(-angle);
    let c_a = Math.cos(-angle);
    let raw_points = []
    for(let j=0; j<LM_LEN; j++) {
      let pt = [0, 0]
      pt[0] = lpts[j].x - mean_x;
      pt[1] = lpts[j].y - mean_y;
      pt[0] = pt[0] / sdev;
      pt[1] = pt[1] / sdev;
      let x_new = pt[0] * c_a - pt[1] * s_a;
      let y_new = pt[0] * s_a + pt[1] * c_a;
      pt[0] = x_new;
      pt[1] = y_new;
      raw_points.push(pt);
    }
    // put all raw points into landmarks objects
    // first everything but the lips (which start at 48)
    for(let j=0; j<48; j++) {
      let key = LM_names[j];
      curLM[key].push(raw_points[j]);
    }
    // now the lips, which have dupes
    for(let j=0; j<top_lip_indices.length; j++) {
      let cur_ix = top_lip_indices[j];
      let cur_pt = raw_points[cur_ix];
      let pt_copy = [cur_pt[0], cur_pt[1]];
      curLM['top_lip'].push(pt_copy);
    }
    for(let j=0; j<bottom_lip_indices.length; j++) {
      let cur_ix = bottom_lip_indices[j];
      let cur_pt = raw_points[cur_ix];
      let pt_copy = [cur_pt[0], cur_pt[1]];
      curLM['bottom_lip'].push(pt_copy);
    }
    curLM['transform'] = {
      'center': [mean_x, mean_y],
      'scale': sdev,
      'angle': angle
    }
    landmarks.push(curLM);
  }
  // print(JSON.stringify(landmarks));
  return landmarks;
}

function get_latents(faceDescriptions) {
  latents = [];
  for(let i=0; i<faceDescriptions.length; i++) {
    let lm = faceDescriptions[i].descriptor;
    latents.push(lm);
    // print(lm);
  }
  return latents;
}

z_focused_random.js

function resetFocusedRandom() {
  return Math.seedrandom(arguments);
}

function focusedRandom(min, max, focus, mean) {
  // console.log("hello")
  if(max === undefined) {
    max = min;
    min = 0;
  }
  if(focus === undefined) {
    focus = 1.0;
  }
  if(mean === undefined) {
    mean = (min + max) / 2.0;
  }
  if(focus == 0) {
    return d3.randomUniform(min, max)();
  }
  else if(focus < 0) {
    focus = -1 / focus;
  }
  let sigma = (max - min) / (2 * focus);
  let val = d3.randomNormal(mean, sigma)();
  if (val >= min && val < max) {
    return val;
  }
  return d3.randomUniform(min, max)();
}

z_kdTree.js

/**
 * k-d Tree JavaScript - V 1.01
 *
 * https://github.com/ubilabs/kd-tree-javascript
 *
 * @author Mircea Pricop <pricop@ubilabs.net>, 2012
 * @author Martin Kleppe <kleppe@ubilabs.net>, 2012
 * @author Ubilabs http://ubilabs.net, 2012
 * @license MIT License <http://www.opensource.org/licenses/mit-license.php>
 */

 (function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['exports'], factory);
    } else if (typeof exports === 'object') {
        factory(exports);
    } else {
        factory((root.commonJsStrict = {}));
    }
}(this, function (exports) {
  function Node(obj, dimension, parent) {
    this.obj = obj;
    this.left = null;
    this.right = null;
    this.parent = parent;
    this.dimension = dimension;
  }

  function kdTree(points, metric, dimensions) {

    var self = this;
    
    function buildTree(points, depth, parent) {
      var dim = depth % dimensions.length,
        median,
        node;

      if (points.length === 0) {
        return null;
      }
      if (points.length === 1) {
        return new Node(points[0], dim, parent);
      }

      points.sort(function (a, b) {
        return a[dimensions[dim]] - b[dimensions[dim]];
      });

      median = Math.floor(points.length / 2);
      node = new Node(points[median], dim, parent);
      node.left = buildTree(points.slice(0, median), depth + 1, node);
      node.right = buildTree(points.slice(median + 1), depth + 1, node);

      return node;
    }

    // Reloads a serialied tree
    function loadTree (data) {
      // Just need to restore the `parent` parameter
      self.root = data;

      function restoreParent (root) {
        if (root.left) {
          root.left.parent = root;
          restoreParent(root.left);
        }

        if (root.right) {
          root.right.parent = root;
          restoreParent(root.right);
        }
      }

      restoreParent(self.root);
    }
    
    // If points is not an array, assume we're loading a pre-built tree
    if (!Array.isArray(points)) loadTree(points, metric, dimensions);
    else this.root = buildTree(points, 0, null);

    // Convert to a JSON serializable structure; this just requires removing 
    // the `parent` property
    this.toJSON = function (src) {
      if (!src) src = this.root;
      var dest = new Node(src.obj, src.dimension, null);
      if (src.left) dest.left = self.toJSON(src.left);
      if (src.right) dest.right = self.toJSON(src.right);
      return dest;
    };

    this.insert = function (point) {
      function innerSearch(node, parent) {

        if (node === null) {
          return parent;
        }

        var dimension = dimensions[node.dimension];
        if (point[dimension] < node.obj[dimension]) {
          return innerSearch(node.left, node);
        } else {
          return innerSearch(node.right, node);
        }
      }

      var insertPosition = innerSearch(this.root, null),
        newNode,
        dimension;

      if (insertPosition === null) {
        this.root = new Node(point, 0, null);
        return;
      }

      newNode = new Node(point, (insertPosition.dimension + 1) % dimensions.length, insertPosition);
      dimension = dimensions[insertPosition.dimension];

      if (point[dimension] < insertPosition.obj[dimension]) {
        insertPosition.left = newNode;
      } else {
        insertPosition.right = newNode;
      }
    };

    this.remove = function (point) {
      var node;

      function nodeSearch(node) {
        if (node === null) {
          return null;
        }

        if (node.obj === point) {
          return node;
        }

        var dimension = dimensions[node.dimension];

        if (point[dimension] < node.obj[dimension]) {
          return nodeSearch(node.left, node);
        } else {
          return nodeSearch(node.right, node);
        }
      }

      function removeNode(node) {
        var nextNode,
          nextObj,
          pDimension;

        function findMin(node, dim) {
          var dimension,
            own,
            left,
            right,
            min;

          if (node === null) {
            return null;
          }

          dimension = dimensions[dim];

          if (node.dimension === dim) {
            if (node.left !== null) {
              return findMin(node.left, dim);
            }
            return node;
          }

          own = node.obj[dimension];
          left = findMin(node.left, dim);
          right = findMin(node.right, dim);
          min = node;

          if (left !== null && left.obj[dimension] < own) {
            min = left;
          }
          if (right !== null && right.obj[dimension] < min.obj[dimension]) {
            min = right;
          }
          return min;
        }

        if (node.left === null && node.right === null) {
          if (node.parent === null) {
            self.root = null;
            return;
          }

          pDimension = dimensions[node.parent.dimension];

          if (node.obj[pDimension] < node.parent.obj[pDimension]) {
            node.parent.left = null;
          } else {
            node.parent.right = null;
          }
          return;
        }

        // If the right subtree is not empty, swap with the minimum element on the
        // node's dimension. If it is empty, we swap the left and right subtrees and
        // do the same.
        if (node.right !== null) {
          nextNode = findMin(node.right, node.dimension);
          nextObj = nextNode.obj;
          removeNode(nextNode);          
          node.obj = nextObj;
        } else {
          nextNode = findMin(node.left, node.dimension);
          nextObj = nextNode.obj;
          removeNode(nextNode);
          node.right = node.left;
          node.left = null;
          node.obj = nextObj;
        }

      }

      node = nodeSearch(self.root);

      if (node === null) { return; }

      removeNode(node);
    };

    this.nearest = function (point, maxNodes, maxDistance) {
      var i,
        result,
        bestNodes;

      bestNodes = new BinaryHeap(
        function (e) { return -e[1]; }
      );

      function nearestSearch(node) {
        var bestChild,
          dimension = dimensions[node.dimension],
          ownDistance = metric(point, node.obj),
          linearPoint = {},
          linearDistance,
          otherChild,
          i;

        function saveNode(node, distance) {
          bestNodes.push([node, distance]);
          if (bestNodes.size() > maxNodes) {
            bestNodes.pop();
          }
        }

        for (i = 0; i < dimensions.length; i += 1) {
          if (i === node.dimension) {
            linearPoint[dimensions[i]] = point[dimensions[i]];
          } else {
            linearPoint[dimensions[i]] = node.obj[dimensions[i]];
          }
        }

        linearDistance = metric(linearPoint, node.obj);

        if (node.right === null && node.left === null) {
          if (bestNodes.size() < maxNodes || ownDistance < bestNodes.peek()[1]) {
            saveNode(node, ownDistance);
          }
          return;
        }

        if (node.right === null) {
          bestChild = node.left;
        } else if (node.left === null) {
          bestChild = node.right;
        } else {
          if (point[dimension] < node.obj[dimension]) {
            bestChild = node.left;
          } else {
            bestChild = node.right;
          }
        }

        nearestSearch(bestChild);

        if (bestNodes.size() < maxNodes || ownDistance < bestNodes.peek()[1]) {
          saveNode(node, ownDistance);
        }

        if (bestNodes.size() < maxNodes || Math.abs(linearDistance) < bestNodes.peek()[1]) {
          if (bestChild === node.left) {
            otherChild = node.right;
          } else {
            otherChild = node.left;
          }
          if (otherChild !== null) {
            nearestSearch(otherChild);
          }
        }
      }

      if (maxDistance) {
        for (i = 0; i < maxNodes; i += 1) {
          bestNodes.push([null, maxDistance]);
        }
      }

      if(self.root)
        nearestSearch(self.root);

      result = [];

      for (i = 0; i < Math.min(maxNodes, bestNodes.content.length); i += 1) {
        if (bestNodes.content[i][0]) {
          result.push([bestNodes.content[i][0].obj, bestNodes.content[i][1]]);
        }
      }
      return result;
    };

    this.balanceFactor = function () {
      function height(node) {
        if (node === null) {
          return 0;
        }
        return Math.max(height(node.left), height(node.right)) + 1;
      }

      function count(node) {
        if (node === null) {
          return 0;
        }
        return count(node.left) + count(node.right) + 1;
      }

      return height(self.root) / (Math.log(count(self.root)) / Math.log(2));
    };
  }

  // Binary heap implementation from:
  // http://eloquentjavascript.net/appendix2.html

  function BinaryHeap(scoreFunction){
    this.content = [];
    this.scoreFunction = scoreFunction;
  }

  BinaryHeap.prototype = {
    push: function(element) {
      // Add the new element to the end of the array.
      this.content.push(element);
      // Allow it to bubble up.
      this.bubbleUp(this.content.length - 1);
    },

    pop: function() {
      // Store the first element so we can return it later.
      var result = this.content[0];
      // Get the element at the end of the array.
      var end = this.content.pop();
      // If there are any elements left, put the end element at the
      // start, and let it sink down.
      if (this.content.length > 0) {
        this.content[0] = end;
        this.sinkDown(0);
      }
      return result;
    },

    peek: function() {
      return this.content[0];
    },

    remove: function(node) {
      var len = this.content.length;
      // To remove a value, we must search through the array to find
      // it.
      for (var i = 0; i < len; i++) {
        if (this.content[i] == node) {
          // When it is found, the process seen in 'pop' is repeated
          // to fill up the hole.
          var end = this.content.pop();
          if (i != len - 1) {
            this.content[i] = end;
            if (this.scoreFunction(end) < this.scoreFunction(node))
              this.bubbleUp(i);
            else
              this.sinkDown(i);
          }
          return;
        }
      }
      throw new Error("Node not found.");
    },

    size: function() {
      return this.content.length;
    },

    bubbleUp: function(n) {
      // Fetch the element that has to be moved.
      var element = this.content[n];
      // When at 0, an element can not go up any further.
      while (n > 0) {
        // Compute the parent element's index, and fetch it.
        var parentN = Math.floor((n + 1) / 2) - 1,
            parent = this.content[parentN];
        // Swap the elements if the parent is greater.
        if (this.scoreFunction(element) < this.scoreFunction(parent)) {
          this.content[parentN] = element;
          this.content[n] = parent;
          // Update 'n' to continue at the new position.
          n = parentN;
        }
        // Found a parent that is less, no need to move it further.
        else {
          break;
        }
      }
    },

    sinkDown: function(n) {
      // Look up the target element and its score.
      var length = this.content.length,
          element = this.content[n],
          elemScore = this.scoreFunction(element);

      while(true) {
        // Compute the indices of the child elements.
        var child2N = (n + 1) * 2, child1N = child2N - 1;
        // This is used to store the new position of the element,
        // if any.
        var swap = null;
        // If the first child exists (is inside the array)...
        if (child1N < length) {
          // Look it up and compute its score.
          var child1 = this.content[child1N],
              child1Score = this.scoreFunction(child1);
          // If the score is less than our element's, we need to swap.
          if (child1Score < elemScore)
            swap = child1N;
        }
        // Do the same checks for the other child.
        if (child2N < length) {
          var child2 = this.content[child2N],
              child2Score = this.scoreFunction(child2);
          if (child2Score < (swap == null ? elemScore : child1Score)){
            swap = child2N;
          }
        }

        // If the element needs to be moved, swap it, and continue.
        if (swap != null) {
          this.content[n] = this.content[swap];
          this.content[swap] = element;
          n = swap;
        }
        // Otherwise, we are done.
        else {
          break;
        }
      }
    }
  };
  
  this.kdTree = kdTree;
  
  exports.kdTree = kdTree;
  exports.BinaryHeap = BinaryHeap;
}));

z_purview_helper.js

// note: this file is poorly named - it can generally be ignored.

// helper functions below for supporting blocks/purview

function saveBlocksImages(doZoom) {
  if(doZoom == null) {
    doZoom = false;
  }

  // generate 960x500 preview.jpg of entire canvas
  // TODO: should this be recycled?
  var offscreenCanvas = document.createElement('canvas');
  offscreenCanvas.width = 960;
  offscreenCanvas.height = 500;
  var context = offscreenCanvas.getContext('2d');
  // background is flat white
  context.fillStyle="#FFFFFF";
  context.fillRect(0, 0, 960, 500);
  context.drawImage(this.canvas, 0, 0, 960, 500);
  // save to browser
  var downloadMime = 'image/octet-stream';
  var imageData = offscreenCanvas.toDataURL('image/jpeg');
  imageData = imageData.replace('image/jpeg', downloadMime);
  p5.prototype.downloadFile(imageData, 'preview.jpg', 'jpg');

  // generate 230x120 thumbnail.png centered on mouse
  offscreenCanvas.width = 230;
  offscreenCanvas.height = 120;

  // background is flat white  
  context = offscreenCanvas.getContext('2d');
  context.fillStyle="#FFFFFF";
  context.fillRect(0, 0, 230, 120);

  if(doZoom) {
    // pixelDensity does the right thing on retina displays
    var pd = this._pixelDensity;
    var sx = pd * mouseX - pd * 230/2;
    var sy = pd * mouseY - pd * 120/2;
    var sw = pd * 230;
    var sh = pd * 120;
    // bounds checking - just displace if necessary
    if (sx < 0) {
      sx = 0;
    }
    if (sx > this.canvas.width - sw) {
      sx = this.canvas.width - sw;
    }
    if (sy < 0) {
      sy = 0;
    }
    if (sy > this.canvas.height - sh) {
      sy = this.canvas.height - sh;
    }
    // save to browser
    context.drawImage(this.canvas, sx, sy, sw, sh, 0, 0, 230, 120);
  }
  else {
    // now scaledown
    var full_width = this.canvas.width;
    var full_height = this.canvas.height;
    context.drawImage(this.canvas, 0, 0, full_width, full_height, 0, 0, 230, 120);
  }
  imageData = offscreenCanvas.toDataURL('image/png');
  imageData = imageData.replace('image/png', downloadMime);
  // call this function after 1 second
  setTimeout(function(){
    p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png');
  }, 1000);
}