xxxxxxxxxx
135
//Smile score calculation adapted (and slightly modified) from https://github.com/Tastenkunst/brfv4_javascript_examples/blob/master/js/examples/face_tracking/smile_detection.js
let facemesh;
let video;
let predictions = [];
let isSmiling = false;
let smileFactor = 0;
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
video.size(width, height);
textSize(32);
facemesh = ml5.facemesh(video, modelReady);
// This sets up an event that fills the global variable "predictions"
// with an array every time new predictions are made
facemesh.on("predict", (results) => {
predictions = results;
});
// Hide the video element, and just show the canvas
video.hide();
}
function modelReady() {
console.log("Model ready!");
}
function draw() {
image(video, 0, 0, width, height);
push();
fill(0,255 - smileFactor*255)
rect(0,0,width, height)
pop();
// We can call both functions to draw all keypoints
drawKeypoints();
smileScore();
if (isSmiling) {
text("smiling", 10, 30);
}
}
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
for (let i = 0; i < predictions.length; i += 1) {
const keypoints = predictions[i].scaledMesh;
// Draw facial keypoints.
for (let j = 0; j < keypoints.length; j += 1) {
const [x, y] = keypoints[j];
fill(0, 255, 0);
ellipse(x, y, 5, 5);
}
}
}
function smileScore() {
var leftEyeInnerX = 0;
var leftEyeInnerY = 0;
var rightEyeInnerX = 0;
var rightEyeInnerY = 0;
var leftMouthCornerX = 0; //face0.vertices[48 * 2];
var leftMouthCornerY = 0; //face0.vertices[48 * 2 + 1];
var rightMouthCornerX = 0; //face0.vertices[54 * 2];
var rightMouthCornerY = 0; //face0.vertices[54 * 2 + 1];
for (let i = 0; i < predictions.length; i += 1) {
const keypoints = predictions[i].scaledMesh;
for (let j = 0; j < keypoints.length; j += 1) {
const [x, y] = keypoints[j];
if (j == 133) {
//left inner Eye
leftEyeInnerX = x;
leftEyeInnerY = y;
} else if (j == 362) {
//right inner Eye
rightEyeInnerX = x;
rightEyeInnerY = y;
} else if (j == 61) {
//left corner Mouth
leftMouthCornerX = x;
leftMouthCornerY = y;
} else if (j == 291) {
//right corner Mouth
rightMouthCornerX = x;
rightMouthCornerY = y;
}
}
fill(255, 0, 255);
ellipse(leftEyeInnerX, leftEyeInnerY, 5, 5);
ellipse(rightEyeInnerX, rightEyeInnerY, 5, 5);
ellipse(leftMouthCornerX, leftMouthCornerY, 5, 5);
ellipse(rightMouthCornerX, rightMouthCornerY, 5, 5);
var eyeDist = dist(
leftEyeInnerX,
leftEyeInnerY,
rightEyeInnerX,
rightEyeInnerY
);
var mouthWidth = dist(
leftMouthCornerX,
leftMouthCornerY,
rightMouthCornerX,
rightMouthCornerY
);
smileFactor = mouthWidth / eyeDist;
smileFactor -= 1.4; // 1.40 - neutral, 1.70 smiling
smileFactor = smileFactor*2;
if (smileFactor < 0.0) smileFactor = 0.0;
smileFactor = constrain(smileFactor, 0, 1)
console.log("smileFactor: " + smileFactor);
if (smileFactor > 0.5) {
isSmiling = true;
} else {
isSmiling = false;
}
}
}