xxxxxxxxxx
303
// A regression using MobileNet, ml5.js, p5js. Based on:
// https://editor.p5js.org/ml5/sketches/FeatureExtractor_Image_Regression
let featureExtractor;
let regressor;
let video;
let statusString = "STATUS_ADD_SAMPLES";
let trainingLoss;
let nSamples = 0;
let predictionValue01;
let windowOpen; //how open the window is
let roomFill; //how full the room is
let projectile;
let attacking;
let timeStart;
let flyingSound;
let splatSound;
let smashSound;
let music;
let static;
let hitSound;
let closefilter;
let paused;
let scene;
let ease = new p5.Ease();
function preload() {
flyingSound = loadSound("Sounds/falling.wav");
splatSound = loadSound("Sounds/splat.wav");
smashSound = loadSound("Sounds/smash.mp3");
music = loadSound("Sounds/music.wav");
static = loadSound("Sounds/static.wav");
hitSound = loadSound("Sounds/hit.wav");
}
function attack() {
flyingSound.play();
projectile = 0;
attacking = true;
timeStart = millis();
}
//--------------------------------------
function setup() {
createCanvas(320, 240);
video = createCapture(VIDEO);
video.hide();
attacking = false;
windowOpen = 0;
closefilter = new p5.LowPass();
closefilter.freq(20);
flyingSound.disconnect();
smashSound.disconnect();
splatSound.disconnect();
music.disconnect();
flyingSound.connect(closefilter);
smashSound.connect(closefilter);
splatSound.connect(closefilter);
music.connect(closefilter);
paused = false;
//music.loop();
music.setVolume(0.05);
splatSound.setVolume(3);
hitSound.setVolume(3);
static.loop();
projectile = 0;
roomFill = 0;
scene = 1;
featureExtractor = ml5.featureExtractor('MobileNet');
regressor = featureExtractor.regression(video);
}
//--------------------------------------
function draw() {
windowOpen = map(mouseX, 0, width, 0, 1);
static.setVolume(roomFill);
// ml5 stuff -------------------------------
background('red');
tint(255, 255, 255, 64);
image(video, 0, 0, 320, 240);
/*
// draw a very simple "slider"
noFill();
stroke(0);
rect(0, 0, width, 10);
var mx = mouseX;
if (predictionValue01) {
mx = map(predictionValue01, 0, 1, 0, width);
}
rect(mx, 0, 1, 10);
// draw a red circle whose X location is
// proportional to our predicted value
var positionX = width / 2;
if (predictionValue01) {
positionX = map(predictionValue01, 0, 1, 0, width);
windowOpen = predictionValue01;
}
noStroke();
fill(255, 0, 0);
ellipse(positionX, 120, 50, 50);
*/
// draw diagnostic/debug information
/*
fill('black');
var instructions = "Press s and adjust mouseX to add samples. \n";
instructions += "Press t to train model. \n";
instructions += "Press p to start predicting. \n";
text(instructions, 15, 30);
text("status: " + statusString, 15, 75);
text("nSamples: " + nSamples, 15, 90);
text("trainingLoss: " + trainingLoss, 15, 105);
var pStr = (predictionValue01) ? nf(predictionValue01, 1, 3) : "undefined";
text("prediction: " + pStr, 15, 120);
*/
// my stuff ---------------------------------
if (predictionValue01) {
if (!attacking && random() < 0.008 && !paused) {
attack();
}
if (attacking) {
projectile = map(millis() - timeStart, 0, 3800, 0, 1);
}
if (attacking && projectile >= 1) {
attacking = false;
if (windowOpen < 0.3) {
if (random() > 0.5)
splatSound.play();
else
smashSound.play();
flyingSound.stop();
} else {
hitSound.play();
roomFill += 0.15;
}
projectile = 0;
}
let openness = ease.adjustableCenterDoubleExponentialSigmoid(windowOpen, 0.9, 0.2);
closefilter.freq(map(openness, 0, 1, 830, 10000));
flyingSound.setVolume(map(openness, 0, 1, 0.2, 1) * projectile);
music.setVolume(map(openness, 0, 1, 0.0, 0.01));
roomFill += map(openness, 0, 1, 0.00005, -0.0005);
if (roomFill > 1)
roomFill = 1;
if (roomFill < 0)
roomFill = 0;
print(roomFill);
}
textAlign(CENTER);
if (scene == 1)
{
tint(255, 255, 255, 64);
text("point your webcam at a window",width/2,height/2);
text("press Enter",width/2,height/2 + 20);
}
else if (scene == 2)
{
background(0,255,0);
text("close the window all the way",width/2,height/2);
text("then press Enter",width/2,height/2 + 20);
}
else if (scene == 3)
{
background(0,0,255);
text("open the window all the way",width/2,height/2);
text("then press Enter",width/2,height/2 + 20);
}
else if (scene == 4)
{
background(255,255,0);
text("open the window halfway",width/2,height/2);
text("then press Enter",width/2,height/2 + 20);
}
else if (scene == 6)
{
background(255,0,255);
text("press Enter to begin",width/2,height/2);
}
else if (scene == 5)
{
background(0,255,255);
text("loading...",width/2,height/2);
if (nSamples == 6)
{
regressor.train(function(lossValue) {
if (lossValue) {
trainingLoss = lossValue;
statusString = "STATUS_TRAINING_MODEL";
} else {
statusString = "STATUS_DONE_TRAINING";
}
});
scene = 6;
}
}
else if (scene == 7)
{
background(0,255,255);
text("close your window to block oncoming baddies",width/2,height/2);
text("open it to let the air out",width/2,height/2 + 20);
}
}
//--------------------------------------
function keyPressed() {
if (keyCode == ENTER)
{
if (scene == 1) {
scene = 2;
} else if (scene == 2) {
regressor.addImage(0);
nSamples++;
regressor.addImage(0);
nSamples++;
scene = 3;
} else if (scene == 3) {
regressor.addImage(1);
nSamples++;
regressor.addImage(1);
nSamples++;
scene = 4;
} else if (scene == 4) {
regressor.addImage(0.5);
nSamples++;
regressor.addImage(0.5);
nSamples++;
scene = 5;
} else if (scene == 6) {
statusString = "STATUS_PREDICTING";
regressor.predict(gotResultsCallback);
scene = 7;
}
}
if (key == 's') { // add sample
var xValue = constrain(map(mouseX, 0, width, 0, 1), 0, 1);
regressor.addImage(xValue);
nSamples++;
} else if (key == 't') { // train the regressor
regressor.train(function(lossValue) {
if (lossValue) {
trainingLoss = lossValue;
statusString = "STATUS_TRAINING_MODEL";
} else {
statusString = "STATUS_DONE_TRAINING";
}
});
} else if (key == 'p') { // initiate prediction
statusString = "STATUS_PREDICTING";
regressor.predict(gotResultsCallback);
} else if (key == 'b') {
paused = !paused;
}
}
//--------------------------------------
// Store the results, and restart the process.
function gotResultsCallback(err, result) {
if (err) {
console.error(err);
}
if (result && result.value) {
predictionValue01 = result.value;
regressor.predict(gotResultsCallback);
}
}