From e7bee9beb4835c80b1a950e134081c4ec05cffe5 Mon Sep 17 00:00:00 2001 From: amcc Date: Mon, 13 May 2024 07:33:32 +0100 Subject: [PATCH] simplified lerp and video flip --- .DS_Store | Bin 8196 -> 10244 bytes examples/.DS_Store | Bin 6148 -> 6148 bytes mediaPipe/.DS_Store | Bin 0 -> 6148 bytes mediaPipe/poseLandmarks/sketch.js | 75 +++++++++++++++++++----------- mediaPipe/poseLandmarks/style.css | 6 ++- 5 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 mediaPipe/.DS_Store diff --git a/.DS_Store b/.DS_Store index ea0c5caf31971a67542a238b4977aa668c6a0ae7..c215eebe2889fea8e609c3f62cee6c5ccaf6ce91 100644 GIT binary patch delta 756 zcmZp1XbF&DU|?W$DortDU{C-uIe-{M3-C-V6q~50Cf{4TF>Oa|<>WPGg_g zAh?;GgN36WB+J5}$B@pD$xs4Q0Tg3kdQ!RqSuQu<#U&{xKM5$t@gyyHQ|i~Fj;Qh} zc;yQ+AhrYbFfe`C0HW9#^y(SP7>XH^8S)uY7*dg~2TH3$lpw1>cEpMNE&huqf*k=g z2vrrrDY#XE9mEX`50Fzp;WPPwn8;)WfyXS&xfM|$&Sq)BqpTbsydr}uE**6Qiil1A zC&tAF5tz&;uEfGz0M+Ip&R@^Tkjsz?^hYK`B0~U>EI{=Uqhx0^&>k$RkbSkvdp6%A zNYG+ciSQY^%6e3*k;9u&Dgoq0R-glO7)%+m7>ZGXx`Mp}RTkMnyB@9I9Rl<|x(b9t zpep3hlps5Rp~7KfVGo-iGsqdh^vMk*TtR7cW8rt^$^0^bB218!s{xW`WMD7=(US{g OdN=NWD)U^OS C`8Iq2 diff --git a/examples/.DS_Store b/examples/.DS_Store index 0c71d2feae7705a3276586f4eec7a20e5eb66c31..cda5018ef6e4ee1cea034bb81ef7f86178f89419 100644 GIT binary patch delta 275 zcmZoMXfc@JFUrHfz`)4BAi%(o&yd29nv-rAoSeVeka;;{JxGe3L64z~p_m~VSvt1> zC<6lOK#Zm$H{Zo2DJMS(D8sSusD0YrsYe~LsY)TJN{}J7AOqwYm~{e^4VlCRATET6 zF@1IPnjFIrTNG4S%tC>landy7O*HL_;K=Of=e?XU-n1q{fQ}1M!Z40+CVza_?U=(LdnLi+@0WgW=8Y z1ZikXy%JE2FK4tup`Ckn^5jH}a={OB+Wg7z?KBdYxUb@thK zd%al4=>C#1?k{K5!t}IHJ>)*6Cz{a&y#~BP5k^Nez~}(|QL>Wb!=k*5nhISrj8dyB z#7)+D!*y1uFW=WS_vz?7KRTnPocS{<$zi1CKgOMyu6@pey$_pzX7qCYFSqZ{i{~td z@pC7NF%tO)J`&nE!X_fN;beS=+NuJoKvIEi zcUa~1|1x|3pCsv#DxeB%lmey{G=n-ylC^cEI9_W#cni+Paj`>7K_knt?eJ230Jny7 X9(RDgVC)bhF#Qp*GH9a;{HX$S3Mk3* literal 0 HcmV?d00001 diff --git a/mediaPipe/poseLandmarks/sketch.js b/mediaPipe/poseLandmarks/sketch.js index 55328f1..93b227f 100644 --- a/mediaPipe/poseLandmarks/sketch.js +++ b/mediaPipe/poseLandmarks/sketch.js @@ -24,32 +24,22 @@ function setup() { function draw() { background(255); + lerpPositions(); - // flip the webcam image so it looks like a mirror - push(); - scale(-1, 1); // mirror webcam - image(capture, -capture.width, 0); // draw webcam - scale(-1, 1); // unset mirror - pop(); + // draw the webcam + image(capture, 0, 0); // mediaPipe.landmarks contains an array of people if (mediaPipe.landmarks.length > 0) { - if (!madeClone) { - lerpLandmarks = JSON.parse(JSON.stringify(mediaPipe.landmarks)); - madeClone = true; - } - // l[start].x = simpLerp(l[start].x, p[start].x, lerpRate); - mediaPipe.landmarks.forEach((person, index) => { - let p = mediaPipe.landmarks[index]; - let l = lerpLandmarks[index]; + mediaPipe.landmarks.forEach((person, personIndex) => { // sometimes we don't have a person for a bit, if not then return - if (!l || !p) return; // each person contains an array of positions of each body part - person.forEach((part, index) => { + person.forEach((part, partIndex) => { // get the lerped position for detected body parts - l[index].x = lerp(l[index].x, part.x, lerpRate); - l[index].y = lerp(l[index].y, part.y, lerpRate); + + const x = lerpLandmarks[personIndex][partIndex].x; + const y = lerpLandmarks[personIndex][partIndex].y; // draw a circle on each body part // non lerped @@ -58,24 +48,57 @@ function draw() { // lerped fill("cyan"); - circle(...getFlipPos(l[index]), 10); + // circle(...getFlipPos(l[index]), 10); + circle(x, y, 10); }); }); } } -// return flipped x and y positions -function getFlipPos(part, xAdd = 0, yAdd = 0) { - return [ - capture.width - part.x * capture.width + xAdd, - part.y * capture.height + yAdd, - ]; +// create and set lerp positions +// this function creates a deep clone of the mediaPipe.landmarks if it doesn't exist already +// then it lerps the positions of the landmarks +// lerp works by moving a percentage of the way from one position to another +function lerpPositions(realPostions = true) { + // check we're getting landmarks + // we're probably already checking, but just in case... + if (mediaPipe.landmarks.length > 0) { + if (!madeClone) { + // deep clone the mediaPipe.landmarks + lerpLandmarks = JSON.parse(JSON.stringify(mediaPipe.landmarks)); + madeClone = true; + } + } + + // realpositions variable controls whether we set the capture width and height or not + // by default we make landmarks relative to the capture width and height + // if false it will be 0 to 1 + + let lerpWidth = realPostions ? capture.width : 1; + let lerpHeight = realPostions ? capture.height : 1; + + mediaPipe.landmarks.forEach((person, personIndex) => { + let p = mediaPipe.landmarks[personIndex]; + let l = lerpLandmarks[personIndex]; + // sometimes we don't have a person for a bit, if not then return + if (!l || !p) return; + // each person contains an array of positions of each body part + person.forEach((part, partIndex) => { + // get the lerped position for detected body parts + l[partIndex].x = lerp(l[partIndex].x, part.x * lerpWidth, lerpRate); + l[partIndex].y = lerp(l[partIndex].y, part.y * lerpHeight, lerpRate); + // draw a circle on each body part + }); + }); } // this function helps to captuer the webcam in a way that ensure video is loaded -// before we start predicting mediaPipe.landmarks. Creatcapture has a callback which is +// before we start predicting mediaPipe.landmarks. Createcapture has a callback which is // only called when the video is correctly loaded. At that point we set the dimensions // and start predicting mediaPipe.landmarks + +// N.B. the video is flipped horizontally in the CSS + function captureWebcam() { capture = createCapture( { diff --git a/mediaPipe/poseLandmarks/style.css b/mediaPipe/poseLandmarks/style.css index 9386f1c..f239776 100644 --- a/mediaPipe/poseLandmarks/style.css +++ b/mediaPipe/poseLandmarks/style.css @@ -1,7 +1,11 @@ -html, body { +html, +body { margin: 0; padding: 0; } canvas { display: block; } +video { + transform: scaleX(-1); +}