xxxxxxxxxx
132
let video;
let detector;
let skeletonJointNames;
let poses = [];
function setup() {
createCanvas(windowWidth, windowHeight);
initSkeletonJointNames();
video = createCapture(VIDEO, initModel);
video.hide();
}
function draw() {
drawBackground();
for (let pose of poses) {
drawKeypoints(pose);
drawSkeleton(pose);
}
}
function drawBackground() {
clear();
push();
// The next two lines change the coordinate system so that the image is
// mirrored left to right.
translate(video.width, 0);
scale(-1, 1);
// Copy the webcam image onto the canvas.
image(video, 0, 0);
pop();
}
function drawKeypoints(pose) {
for (let keypoint of pose.keypoints) {
if (keypoint.score > 0.5 && !isEyeCorner(keypoint)) {
let x = video.width - keypoint.x;
let y = keypoint.y;
// Label the keypoint.
// This is helpful during development.
// You may want to comment out the call to text() in your presentation code.
fill(255);
textSize(12);
text(keypoint.name, x, y);
// Draw a circle at the keypoint position
noStroke();
fill(255, 0, 0);
ellipse(x, y, 10, 10);
}
}
}
function drawSkeleton(pose) {
for (let [name1, name2] of skeletonJointNames) {
let keypoint1 = findKeypoint(pose, name1);
let keypoint2 = findKeypoint(pose, name2);
if (min(keypoint1.score, keypoint2.score) > 0.5) {
stroke(0, 0, 255);
line(video.width - keypoint1.x, keypoint1.y, video.width - keypoint2.x, keypoint2.y);
}
}
}
/*
* Functions that initialize and receive data from BlazePose
*/
function initModel() {
let model = poseDetection.SupportedModels.BlazePose;
let detectorConfig = {
runtime: 'tfjs', // 'mediapipe', 'tfjs'
modelType: 'full' // 'lite', 'full', 'heavy'
};
poseDetection.createDetector(model, detectorConfig).then(d => {
detector = d;
getPose();
});
}
function getPose() {
detector.estimatePoses(video.elt).then(p => {
poses = p;
getPose();
})
}
/*
* Functions that initialize the skeleton joint names, and tell what kind of
* feature a keypoint is.
*/
function initSkeletonJointNames() {
skeletonJointNames = [];
for (let side of ['left', 'right']) {
for (let chain of [['shoulder', 'elbow', 'wrist'], ['hip', 'knee', 'ankle', 'heel']]) {
for (let i = 1; i < chain.length; i++) {
let p1 = chain[i - 1];
let p2 = chain[i];
let name1 = `${side}_${p1}`;
let name2 = `${side}_${p2}`;
skeletonJointNames.push([name1, name2]);
}
}
for (let finger of ['pinky', 'index', 'thumb']) {
skeletonJointNames.push([`${side}_wrist`, `${side}_${finger}`]);
}
}
}
function findKeypoint(pose, name) {
return pose.keypoints.find(keypoint => keypoint.name === name);
}
function isEyeCorner(keypoint) {
return keypoint.name.endsWith('eye_outer') || keypoint.name.endsWith('eye_inner');
}
function isFingerJoint(keypoint) {
return keypoint.name.endsWith('pinky') || keypoint.name.endsWith('index') || keypoint.name.endsWith('thumb');
}
function isFacialFeature(keypoint) {
return keypoint.name.match(/nose|eye|ear|mouth/);
}
function isSkeletalJoint(keypoint) {
return !isFacialFeature(keypoint);
}