xxxxxxxxxx
333
let poseViz;
let m = 0.5;
let cnv, svg;
let camX = 640;
let camY = 480;
let svgX = 297;
let svgY = 420;
let camX2, camY2;
function setup() {
camY2 = (camY / camX) * (windowWidth / 2);
camX2 = windowWidth / 2;
svgY2 = windowHeight
svgX2 = svgX / svgY * svgY2;
createCanvas(windowWidth, windowHeight); // create Main Canvas
svg = createGraphics(svgX2, svgY2); // create SVG Canvas
poseViz = new PoseViz(svg);
}
function draw() {
background(200);
poseViz.drawCam();
poseViz.drawSVG();
image(svg, width/2 + ((width/2) - svgX2)/2,
(height - svgY2)/2);
}
function keyPressed() {
if (keyCode === ENTER) {
poseViz.clearSVG();
poseViz.toggle = true;
poseViz.X = 30;
poseViz.Y = 30;
}
}
class PoseViz {
constructor(svg) {
this.svg = svg; // SVG Canvas
this.s = 30;
this.X = 30;
this.Y = 30;
this.capture = createCapture(VIDEO);
this.capture.size(camX2, camY2);
this.capture.hide();
this.poseNet = ml5.poseNet(this.capture, this.modelLoaded);
let callback = this.gotPoses.bind(this); // bind the "this" to the callback
this.poseNet.on("pose", callback);
this.clearSVG();
this.toggle = true;
}
gotPoses(poses) {
if (poses.length > 0) {
// maybe add a condition to take only a high confidence pose
this.pose = poses[0].pose; // take the first pose and put in the global variable
}
}
modelLoaded() {
console.log("poseNet ready");
}
drawCam() {
rectMode(CENTER);
noFill();
push();
translate(width / 4 - camX2 / 2, (height - camY2) / 2);
image(this.capture, 0, 0, camX2, camY2);
stroke(255);
strokeWeight(2);
this.drawSinglePose(this.pose);
stroke(0, 255, 0);
strokeWeight(3);
rect(camX2 / 2, camY2 / 2, camY2 - 30, camY2 - 30);
pop();
}
drawSinglePose(pose, s = 1) {
// if (pose && frameCount % 3 == 0) {
if (pose) {
// get distance by getting distance between two shoulder
let R = pose.leftEye;
let L = pose.rightEye;
const d = dist(R.x, R.y, L.x, L.y); // i can then use d to handle size of dots
const circleSize = d / s;
// Keypoints
ellipse(pose.nose.x / s, pose.nose.y / s, circleSize * 3);
ellipse(pose.leftShoulder.x / s, pose.leftShoulder.y / s, circleSize);
ellipse(pose.rightShoulder.x / s, pose.rightShoulder.y / s, circleSize);
ellipse(pose.leftElbow.x / s, pose.leftElbow.y / s, circleSize);
ellipse(pose.rightElbow.x / s, pose.rightElbow.y / s, circleSize);
ellipse(pose.leftWrist.x / s, pose.leftWrist.y / s, circleSize);
ellipse(pose.rightWrist.x / s, pose.rightWrist.y / s, circleSize);
ellipse(pose.leftHip.x / s, pose.leftHip.y / s, circleSize);
ellipse(pose.rightHip.x / s, pose.rightHip.y / s, circleSize);
ellipse(pose.leftKnee.x / s, pose.leftKnee.y / s, circleSize);
ellipse(pose.rightKnee.x / s, pose.rightKnee.y / s, circleSize);
ellipse(pose.leftAnkle.x / s, pose.leftAnkle.y / s, circleSize);
ellipse(pose.rightAnkle.x / s, pose.rightAnkle.y / s, circleSize);
// Bones
line(
pose.leftAnkle.x / s,
pose.leftAnkle.y / s,
pose.leftKnee.x / s,
pose.leftKnee.y / s
);
line(
pose.leftKnee.x / s,
pose.leftKnee.y / s,
pose.leftHip.x / s,
pose.leftHip.y / s
);
line(
pose.leftHip.x / s,
pose.leftHip.y / s,
pose.leftShoulder.x / s,
pose.leftShoulder.y / s
);
line(
pose.leftShoulder.x / s,
pose.leftShoulder.y / s,
pose.leftElbow.x / s,
pose.leftElbow.y / s
);
line(
pose.leftElbow.x / s,
pose.leftElbow.y / s,
pose.leftWrist.x / s,
pose.leftWrist.y / s
);
line(
pose.rightAnkle.x / s,
pose.rightAnkle.y / s,
pose.rightKnee.x / s,
pose.rightKnee.y / s
);
line(
pose.rightKnee.x / s,
pose.rightKnee.y / s,
pose.rightHip.x / s,
pose.rightHip.y / s
);
line(
pose.rightHip.x / s,
pose.rightHip.y / s,
pose.rightShoulder.x / s,
pose.rightShoulder.y / s
);
line(
pose.rightShoulder.x / s,
pose.rightShoulder.y / s,
pose.rightElbow.x / s,
pose.rightElbow.y / s
);
line(
pose.rightElbow.x / s,
pose.rightElbow.y / s,
pose.rightWrist.x / s,
pose.rightWrist.y / s
);
line(
pose.leftHip.x / s,
pose.leftHip.y / s,
pose.rightHip.x / s,
pose.rightHip.y / s
);
line(
pose.leftShoulder.x / s,
pose.leftShoulder.y / s,
pose.rightShoulder.x / s,
pose.rightShoulder.y / s
);
}
}
drawPoseSVG(pose, s, v=createVector(0,0)) {
if (pose) {
// get distance by getting distance between two shoulder
let R = pose.leftEye;
let L = pose.rightEye;
const d = dist(R.x, R.y, L.x, L.y); // i can then use d to handle size of dots
const circleSize = d / s;
// Keypoints
this.svg.ellipse(pose.nose.x / s , pose.nose.y / s , circleSize * 3);
this.svg.ellipse(pose.leftShoulder.x / s, pose.leftShoulder.y / s , circleSize);
this.svg.ellipse(pose.rightShoulder.x / s, pose.rightShoulder.y / s , circleSize);
this.svg.ellipse(pose.leftElbow.x / s, pose.leftElbow.y / s , circleSize);
this.svg.ellipse(pose.rightElbow.x / s, pose.rightElbow.y / s , circleSize);
this.svg.ellipse(pose.leftWrist.x / s, pose.leftWrist.y / s , circleSize);
this.svg.ellipse(pose.rightWrist.x / s, pose.rightWrist.y / s , circleSize);
this.svg.ellipse(pose.leftHip.x / s, pose.leftHip.y / s , circleSize);
this.svg.ellipse(pose.rightHip.x / s, pose.rightHip.y / s , circleSize);
this.svg.ellipse(pose.leftKnee.x / s, pose.leftKnee.y / s , circleSize);
this.svg.ellipse(pose.rightKnee.x / s, pose.rightKnee.y / s , circleSize);
this.svg.ellipse(pose.leftAnkle.x / s, pose.leftAnkle.y / s , circleSize);
this.svg.ellipse(pose.rightAnkle.x / s, pose.rightAnkle.y / s , circleSize);
// Bones
this.svg.line(
pose.leftAnkle.x / s,
pose.leftAnkle.y / s,
pose.leftKnee.x / s,
pose.leftKnee.y / s
);
this.svg.line(
pose.leftKnee.x / s,
pose.leftKnee.y / s,
pose.leftHip.x / s,
pose.leftHip.y / s
);
this.svg.line(
pose.leftHip.x / s,
pose.leftHip.y / s,
pose.leftShoulder.x / s,
pose.leftShoulder.y / s
);
this.svg.line(
pose.leftShoulder.x / s,
pose.leftShoulder.y / s,
pose.leftElbow.x / s,
pose.leftElbow.y / s
);
this.svg.line(
pose.leftElbow.x / s,
pose.leftElbow.y / s,
pose.leftWrist.x / s,
pose.leftWrist.y / s
);
this.svg.line(
pose.rightAnkle.x / s,
pose.rightAnkle.y / s,
pose.rightKnee.x / s,
pose.rightKnee.y / s
);
this.svg.line(
pose.rightKnee.x / s,
pose.rightKnee.y / s,
pose.rightHip.x / s,
pose.rightHip.y / s
);
this.svg.line(
pose.rightHip.x / s,
pose.rightHip.y / s,
pose.rightShoulder.x / s,
pose.rightShoulder.y / s
);
this.svg.line(
pose.rightShoulder.x / s,
pose.rightShoulder.y / s,
pose.rightElbow.x / s,
pose.rightElbow.y / s
);
this.svg.line(
pose.rightElbow.x / s,
pose.rightElbow.y / s,
pose.rightWrist.x / s,
pose.rightWrist.y / s
);
this.svg.line(
pose.leftHip.x / s,
pose.leftHip.y / s,
pose.rightHip.x / s,
pose.rightHip.y / s
);
this.svg.line(
pose.leftShoulder.x / s,
pose.leftShoulder.y / s,
pose.rightShoulder.x / s,
pose.rightShoulder.y / s
);
}
}
clearSVG(){
this.svg.clear();
this.svg.background(20,80,250);
}
drawSVG() {
if (this.toggle && frameCount % 3 == 0) {
let padding = 30;
let stepX = 25;
let stepY = 40;
this.svg.noFill();
this.svg.stroke(255);
this.svg.strokeWeight(1);
this.svg.push();
let v = createVector(this.X, this.Y)
this.svg.translate(v.x, v.y)
this.drawPoseSVG(this.pose, this.s, v);
this.svg.pop();
this.X += stepX;
if (this.X > svgX2 - padding * 2 ) {
this.X = padding;
this.Y += stepY;
}
if (this.Y > svgY2 - padding) {
this.X = padding;
this.Y = padding;
this.toggle = false;
}
}
}
}