xxxxxxxxxx
82
/*
Face Confetti with Facemesh
This example uses Facemesh to analyse a face via the webcam and creates a face confetti effect.
If you move your face the confetti will follow you for some time.
Built with Facemesh model from ml5js and p5js
Created by Tom-Lucas Säger 2021
*/
let video;
let predictions = [];
let face = [];
//The canvas is setup, we us HSB as the color mode, giving it a 4th argument for the opacity.
//We also reduce the pixelDensity to make the effect more performant.
//Facemesh is initiated
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
colorMode(HSB, 360, 100, 100, 1);
pixelDensity(1);
noStroke();
const facemesh = ml5.facemesh(video, modelReady);
facemesh.on('predict', gotResults);
video.hide();
}
//The webcam image is drawn and we call our functions that calculate and draw the keypoints.
function draw() {
image(video, 0, 0, width, height)
calcNewKeypoints();
drawKeypoints();
}
function modelReady() {
console.log('model ready')
}
//Once the results are in we store them in our variable predictions
function gotResults(results) {
predictions = results;
}
//
function calcNewKeypoints() {
for (let i = 0; i < predictions.length; i += 1) {
const keypoints = predictions[i].scaledMesh;
//An array point is created that will store the x, y, z values at one specific point.
let point = [];
for (let j = 0; j < keypoints.length; j += 1) {
const [x, y, z] = keypoints[j];
point.push([{
x: x,
y: y,
z: z
}]);
}
//Once all keypoints are in point we write them into a new array called face. They make up one "face"
face.push(point);
//If the face array has more then 16 points we delete the oldest one. This will create the trail effect
if (face.length > 16) {
face.shift();
}
}
}
//Now we can draw the last 16 faces to the canvas
function drawKeypoints() {
for (let i = 0; i < face.length; i++) {
// We use i to give the drawn faces a fade effect later
let opacity = map(i, 0, 15, 0, 1);
let pose = face[i];
//We draw every point from the array, we use our z value to give the point a specific color
//and use opacity, which we defined earlier
for (let j = 0; j < pose.length; j++) {
let poses = pose[j][0]
fill(abs(poses.z * 15 % 360), 50, 100, opacity);
ellipse(poses.x, poses.y, 5);
}
}
}