JSFiddle - React, Tailwind, and code Playground

by morphcast

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/smoothie/1.34.0/smoothie.min.js"></script>
<script src="https://ai-sdk.morphcast.com/dev/ai-sdk.js"></script>
<body>
  <div class="container-fluid">
    <div class="row">
       <video playsinline preload="auto" loop crossorigin="Anonymous" onclick="toggleVideo();" src="https://s3.eu-central-1.amazonaws.com/demo.morphcast.com/attention/claudia2.mp4" id="yt_player" width=320></video>
        <strong>MorphCast JS SDK - Attention module (dev environment)</strong>
      <br />
      Raw attention
      <br />
      <canvas id="chart_att" width="400" height="250"></canvas>
      <br />
      pose_attention
      <br />
      <canvas id="chart_yaw" width="400" height="250"></canvas>
      <br />
      arousal_attention (with clipped outliers)
      <br />
      <canvas id="chart_arousal" width="400" height="250"></canvas>
      <div class="col-md-4">
        <div id="results" style="word-wrap:break-word;font-size:40px"></div>
        <div id="detector"></div>
      </div>
    </div>
    <div>
      <button id="start" onclick="onStart()" disabled>Start</button>
      <button id="stop" onclick="onStop()">Stop</button>
      <p>
        <strong>Instructions</strong>
        Press the start button to start the detector.
        <br/> Press the stop button to end the detector.
      </p>
      <div>
        <strong>LOG:</strong>
      </div>
      <div id="logs"></div>
    </div>
  </div>
</body>

JavaScript

const config = {
  minAttention: 0,
  maxYaw: 0.25, // 15°
  maxArousal: 0.5,
  arousalNegTrigger: -0.2
};
log('Current config is : ' + JSON.stringify(config));

let prev_filtered_attention;

function attentionMetric({
  yaw
}, arousal) {
  let attention = config.minAttention;

  const MAX_YAW = config.maxYaw;
  const MAX_AROUSAL = config.maxArousal;
  const AROUSAL_NEG_TRIGGER = config.arousalNegTrigger;

  //let pose_attention = Math.max(0, 1 - Math.abs(yaw)/MAX_YAW);
  let pose_attention = yaw; // Math.max(0, 1-Math.pow(Math.abs(yaw),2.5)/0.0129);
  //let neg_arousal = arousal < AROUSAL_NEG_TRIGGER ? Math.abs(arousal) : 0;
  //let arousal_attention = Math.max(0, 1 - neg_arousal / (MAX_AROUSAL) ); // edited

  let arousal_attention = arousal; // 1 + Math.max(-1,Math.min(0, arousal*3));
  ts_yaw_raw.append(new Date().getTime(), pose_attention);
  ts_arousal.append(new Date().getTime(), arousal_attention);

  attention = pose_attention * arousal_attention;
  let clipped_attention = clip_window_filter(attention_mean, attention);

  ts_att_raw.append(new Date().getTime(), clipped_attention);

  const ALPHA = 0.17;

  if (prev_filtered_attention === undefined) {
    prev_filtered_attention = clipped_attention;
  }

  let final_attention = ALPHA * clipped_attention + (1 - ALPHA) * prev_filtered_attention;
  prev_filtered_attention = final_attention;

  return Math.min(1, Math.max(0, final_attention));

}

///////

class Window {
  constructor(maxLen) {
    if (!Number.isInteger(maxLen) || maxLen < 1) {
      throw new RangeError('Maximum window size must be an integer greater than zero.');
    }
    this._maxLen = maxLen;
    this._queue = [];
  }

  enqueue(item) {
    this._queue.unshift(item);
    if (this._queue.length > this._maxLen) {
      return this._queue.pop();
    }
  }

  get length() {
    return this._queue.length;
  }
}

/*
  The average squared deviation is normally calculated as
  ``x.sum() / N``, where ``N = len(x)``.  If, however, `ddof` is...