xxxxxxxxxx
231
/* INSTRUCTIONS
Use RIGHT/LEFT arrow keys to control how often the cropping happens. (The range is 10x per second to 1x per 10 seconds.)
Use UP/DOWN arrow keys to control how loud you have to be to make it crop very close.
Click the canvas to manually freeze and unfreeze the image. Image will stay frozen until you click mouse again.
Press SPACEBAR to autofreeze based on how often the cropping happens.
*/
// Set-up posenet
let poseNet;
let joints = ['nose', 'leftEye', 'rightEye', 'leftEar', 'rightEar', 'leftShoulder', 'rightShoulder', 'leftWrist', 'rightWrist'];
let joint = 'nose';
// Video
let input, output;
let crop = {};
let wc = {};
let scl = 1;
let cw, ch;
// Rate of cropping
let rate = 100;
// Range of level mapping
let range = 0.5;
// Video stream constraints
let ocs = {
video: {
width: 1280,
height: 720
},
audio: false
};
let ics = {
video: {
width: 320,
height: 180
},
audio: false
};
// Scaling cropped video to window
let H2W;
// Scaling of input to output video
let I2O = ocs.video.width / ics.video.width;
// Audio
let mic;
// Freeze
let m_freeze = false;
let a_freeze = true;
let int;
function setup() {
createCanvas(1280, 720);
// Calculate center of window
wc = {
x: width / 2,
y: height / 2
};
// Calculate ratios of window dimensions
H2W = height / width;
// Set up output video
output = createCapture(ocs, (stream) => {
console.log("GOT OUTPUT STREAM");
});
output.hide();
// Set up input video
input = createCapture(ics, (stream) => {
console.log("GOT INPUT STREAM");
});
input.hide();
// Set up posenet
poseNet = ml5.poseNet(input, modelReady);
poseNet.on('pose', bodiesTracked);
// Center the image
imageMode(CENTER);
// Sound
mic = new p5.AudioIn();
mic.start();
// Set up cropping
setupInterval();
}
function setupInterval() {
// Clear old one
if (int) clearInterval(int);
// Make it freeze
int = setInterval(() => {
let level = mic.getLevel();
//if (level > 0.25) freeze();
if (level > 0.01) update(level);
if (a_freeze) display();
}, rate);
}
function display() {
background('white');
//background(0);
//image(output, 0, 0, 1280, 720);
//translate(video.width, 0);
image(output, wc.x, wc.y, width, height, crop.x, crop.y, crop.w, crop.h);
}
function modelReady() {
console.log("Model has loaded!");
}
function draw() {
let unfrozen = !a_freeze && !m_freeze;
if (unfrozen) display();
}
// Found bodies
function bodiesTracked(bodies) {
//console.log("Found "+ bodies.length + " bodies.");
for (let body of bodies) {
bodyTracked(body.pose);
}
}
function bodyTracked(_body) {
body = _body;
}
// Manually freeze
function mousePressed() {
m_freeze = !m_freeze;
if(m_freeze) a_freeze = false;
}
function keyPressed() {
// Turn on auto-freezing
if(key == 'a') {
a_freeze = !a_freeze;
if(a_freeze) m_freeze = false;
return;
}
switch (keyCode) {
case UP_ARROW:
range += 0.1;
break;
case DOWN_ARROW:
range -= 0.1;
break;
case RIGHT_ARROW:
rate += 100;
break;
case LEFT_ARROW:
rate -= 100;
break;
}
// Constrain the range
range = constrain(range, 0, 1);
// Constrain the rate
rate = constrain(rate, 100, 10000);
// Update rate setup
setupInterval();
console.log("RANGE: ", range);
console.log("RATE: ", rate);
}
function resize() {
cw = output.width * scl;
ch = cw * H2W;
crop.w = cw;
crop.h = ch;
}
function update(level) {
if (body == null) return;
// Randomize
joint = body[random(joints)];
//let range = map(level, 0, 0.5, 1, 0);
scl = map(level, 0, range, 1, 0);
//console.log(level, scl);
// Resize crop
resize();
// Update mid-point
crop.x = joint.x * I2O;
crop.y = joint.y * I2O;
recenter();
}
function recenter() {
// Re-center
let hw = crop.w / 2;
let hh = crop.h / 2;
let left = crop.x - hw;
let right = (crop.x + hw) - output.width;
let top = crop.y - hh;
let bottom = (crop.y + hh) - output.height;
// Shift center around to fit video crop inside video
if (left < 0) crop.x -= left;
else if (right > 0) crop.x -= right;
if (top < 0) crop.y -= top;
else if (bottom > 0) crop.y -= bottom;
// Shift x,y to corner of cropped area
crop.x -= crop.w / 2;
crop.y -= crop.h / 2;
}