xxxxxxxxxx
218
var lastCapture = -1;
var saveCount = 1;
var handsfree;
let capture;
var faceMask;
var mouthMask;
var mouthOpenMask;
var eyeMask;
var webcam;
var smile = false;
var debug = false;
function setup() {
// Setup canvas
createCanvas(640, 480);
background(0);
noStroke();
ellipseMode(CENTER);
// Setup Handsfree
setupHandsfree();
capture = createCapture(VIDEO);
capture.hide();
capture.size(640, 480);
faceMask = createGraphics(640, 480);
mouthMask = createGraphics(640, 480);
mouthOpenMask = createGraphics(640, 480);
eyeMask = createGraphics(640, 480);
webcam = createGraphics(640, 480);
}
function draw() {
if (!debug) {
translate(width, 0);
scale(-1, 1);
}
// fill(0, 0, 0, 10);
// rect(0, 0, width, height);
clear();
webcam.image(capture, 0, 0, 640, 480);
if (debug) image(webcam, 0, 0);
if (handsfree.isTracking) {
if (handsfree.pose.length > 0) {
var face0 = handsfree.pose[0].face;
var nDataPieces = face0.vertices.length;
faceMask.clear();
mouthMask.clear();
mouthOpenMask.clear();
eyeMask.clear();
if (debug) {
fill(255, 0, 0);
for (var i = 0; i < nDataPieces; i += 2) {
var x = face0.vertices[i + 0];
var y = face0.vertices[i + 1];
text(i / 2, x, y);
}
}
//mouth
var bounds = [100, 50, width - 100, height - 50];
var mouthVertices = face0.vertices.slice(96, 120);
var r1 = getMask(webcam, mouthMask, mouthVertices);
fitToBounds(r1, bounds, mouthVertices);
//mouth open
var openVertices = face0.vertices.slice(120, 136);
var newMask = fitToBounds(null, bounds, openVertices);
var r = pgMask(webcam, newMask);
image(r, 0, 0);
}
}
}
function getMask(content, graphic, vertices) {
graphic.beginShape();
for (var i = 0; i < vertices.length; i += 2) {
var x = vertices[i + 0];
var y = vertices[i + 1];
graphic.vertex(x, y);
}
graphic.endShape();
return pgMask(content, graphic);
}
function fitToBounds(graphic, bounds, vertices) {
var rect = [-1, -1, -1, -1];
for (var i = 0; i < vertices.length; i += 2) {
var x = vertices[i + 0];
var y = vertices[i + 1];
if (rect[0] == -1 || x < rect[0]) rect[0] = x;
if (rect[1] == -1 || y < rect[1]) rect[1] = y;
if (rect[2] == -1 || x > rect[2]) rect[2] = x;
if (rect[3] == -1 || y > rect[3]) rect[3] = y;
}
push();
var xScale = (bounds[2] - bounds[0]) / (rect[2] - rect[0]);
var yScale = (bounds[3] - bounds[1]) / (rect[3] - rect[1]);
var xCenter = (rect[2] + rect[0]) / 2;
var yCenter = (rect[3] + rect[1]) / 2;
var sc = min(xScale, yScale);
translate(width / 2, height / 2);
scale(sc);
translate(-xCenter, -yCenter);
if (graphic) image(graphic, 0, 0);
pop();
var result = createGraphics(width, height);
result.push();
result.translate(width / 2, height / 2);
result.scale(sc);
result.translate(-xCenter, -yCenter);
result.beginShape();
for (var i = 0; i < vertices.length; i += 2) {
var x = vertices[i + 0];
var y = vertices[i + 1];
result.vertex(x, y);
}
result.endShape();
result.pop();
return result;
return [xScale * (rect[0] - xCenter) + width / 2,
yScale * (rect[1] - yCenter) + height / 2,
xScale * (rect[2] - xCenter) + width / 2,
yScale * (rect[3] - yCenter) + height / 2
];
}
// From https://editor.p5js.org/mikima/sketches/SkEXyPvpf
function pgMask(_content, _mask) {
//Create the mask as image
var img = createImage(_mask.width, _mask.height);
img.copy(_mask, 0, 0, _mask.width, _mask.height, 0, 0, _mask.width, _mask.height);
//load pixels
img.loadPixels();
for (var i = 0; i < img.pixels.length; i += 4) {
// 0 red, 1 green, 2 blue, 3 alpha
// Assuming that the mask image is in grayscale,
// the red channel is used for the alpha mask.
// the color is set to black (rgb => 0) and the
// alpha is set according to the pixel brightness.
var v = img.pixels[i];
img.pixels[i] = 0;
img.pixels[i + 1] = 0;
img.pixels[i + 2] = 0;
img.pixels[i + 3] = v;
}
img.updatePixels();
//convert _content from pg to image
var contentImg = createImage(_content.width, _content.height);
contentImg.copy(_content, 0, 0, _content.width, _content.height, 0, 0, _content.width, _content.height);
// create the mask
contentImg.mask(img)
// return the masked image
return contentImg;
}
function setupHandsfree() {
// Initialize Handsfree.js
// @see: https://github.com/labofoz/handsfree.js
handsfree = new Handsfree({
hideCursor: true,
// Set to false to hide the webcam
debug: false
})
handsfree.start()
// This creates a plugin,
// which is accessible through: handsfree.plugin['drawingDemo']
handsfree.use({
// The name of the plugin; can be anything
name: 'drawingDemo',
// Called on the first frame of a click
onMouseDown(face) {
fill(random(255), random(255), random(255))
this.capture(face)
smile = true;
},
onMouseUp(face) {
smile = false;
},
// // Called on subsequent frames of a click (before release)
onMouseDrag(face) {
if (second() != lastCapture) {
this.capture(face);
}
},
// Draw a point based on where the cursor is
capture(face) {
// var name = "=";
// for (i = 0; i < saveCount; i++) {
// name += ")";
// }
// saveCanvas(name + ".png");
// saveCount++;
// lastCapture = second();
}
})
}