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...