xxxxxxxxxx
143
// This sketch demonstrates the use of ml5js to draw shapes over the face or body
//
// It is based on this "Hour of Code" Coding Train video
// by Daniel Shiffman: https://youtu.be/EA3-k9mnLHs
//
// See our step-by-step tutorial:
// https://makeabilitylab.github.io/physcomp/communication/ml5js-serial
//
// Reference for the ml5js PoseNet implementation:
// https://ml5js.org/reference/api-PoseNet/
//
// By Jon E. Froehlich
// @jonfroehlich
// http://makeabilitylab.io/
//
let pHtmlMsg;
let serialOptions = { baudRate: 115200 };
let serial;
let video;
let poseNet;
let currentPoses;
let poseNetModelReady = false;
function setup() {
createCanvas(640, 480);
// Setup Web Serial using serial.js
serial = new Serial();
serial.on(SerialEvents.CONNECTION_OPENED, onSerialConnectionOpened);
serial.on(SerialEvents.CONNECTION_CLOSED, onSerialConnectionClosed);
serial.on(SerialEvents.DATA_RECEIVED, onSerialDataReceived);
serial.on(SerialEvents.ERROR_OCCURRED, onSerialErrorOccurred);
// If we have previously approved ports, attempt to connect with them
serial.autoConnectAndOpenPreviouslyApprovedPort(serialOptions);
// Add in a lil <p> element to provide messages. This is optional
pHtmlMsg = createP("Click anywhere on this page to open the serial connection dialog");
pHtmlMsg.style('color', 'white');
// ml5js PoseNet initialization
video = createCapture(VIDEO);
video.hide(); // hide raw video (feel free to comment in/out to see effect)
poseNet = ml5.poseNet(video, onPoseNetModelReady); //call onPoseNetModelReady when ready
poseNet.on('pose', onPoseDetected); // call onPoseDetected when pose detected
}
/**
* Callback function called by ml5.js PoseNet when the PoseNet model is ready
* Will be called once and only once
*/
function onPoseNetModelReady() {
print("The PoseNet model is ready...");
poseNetModelReady = true;
}
/**
* Callback function called by ml5.js PosetNet when a pose has been detected
*/
function onPoseDetected(poses) {
print("On new poses detected!");
currentPoses = poses;
if(currentPoses){
let strHuman = " human";
if(currentPoses.length > 1){
strHuman += 's';
}
text("We found " + currentPoses.length + strHuman);
}
}
function draw() {
background(100);
if(!poseNetModelReady){
textSize(32);
textAlign(CENTER);
fill(255);
noStroke();
text("Waiting for PoseNet model to load...", width/2, height/2);
}
image(video, 0, 0); // draw the video to the screen at 0,0
if(currentPoses){
for(let human of currentPoses){
fill("red"); // red nose
noStroke();
circle(human.pose.nose.x, human.pose.nose.y, 40);
}
}
}
/**
* Callback function by serial.js when there is an error on web serial
*
* @param {} eventSender
*/
function onSerialErrorOccurred(eventSender, error) {
console.log("onSerialErrorOccurred", error);
pHtmlMsg.html(error);
}
/**
* Callback function by serial.js when web serial connection is opened
*
* @param {} eventSender
*/
function onSerialConnectionOpened(eventSender) {
console.log("onSerialConnectionOpened");
pHtmlMsg.html("Serial connection opened successfully");
}
/**
* Callback function by serial.js when web serial connection is closed
*
* @param {} eventSender
*/
function onSerialConnectionClosed(eventSender) {
console.log("onSerialConnectionClosed");
pHtmlMsg.html("onSerialConnectionClosed");
}
/**
* Callback function serial.js when new web serial data is received
*
* @param {*} eventSender
* @param {String} newData new data received over serial
*/
function onSerialDataReceived(eventSender, newData) {
console.log("onSerialDataReceived", newData);
pHtmlMsg.html("onSerialDataReceived: " + newData);
}
/**
* Called automatically by the browser through p5.js when mouse clicked
*/
function mouseClicked() {
if (!serial.isOpen()) {
serial.connectAndOpen(null, serialOptions);
}
}