JSFiddle - React, Tailwind, and code Playground

by morphcast

HTML

<script src="https://ai-sdk.morphcast.com/rc/ai-sdk.js"></script>
<body>
  <div class="container-fluid">
    <div class="row">
      <canvas id="canvas" class="col-md-8"></canvas>
      <div class="col-md-4">
        <div style="height:25em;">
          <strong>Results of Emotion Tracker (RC env) with features</strong>
          <div id="frame_counter" style="word-wrap:break-word;"></div>
          <div id="fps" style="word-wrap:break-word;"></div>
          <div id="face_detector_results" style="word-wrap:break-word;"></div>
          <div id="emotion_results" style="word-wrap:break-word;"></div>
          <div id="age_results" style="word-wrap:break-word;"></div>
          <div id="gender_results" style="word-wrap:break-word;"></div>
          <div id="pose_results" style="word-wrap:break-word;"></div>
          <div id="prediction_time" style="word-wrap:break-word;"></div>
          <div id="features_results" style="word-wrap:break-word;"></div>
      </div>
    </div>
    <div>
      <button id="start" onclick="onStart()" disabled>Start</button>
      <button id="stop" onclick="onStop()">Stop</button>
      <div>
        <strong>DETECTOR LOG MSGS</strong>
      </div>
      <div id="logs"></div>
      <h3>MorphCast JS SDK tracks different emotions.</h3>
      <p>
        <strong>Instructions</strong>
        </br>
        Press the start button to start the detector.
        <br/> When a face is detected, the probabilities of the different emotions are written to the DOM.
        <br/> Press the stop button to end the detector.
      </p>
    </div>
  </div>
</body>

JavaScript

function log(msg) {
	var element = document.getElementById("logs");
  element.innerHTML += "<span>" + msg + "</span><br />";
}

function print(node, msg) {
  document.getElementById(node).innerHTML = msg;
}

function getArgMaxKey(dict) {
	return Object.keys(dict).reduce((a, b) => dict[a] > dict[b] ? a : b)
} 

//function executes when Start button is pushed.
function onStart() {
  if (detector && !detector.isRunning) {
		detector.t2 = performance.now();
    detector.framesCounter = 0;
    detector.fpsCounter = 0;
    detector.isRunning = true;
    detector.start().then(()=>{
    	detector.startTime = performance.now() - detector.t2;
      log("Start time: " + detector.startTime.toFixed(0) + " ms");
    });
  }
  log("Clicked the start button");
}

//function executes when the Stop button is pushed.
function onStop() {
  log("Clicked the stop button");
  if (detector && detector.isRunning) {
    detector.stop();
    detector.isRunning = false;
  }
}

window.addEventListener(CY.modules().FACE_DETECTOR.eventName, (evt) => {
  if(detector.t_loop === undefined) {
    detector.t_loop = performance.now();
  }
  if (performance.now() - detector.t_loop >= 1000 ) {
  	const accumulatedTime = performance.now() - detector.t_loop;
    const mean_time = accumulatedTime / detector.fpsCounter;
  	print("fps", "FPS: " + (1000/mean_time).toFixed(0));
    detector.fpsCounter = 0;
  	detector.t_loop = performance.now();
  }
  
  detector.fpsCounter++;
  
  print("face_detector_results", "Number of faces found: " + evt.detail.faces.length);
});

window.addEventListener(CY.modules().FACE_AGE.eventName, (evt) => {
  print("age_results", "Age: " + getArgMaxKey(evt.detail.output.age));
});

window.addEventListener(CY.modules().FACE_EMOTION.eventName, (evt) => {
  print("emotion_results", "Emotions: " + getArgMaxKey(evt.detail.output.emotion));
});

window.addEventListener(CY.modules().FACE_GENDER.eventName, (evt) => {
  print("gender_results", "Gender: " +...