xxxxxxxxxx
187
/*
Resources
https://openprocessing.org/sketch/853212
https://openprocessing.org/sketch/854150
*/
const MAX_TRAIL_COUNT = 30;
let colorScheme = ["#0A1B28", "#071F43", "#357D7E", "#35EEEE", "#919DF0"];
let trail = [];
let particles = [];
let segmenter;
let img; // output
let segmentationData = [];
let snowflakes = [];
function setup() {
createCanvas(windowWidth, windowHeight);
noCursor();
//setupMoveNet();
cam = createCapture(VIDEO, camReady);
//cam.size(windowWidth, windowHeight);
cam.hide();
pixelDensity(1); // ***
img = createGraphics(windowWidth, windowHeight);
}
function draw() {
updateMoveNet();
getSegmentation();
blendMode(BLEND);
background(255);
push();
translate(img.width, 0);
scale(-1,1);
image(img, 0, 0); // this img is the output from the bodySegmentation.
pop();
blendMode(SCREEN);
//drawMirroredCam(0, 0, width, height); //this will cover the output so it should be removed.
//cam.hide(); // I wouldn't do this here. It can be done in setup();
// let x = map(pose.rightWrist.x, 0, cam.width, 0, width);
// let y = map(pose.rightWrist.y, 0, cam.height, 0, height);
// fill(255);
// ellipse(x, y, 30, 30);
// Trim end of trail.
trail.push([pose.rightWrist.x, pose.rightWrist.y]);
let removeCount = 1;
if (mouseIsPressed && mouseButton == CENTER) {
removeCount++;
}
for (let i = 0; i < removeCount; i++) {
if (trail.length == 0) {
break;
}
if (mouseIsPressed || trail.length > MAX_TRAIL_COUNT) {
trail.splice(0, 1);
}
}
// Spawn particles.
if (trail.length > 1) {
let mouse = new p5.Vector(pose.rightWrist.x, pose.rightWrist.y);
mouse.sub(pmouseX, pmouseY);
if (mouse.mag() > 5) {
mouse.normalize();
for (let i = 0; i < 3; i++) {
particles.push(
new Particle(pose.rightWrist.x, pose.rightWrist.y, mouse.x, mouse.y)
);
}
}
}
// Move and kill particles.
for (let i = particles.length - 1; i > -1; i--) {
particles[i].move();
if (particles[i].vel.mag() < 0.1) {
particles.splice(i, 1);
}
}
// Draw trail.
drawingContext.shadowColor = color(0, 125, 255);
for (let i = 0; i < trail.length; i++) {
let mass = i * 1.5;
drawingContext.shadowBlur = mass;
stroke(0);
strokeWeight(mass);
point(trail[i][0], trail[i][1]);
}
// Draw particles.
for (let i = 0; i < particles.length; i++) {
let p = particles[i];
let mass = p.mass * p.vel.mag() * 0.6;
drawingContext.shadowColor = color(colorScheme[p.colorIndex]);
drawingContext.shadowBlur = mass;
stroke(0);
strokeWeight(mass);
point(p.pos.x, p.pos.y);
stroke(255);
strokeWeight(mass * 0.05);
point(p.pos.x, p.pos.y);
}
// generate snowflakes
snowflakes.push(new Snowflake(random(width), 0));
// update and display the snowflakes
for (let s of snowflakes) {
s.fall(0.1);
s.move();
s.checkSegmentation(segmentationData);
s.display();
s.updateLifespan();
}
// remove the particles once they are done
for (let i = snowflakes.length - 1; i >= 0; i--) {
if (snowflakes[i].isDone) {
snowflakes.splice(i, 1);
}
}
drawingContext.shadowBlur = 0;
}
function camReady() {
console.log("Webcam Ready!");
loadPoseDetectionModel();
loadBodySegmentationModel();
}
async function loadBodySegmentationModel() {
const model = bodySegmentation.SupportedModels.MediaPipeSelfieSegmentation;
const segmenterConfig = {
runtime: 'mediapipe',
solutionPath: 'https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation'
// or 'base/node_modules/@mediapipe/selfie_segmentation' in npm.
};
segmenter = await bodySegmentation.createSegmenter(model, segmenterConfig);
console.log("Model Loaded!");
}
async function getSegmentation() {
if (segmenter == undefined) return;
const segmentationConfig = {
flipHorizontal: false
};
const segmentation = await segmenter.segmentPeople(cam.elt, segmentationConfig);
if (segmentation.length > 0) {
let result = await segmentation[0].mask.toImageData();
segmentationData = result.data;;
}
const foregroundThreshold = 0.5;
const backgroundBlurAmount = 10;
const edgeBlurAmount = 3;
const flipHorizontal = false;
const inputCanvas = cam.elt;
const outputCanvas = img.elt;
bodySegmentation.drawBokehEffect(
outputCanvas, inputCanvas, segmentation, foregroundThreshold, backgroundBlurAmount,
edgeBlurAmount, flipHorizontal);
}