510 lines
12 KiB
PHP
510 lines
12 KiB
PHP
<html>
|
|
<head>
|
|
<title>Results of analysis: The Black Box Concern</title>
|
|
<script type="text/javascript" src="lodash.core.min.js"></script>
|
|
<script type="text/javascript" src="plotly-1.31.2.min.js"></script>
|
|
<script type="text/javascript">
|
|
|
|
var d1 = <?php echo require "output/talk1.json" ?>;
|
|
var d2 = <?php echo require "output/talk2.json" ?>;
|
|
//~ var d3 = <?php echo require "output/talk3.json" ?>;
|
|
|
|
</script>
|
|
<style type="text/css">
|
|
body{
|
|
font-family: sans-serif;
|
|
width:calc(88%);
|
|
margin-left:12%;
|
|
margin-right:0;
|
|
}
|
|
#scroller{
|
|
width:100%;
|
|
overflow-x:auto;
|
|
}
|
|
#presentations{
|
|
width:200%;
|
|
}
|
|
#presentations .presentation{
|
|
width:50%;
|
|
float:left;
|
|
}
|
|
#presentations .presentation div.plot{
|
|
width:100%;
|
|
height:10em;
|
|
}
|
|
#checkboxes{
|
|
font-size: .8em;
|
|
width: 13em;
|
|
position:absolute;
|
|
left:0;
|
|
top:0;
|
|
}
|
|
label{
|
|
display:block;
|
|
}
|
|
.legendColour{
|
|
width:1em;
|
|
height:1em;
|
|
display:inline-block;
|
|
float:right;
|
|
margin-top:0.6em;
|
|
}
|
|
#checkboxes span{
|
|
color: gray;
|
|
}
|
|
#checkboxes :checked + span{
|
|
color: black;
|
|
}
|
|
#imgwrap{
|
|
|
|
}
|
|
|
|
#imgwrap div{
|
|
display:block;
|
|
color:#999;
|
|
font-size:80%;
|
|
}
|
|
#imgwrap img{
|
|
height:7em;
|
|
min-width: 3em;
|
|
background:#ccc;
|
|
margin-left:2%;
|
|
margin-top:1em;
|
|
}
|
|
h1{
|
|
margin: .1em 0;
|
|
text-transform:uppercase;
|
|
height:.9em;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="checkboxes">
|
|
|
|
</div>
|
|
|
|
<div id="scroller">
|
|
<div id='presentations'>
|
|
<div class='presentation'>
|
|
<h1>Penousal Machado</h1>
|
|
<div class='stats' id='plot2-stats'></div>
|
|
<div class='plot' id="plot2-div"></div>
|
|
</div>
|
|
|
|
<div class='presentation'>
|
|
<h1>Orit Halpern</h1>
|
|
<div class='stats' id='plot1-stats'></div>
|
|
<div class='plot' id="plot1-div"></div>
|
|
</div>
|
|
|
|
|
|
<!--
|
|
|
|
<div class='presentation'>
|
|
<h1>Nicolas Maigret</h1>
|
|
<div class='stats' id='plot3-stats'></div>
|
|
<div class='plot' id="plot3-div"></div>
|
|
</div>
|
|
-->
|
|
</div>
|
|
</div>
|
|
|
|
<div id='imgwrap'>
|
|
</div>
|
|
|
|
<script type='text/javascript'>
|
|
|
|
facialParameters = [
|
|
"smile",
|
|
"innerBrowRaise",
|
|
"browRaise",
|
|
"browFurrow",
|
|
"noseWrinkle",
|
|
"upperLipRaise",
|
|
"lipCornerDepressor",
|
|
"chinRaise",
|
|
"lipPucker",
|
|
"lipPress",
|
|
"lipSuck",
|
|
"mouthOpen",
|
|
"smirk",
|
|
"eyeClosure",
|
|
"eyeWiden",
|
|
"cheekRaise",
|
|
"lidTighten",
|
|
"dimpler",
|
|
"lipStretch",
|
|
"jawDrop",
|
|
]
|
|
defaultFacialParameters = [
|
|
"smile",
|
|
"innerBrowRaise",
|
|
"browRaise",
|
|
"browFurrow",
|
|
"noseWrinkle",
|
|
//~ "upperLipRaise",
|
|
//~ "lipCornerDepressor",
|
|
"chinRaise",
|
|
// "lipPucker",
|
|
//~ "lipPress",
|
|
//~ "lipSuck",
|
|
//~ "mouthOpen",
|
|
//"smirk",
|
|
// "attention",
|
|
//~ "eyeClosure",
|
|
//~ "eyeWiden",
|
|
"cheekRaise", //
|
|
"lidTighten",
|
|
//~ "dimpler", //
|
|
//~ "lipStretch",
|
|
//~ "jawDrop", //
|
|
];
|
|
|
|
var paramColours = {
|
|
"smile":"#FFA500",
|
|
"innerBrowRaise":"#FF3300",
|
|
"browRaise":"#FF003D",
|
|
"browFurrow":"#FF0095",
|
|
"noseWrinkle":"#E000FF",
|
|
"upperLipRaise":"#9B00FF",
|
|
"lipCornerDepressor":"#5800FF",
|
|
"chinRaise":"#0053FF",
|
|
"lipPucker":"#00C1FF",
|
|
"lipPress":"#00FF8C",
|
|
"lipSuck":"#0BFF00",
|
|
"mouthOpen":"#8CFF00",
|
|
"smirk":"#DCFF00",
|
|
"eyeClosure":"#A3841A",
|
|
"eyeWiden":"#852D0C",
|
|
"cheekRaise":"#850C3B",
|
|
"lidTighten":"#301271",
|
|
"dimpler":"#214761",
|
|
"lipStretch":"#216156",
|
|
"jawDrop":"#326121",
|
|
}
|
|
|
|
function getCheckedParams(){
|
|
params = [];
|
|
for(var i in facialParameters){
|
|
let param = facialParameters[i];
|
|
if(document.getElementById("check_"+param).checked){
|
|
params.push(param);
|
|
}
|
|
}
|
|
return params;
|
|
}
|
|
|
|
// expresiveness = average change in value
|
|
function getExpressivenessForParams(d, params)
|
|
{
|
|
let total = 0;
|
|
let nrs = 0;
|
|
for(let i in d['windows']) {
|
|
if(i == 0) {
|
|
continue;
|
|
}
|
|
nrs++;
|
|
let sub = 0;
|
|
for(let p in params) {
|
|
let param = params[p];
|
|
sub += Math.pow(d['windows'][i-1]['params'][param] - d['windows'][i]['params'][param], 2);
|
|
}
|
|
total += Math.sqrt(sub);
|
|
}
|
|
return total/nrs;
|
|
}
|
|
|
|
function getExpressivenessPerParam(d, params)
|
|
{
|
|
let paramValues = {};
|
|
for(let p in params) {
|
|
let param = params[p];
|
|
let value = 0;
|
|
for(let i in d['windows']) {
|
|
if(i == 0) {
|
|
continue;
|
|
}
|
|
value += Math.abs(d['windows'][i-1]['params'][param] - d['windows'][i]['params'][param]);
|
|
}
|
|
paramValues[param] = value / (d['windows'].length - 1);
|
|
}
|
|
return paramValues;
|
|
}
|
|
|
|
var checkboxWrapperEl = document.getElementById("checkboxes");
|
|
var d1ParamExpressiveness = getExpressivenessPerParam(d1, facialParameters);
|
|
var d2ParamExpressiveness = getExpressivenessPerParam(d2, facialParameters);
|
|
var d3ParamExpressiveness = getExpressivenessPerParam(d3, facialParameters);
|
|
for(var i in facialParameters){
|
|
let param = facialParameters[i];
|
|
var labelEl = document.createElement('label');
|
|
var checkboxEl = document.createElement('input');
|
|
var spanEl = document.createElement('span');
|
|
checkboxEl.type = "checkbox";
|
|
checkboxEl.checked = defaultFacialParameters.indexOf(param) > -1;
|
|
checkboxEl.id = "check_"+param;
|
|
checkboxEl.addEventListener('change',function(a){drawGraphs();});
|
|
labelEl.appendChild(checkboxEl);
|
|
|
|
spanEl.innerHTML = param;
|
|
labelEl.appendChild(spanEl);
|
|
|
|
var spanColourEl = document.createElement('span');
|
|
spanColourEl.style.background = paramColours[param];
|
|
spanColourEl.innerHTML = " ";
|
|
spanColourEl.classList.add('legendColour');
|
|
labelEl.appendChild(spanColourEl);
|
|
|
|
checkboxWrapperEl.appendChild(labelEl);
|
|
|
|
labelEl.title = "Expressiveness: " + d1ParamExpressiveness[param] + ", " + d2ParamExpressiveness[param] + ", " + d3ParamExpressiveness[param];
|
|
}
|
|
|
|
var imgwrapEl = document.getElementById("imgwrap");
|
|
var plot1Div = document.getElementById('plot1-div');
|
|
var plot2Div = document.getElementById('plot2-div');
|
|
// var plot3Div = document.getElementById('plot3-div');
|
|
var stats1Div = document.getElementById('plot1-stats');
|
|
var stats2Div = document.getElementById('plot2-stats');
|
|
// var stats3Div = document.getElementById('plot3-stats');
|
|
|
|
function drawGraphs(){
|
|
params = getCheckedParams();
|
|
drawGraph("talk1", plot1Div, d1, params, stats1Div);
|
|
drawGraph("talk2", plot2Div, d2, params, stats2Div);
|
|
//~ drawGraph("talk3", plot3Div, d3, params);
|
|
}
|
|
|
|
|
|
function drawGraph(id, targetEl, d, params, statsEl) {
|
|
|
|
statsEl.innerHTML = "Total expressiveness: " + getExpressivenessForParams(d, params);
|
|
|
|
var data = [
|
|
/* {
|
|
name: "Mean",
|
|
x: d['windows'].map(function(w){return w['start'];}),
|
|
y: d['windows'].map(function(w){return _.mean(_.filter(w['params'], function(v, param){return params.indexOf(param) > -1}));}),
|
|
//~ error_y: {
|
|
//~ type: 'data',
|
|
//~ array: d['windows'].map(function(w){return w['stddev'];}),
|
|
//~ visible: true
|
|
//~ },
|
|
type: 'scatter',
|
|
line: {
|
|
//~ color: 'rgb(55, 128, 191)',
|
|
width: 5
|
|
}
|
|
}*/
|
|
];
|
|
|
|
|
|
var avgV = {};
|
|
for(var i in params){
|
|
param = params[i];
|
|
paramValues = d['windows'].map(function(w){return w['params'][param];});
|
|
data.push({
|
|
name: param,
|
|
x: d['windows'].map(function(w){return w['start'];}),
|
|
y: paramValues,
|
|
type: 'scatter',
|
|
line: {
|
|
color: paramColours[param],
|
|
width: 1.5
|
|
}
|
|
});
|
|
avgV[param] = _.mean(paramValues);
|
|
}
|
|
|
|
var devFunction = function(w){
|
|
let dev = 0;
|
|
for(var i in params){
|
|
let param = params[i];
|
|
dev += Math.pow(avgV[param] - w['params'][param], 2);
|
|
}
|
|
return Math.sqrt(dev);
|
|
};
|
|
data.push({
|
|
name: "Deviation",
|
|
x: d['windows'].map(function(w){return w['start'];}),
|
|
y: d['windows'].map(devFunction),
|
|
//~ error_y: {
|
|
//~ type: 'data',
|
|
//~ array: d['windows'].map(function(w){return w['stddev'];}),
|
|
//~ visible: true,
|
|
//~ color: '#f00'
|
|
//~ },
|
|
type: 'scatter',
|
|
line: {
|
|
color: '#800080',
|
|
width: 5
|
|
}
|
|
});
|
|
|
|
valFun = function(w){return w['params']['smile'] - (w['params']["innerBrowRaise"]+ w['params']["browFurrow"]+ w['params']["noseWrinkle"]+ w['params']["upperLipRaise"]+ w['params']["lipCornerDepressor"]+ w['params']["chinRaise"]+ w['params']["lipPress"]+ w['params']["lipSuck"])/8;};
|
|
|
|
var posWindow = _.maxBy(d['windows'], valFun);
|
|
var negWindow = _.minBy(d['windows'], valFun);
|
|
var devWindow = _.maxBy(d['windows'], devFunction);
|
|
var avgWindow = _.minBy(d['windows'], devFunction);
|
|
var diffWindow = _.maxBy(d['windows'], function(w){return w['stddev'];});
|
|
var concensusWindow = _.minBy(d['windows'], function(w){return w['stddev'];});
|
|
|
|
var annotations = [
|
|
//~ {
|
|
//~ x: posWindow['start'],
|
|
//~ y: posWindow['params']['smile'],
|
|
//~ xref: 'x',
|
|
//~ yref: 'y',
|
|
//~ text: 'Most positive moment',
|
|
//~ font: {color: 'gray'},
|
|
//~ showarrow: true,
|
|
//~ arrowhead: 7,
|
|
//~ ax: 0,
|
|
//~ ay: -40
|
|
//~ },
|
|
//~ {
|
|
//~ x: negWindow['start'],
|
|
//~ y: _.max([negWindow['params']["innerBrowRaise"], negWindow['params']["browFurrow"], negWindow['params']["noseWrinkle"], negWindow['params']["upperLipRaise"], negWindow['params']["lipCornerDepressor"], negWindow['params']["chinRaise"], negWindow['params']["lipPress"], negWindow['params']["lipSuck"]]),
|
|
//~ xref: 'x',
|
|
//~ yref: 'y',
|
|
//~ text: 'Most negative moment',
|
|
//~ font: {color: 'gray'},
|
|
//~ showarrow: true,
|
|
//~ arrowhead: 7,
|
|
//~ ax: 0,
|
|
//~ ay: -40
|
|
//~ },
|
|
{
|
|
x: devWindow['start'],
|
|
y: devFunction(devWindow),
|
|
xref: 'x',
|
|
yref: 'y',
|
|
text: 'Most deviant moment',
|
|
font: {color: 'gray'},
|
|
showarrow: true,
|
|
arrowhead: 7,
|
|
ax: 0,
|
|
ay: -40
|
|
},
|
|
{
|
|
x: avgWindow['start'],
|
|
y: devFunction(avgWindow),
|
|
xref: 'x',
|
|
yref: 'y',
|
|
text: 'Most average moment',
|
|
font: {color: 'gray'},
|
|
showarrow: true,
|
|
arrowhead: 7,
|
|
ax: 0,
|
|
ay: -40
|
|
},
|
|
{
|
|
x: avgWindow['start'],
|
|
y: devFunction(avgWindow),
|
|
xref: 'x',
|
|
yref: 'y',
|
|
text: 'Most average moment',
|
|
font: {color: 'gray'},
|
|
showarrow: true,
|
|
arrowhead: 7,
|
|
ax: 0,
|
|
ay: -40
|
|
},
|
|
{
|
|
x: diffWindow['start'],
|
|
y: devFunction(diffWindow),
|
|
xref: 'x',
|
|
yref: 'y',
|
|
text: 'Least concensus',
|
|
font: {color: 'gray'},
|
|
showarrow: true,
|
|
arrowhead: 7,
|
|
ax: 0,
|
|
ay: -40
|
|
},
|
|
{
|
|
x: concensusWindow['start'],
|
|
y: devFunction(concensusWindow),
|
|
xref: 'x',
|
|
yref: 'y',
|
|
text: 'Most concensus',
|
|
font: {color: 'gray'},
|
|
showarrow: true,
|
|
arrowhead: 7,
|
|
ax: 0,
|
|
ay: -40
|
|
}
|
|
]
|
|
|
|
var layout = {
|
|
//~ dragmode: 'zoom',
|
|
|
|
annotations: annotations,
|
|
|
|
//~ boxmode: 'group',
|
|
margin: {
|
|
r: 10,
|
|
t: 10,
|
|
b: 18,
|
|
l: 20
|
|
},
|
|
showlegend: false,
|
|
xaxis: {
|
|
autorange: true,
|
|
//~ domain: [0, 1],
|
|
//~ range: ['2017-01-03 12:00', '2017-02-15 12:00'],
|
|
//~ rangeslider: {range: ['2017-01-03 12:00', '2017-02-15 12:00']},
|
|
//~ title: 'Date',
|
|
type: 'date'
|
|
},
|
|
yaxis: {
|
|
autorange: true,
|
|
domain: [0, 1],
|
|
//~ range: [114.609999778, 137.410004222],
|
|
type: 'linear'
|
|
}
|
|
};
|
|
|
|
Plotly.newPlot(targetEl.id, data, layout,{displayModeBar: false});
|
|
|
|
//~ targetEl.on('plotly_click', function(data){
|
|
//~ console.log(data);
|
|
//~ var pts = '';
|
|
//~ for(var i=0; i < data.points.length; i++){
|
|
//~ pts = 'x = '+data.points[i].x +'\ny = '+
|
|
//~ data.points[i].y.toPrecision(4) + '\n\n';
|
|
//~ }
|
|
//~ alert('Closest point clicked:\n\n'+pts);
|
|
//~ });
|
|
|
|
targetEl.on('plotly_hover', function (data){
|
|
let HTML = "";
|
|
var points = data.points[0],
|
|
pointNum = points.pointNumber;
|
|
console.log(d);
|
|
for(let i in d['windows'][pointNum]['frames']) {
|
|
console.log(pointNum, d['windows'][pointNum]['frames'][i], data);
|
|
//~ imgEl.src = "/images.php?i="+d['windows'][pointNum]['frames'][i]+"¶ms="+params.join() + "&nr=" + d['outputNr'] ;
|
|
HTML+= "<div>"+d['windows'][pointNum]['frames'][i]+"<img src=\"/images.php?i="+d['windows'][pointNum]['frames'][i]+"¶ms="+params.join() + "&nr=" + d['outputNr'] +"\"></div>" ;
|
|
}
|
|
imgwrapEl.innerHTML = HTML;
|
|
|
|
var audio = new Audio('output/'+d['outputNr']+'/'+d['windows'][pointNum]['startFrame']+'.wav');
|
|
audio.play();
|
|
|
|
//~ Plotly.Fx.hover('plot-div',[
|
|
//~ { curveNumber:0, pointNumber:pointNum },
|
|
//~ { curveNumber:1, pointNumber:pointNum },
|
|
//~ { curveNumber:2, pointNumber:pointNum },
|
|
//~ ]);
|
|
});
|
|
//~ plotDiv.on('plotly_hover', function (eventdata){
|
|
//~ console.log(data);
|
|
//~ });
|
|
}
|
|
|
|
drawGraphs();
|
|
</script>
|
|
</body>
|
|
</html>
|