xxxxxxxxxx
223
// p5.js + BRFv4 face tracker (via handsfree.js)
//
// We're using a specific version of handsfree.js
// that has the (commercial, trial) BRFv4 tracker baked in:
// https://unpkg.com/handsfree@4.0.2/dist/handsfree.js
// more information about the BRFv4 tracker is at:
// https://github.com/Tastenkunst/brfv4_javascript_examples
var myHandsfree;
function preload() {
peng = loadModel('penguin09_15_19.obj');
}
function setup() {
createCanvas(640, 480,WEBGL);
video = createCapture(VIDEO);
video.size(width, height);
// Create a new poseNet method with a single detection
poseNet = ml5.poseNet(video);
// This sets up an event that fills the global variable "poses"
// with an array every time new poses are detected
poseNet.on('pose', function(results) {
poses = results;
});
// Hide the video element, and just show the canvas
video.hide();
var myConfig = {
hideCursor: true
};
myHandsfree = new Handsfree(myConfig);
myHandsfree.start();
}
function draw() {
background(255, 0, 0);
push();
translate(-width/2,-height/2);
//image(video, 0, 0, width, height);
updateKeypoints();
drawKeypoints();
if (myHandsfree.isTracking) {
if (myHandsfree.pose.length > 0) {
var face0 = myHandsfree.pose[0].face;
var nPoints = face0.vertices.length;
fill(255);
beginShape();
for (var i = 0; i < 33; i += 2) {
vertex(face0.vertices[i+0],face0.vertices[i+1]);
}
for (var i = 52; i > 33; i -= 2) {
vertex(face0.vertices[i+0],face0.vertices[i+1]);
}
endShape(CLOSE);
fill(0);
beginShape();
vertex(face0.vertices[6],face0.vertices[7]);
vertex(face0.vertices[132],face0.vertices[133]);
vertex(face0.vertices[26],face0.vertices[27]);
vertex(face0.vertices[124],face0.vertices[125]);
endShape(CLOSE);
beginShape();
vertex(face0.vertices[58],face0.vertices[59]);
for (var i = 62; i < 71; i += 2) {
vertex(face0.vertices[i+0],face0.vertices[i+1]);
}
endShape(CLOSE);
beginShape();
for (var i = 96; i < 119; i += 2) {
vertex(face0.vertices[i+0],face0.vertices[i+1]);
}
endShape(CLOSE);
beginShape();
for (var i = 72; i < 83; i += 2) {
vertex(face0.vertices[i+0],face0.vertices[i+1]);
}
endShape(CLOSE);
beginShape();
for (var i = 84; i < 95; i += 2) {
vertex(face0.vertices[i+0],face0.vertices[i+1]);
}
endShape(CLOSE);
fill(255, 255, 0);
avgX = 0;
avgY = 0;
for (var i = 0; i < nPoints; i += 2) {
var x = face0.vertices[i + 0];
var y = face0.vertices[i + 1];
avgX += x;
avgY +=y;
//ellipse(x, y, 5, 5);
}
avgX /= nPoints/2;
avgY /= nPoints/2;
fill(255,0,0);
ellipse(avgX,avgY,5,5);
// Rotations of the head, in radians
var rx = face0.rotationX; // pitch
var ry = face0.rotationY; // yaw
var rz = face0.rotationZ; // roll
pop();
translate(-150,0);
drawModel(rx, ry, rz, face0);
}
}
}
// Adapted from the ml5 PoseNet example for p5.js.
// Uses p5.js v.0.9.0
// Uses ml5.js v.0.3.1
// September 2019
let video;
let poseNet;
let poses = [];
let mostRecentKeypoints = [];
let numKeypoints = 17;
//---------------------------------------------
function updateKeypoints() {
if (poses.length <= 0) {
// If there are no poses, ignore.
return;
} else {
// Otherwise, update the points.
var pose = poses[0].pose;
var keypoints = pose.keypoints;
for (var i = 0; i < keypoints.length; i++) {
var ithNewKeypoint = keypoints[i].position;
mostRecentKeypoints[i] = ithNewKeypoint;
}
}
}
//---------------------------------------------
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
fill(255, 0, 0);
for (var i = 5; i < mostRecentKeypoints.length; i++) {
keypoint = mostRecentKeypoints[i];
ellipse(keypoint.x, keypoint.y, 9, 9);
}
fill(255);
if (mostRecentKeypoints.length > 11){
beginShape();
vertex(mostRecentKeypoints[5].x,mostRecentKeypoints[5].y);
vertex(mostRecentKeypoints[6].x,mostRecentKeypoints[6].y);
vertex(mostRecentKeypoints[12].x,mostRecentKeypoints[12].y);
vertex(mostRecentKeypoints[11].x,mostRecentKeypoints[11].y);
endShape(CLOSE);
fill(255);
strokeWeight(10);
line(mostRecentKeypoints[5].x,mostRecentKeypoints[5].y,
mostRecentKeypoints[7].x,mostRecentKeypoints[7].y);
line(mostRecentKeypoints[6].x,mostRecentKeypoints[6].y,
mostRecentKeypoints[8].x,mostRecentKeypoints[8].y);
line(mostRecentKeypoints[8].x,mostRecentKeypoints[8].y,
mostRecentKeypoints[10].x,mostRecentKeypoints[10].y);
line(mostRecentKeypoints[7].x,mostRecentKeypoints[7].y,
mostRecentKeypoints[9].x,mostRecentKeypoints[9].y);
dX = (mostRecentKeypoints[5].x - mostRecentKeypoints[6].x);
dY = (mostRecentKeypoints[5].y - mostRecentKeypoints[6].y);
neckBaseX = mostRecentKeypoints[6].x + dX/2;
neckBaseY = mostRecentKeypoints[6].y + dY/2;
line(neckBaseX,neckBaseY,
mostRecentKeypoints[0].x,mostRecentKeypoints[0].y);
}
}
function drawModel(rx, ry, rz, face0) {
let locX = mouseX - height / 2;
let locY = mouseY - width / 2;
pointLight(255, 255, 255, locX, locY, 200);
scale(20);
push();
rotateZ(radians(180));
rotateX(rx);
rotateY(-ry);
rotate(-rz);
noStroke();
//normalMaterial();
normalMaterial(250);
//fill(10, 110, 240);
model(peng);
pop();
}
/*
// Alternate configuration
*/