xxxxxxxxxx
528
//cocossd class: https://github.com/tensorflow/tfjs-models/blob/master/coco-ssd/src/classes.ts
//ml5js code taken from https://github.com/ml5js/ml5-examples/tree/release/p5js/ObjectDetector
let video;
let pg;
let changeMode = false;
let flag1 = false;
let flag2 = false;
let flag3 = false;
let flag4 = false;
let objectDetector;
let sampleImage;
let processCheck = false;
let imageMask;
let objects = [];
let status;
let iMed, iReg, iLight, iBold;
let sceneNum = 0;
let uploadButton;
let uploadImage;
let check1, check2, nCheck1, nCheck2;
let button1, button2, sampleButton, button4, button5;
let downloadButton;
var colorArray = ['#FF0000', '#FF0000', '#FF0000', '#FF6633', '#FFB399', '#FF33FF', '#FFFF99', '#00B3E6', '#E6B333', '#3366E6', '#999966', '#99FF99', '#B34D4D', '#80B300', '#809900', '#E6B3B3', '#6680B3', '#66991A', '#FF99E6', '#CCFF1A', '#FF1A66', '#E6331A', '#33FFCC', '#66994D', '#B366CC', '#4D8000', '#B33300', '#CC80CC', '#E666B3', '#33991A', '#CC9999', '#B3B31A', '#00E680'];
function preload() {
iMed = loadFont('Inter-Medium.ttf');
iReg = loadFont('Inter-Regular.ttf');
iLight = loadFont('Inter-Light.ttf');
iBold = loadFont('Inter-Bold.ttf');
sampleImage = loadImage('ques-camera.png');
}
function setup() {
createCanvas(640, 650);
pixelDensity(1);
button1 = createButton('Learn more');
button1.position(width / 2-50, 550);
button1.mousePressed(changeBG);
button1.hide();
button2 = createButton('Start Camera');
button2.position(width / 2 - 50, 570);
button2.mousePressed(changeTC);
button2.hide();
sampleButton = createButton('View Sample');
sampleButton.position(width / 2 - 50, 585);
sampleButton.mousePressed(changeSample);
sampleButton.hide();
button4 = createButton('Upload Image');
button4.position(width / 2 - 50, 570);
button4.mousePressed(changeUF);
button4.hide();
button5 = createButton('Process Image');
button5.position(450, 620);
button5.mousePressed(processImg);
button5.hide();
downloadButton = createButton('Download');
downloadButton.position(550, 620);
downloadButton.mousePressed(downloadImg);
downloadButton.hide();
uploadButton = createFileInput(uploadFile);
uploadButton.position(40, 620);
uploadButton.style('color', color(240));
uploadButton.hide();
check1 = createCheckbox('Okay, I agree', false);
check1.position(100, 500);
check1.style('color', color(240));
check1.style('font-family', iMed);
check1.changed(myCheckedEvent1);
check1.hide();
nCheck1 = createCheckbox('Sorry, I disagree', false);
nCheck1.position(100, 520);
nCheck1.style('color', color(240));
nCheck1.changed(myCheckedEventn1);
nCheck1.hide();
check2 = createCheckbox('Okay, I agree', false);
check2.position(350, 500);
check2.style('color', color(240));
check2.changed(myCheckedEvent2);
check2.hide();
nCheck2 = createCheckbox('Sorry, I disagree', false);
nCheck2.position(350, 520);
nCheck2.style('color', color(240));
nCheck2.changed(myCheckedEventn2);
nCheck2.hide();
}
function draw() {
background(220);
switch (sceneNum) {
case 0:
background(0);
if (millis() % 10 == 1) {
for (var i = 0; i < 100; i++) {
textSize(random(30));
push();
rotate(random(10));
text("?", random(height), random(width));
pop();
}
}
fill(255);
textFont(iMed);
textSize(40);
textAlign(CENTER);
text("Questioning Camera", width / 2, height / 2);
button1.show();
break;
case 1:
textAlign(LEFT);
background(100);
fill(255);
textFont(iMed);
textSize(18);
text("The Questioning Camera is camera which helps the viewer question what they see by augmenting the viewers vision with a critical lens.", 100, 60, 420, 100);
textSize(14);
textFont(iReg);
text("It does this by using a small machine learning model to categorise what the camera sees, and applies a layer of criticality. This is non-networked experience, which requires a one-time download of the machine learning model. There is no data exchange, and no tracking whatsoever. This page has a footprint of 0.41g of CO2.", 100, 180, 420, 190);
textSize(12);
textFont(iLight);
text("This experience requires the use of your device's camera. In order to use the 'Questiong Camera', you will need to grant permission to the web page. Are you okay with that?", 100, 350, 200, 150);
text("The 'Questiong Camera' also needs to download a machine learning model to work. This is a one-time 20MB download, post which there is no data exchange. Feel free to disconnect from the internet once the camera has loaded! Are you okay with that?", 350, 350, 200, 150);
check1.show();
nCheck1.show();
check2.show();
nCheck2.show();
if (flag1) {
nCheck1.hide();
} else {
nCheck1.show();
}
if (flag3) {
check1.hide();
} else {
check1.show();
}
if (flag2) {
nCheck2.hide();
} else {
nCheck2.show();
}
if (flag4) {
check2.hide();
} else {
check2.show();
}
if (flag1 && flag2) {
button2.show();
} else {
button2.hide();
}
if (flag3 && flag2) {
button4.show();
} else {
button4.hide();
}
if (flag1 && flag4 || flag3 && flag4) {
textAlign(CENTER);
text("Sorry, you won't be able to view the Questioning Camera!", width / 2, 570);
sampleButton.show();
} else {
sampleButton.hide();
}
break;
case 2:
background(100);
textSize(9);
if (!objectDetector) {
objectDetector = ml5.objectDetector('cocossd', modelReady);
video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
pg = createGraphics(width, height);
}
buttonSection();
topButtons();
if (changeMode) {
// image(pg, 0, 0);
if (status != undefined) {
image(pg, 0, 40)
for (let i = 0; i < objects.length; i++) {
textFont(iMed);
textAlign(LEFT);
textSize(11);
noStroke();
fill(colorArray[i]);
text(objects[i].label + " " + nfc(objects[i].confidence * 100.0, 2) + "%", objects[i].x + 10, objects[i].y + 15);
push()
blendMode(DIFFERENCE);
noFill();
// fill(255, 20);
strokeWeight(2);
stroke(255, 0, 0);
stroke(colorArray[i]);
rect(objects[i].x, objects[i].y, objects[i].width, objects[i].height, 10);
let labelTag = objects[i].label;
labelTag = labelTag.replace(" ", "_");
push();
blendMode(SCREEN);
for (var j = 0; j < questions[labelTag].length; j++) {
fill(255);
noStroke();
text(questions[labelTag][j], objects[i].x + 10, objects[i].y + 35 + (15 * j));
}
pop();
pop();
}
}
} else {
image(video, 0, 40);
}
break;
case 4:
background(0);
topButtons();
uploadButton.show();
if (processCheck) {
textFont(iMed);
textSize(20);
textAlign(CENTER);
text("Loading...", width / 2, height / 2);
}
if (status == true) {
image(uploadImage, 0, 40);
uploadImage.resize(width, 0);
for (let i = 0; i < objects.length; i++) {
textFont(iMed);
textAlign(LEFT);
textSize(11);
noStroke();
fill(colorArray[i]);
text(objects[i].label + " " + nfc(objects[i].confidence * 100.0, 2) + "%", objects[i].x + 10, objects[i].y + 15);
push();
blendMode(DIFFERENCE);
noFill();
// fill(255, 20);
strokeWeight(2);
stroke(255, 0, 0);
stroke(colorArray[i]);
rect(objects[i].x, objects[i].y, objects[i].width, objects[i].height, 10);
let labelTag = objects[i].label;
labelTag = labelTag.replace(" ", "_");
push();
blendMode(SCREEN);
for (var j = 0; j < questions[labelTag].length; j++) {
fill(255);
noStroke();
text(questions[labelTag][j], objects[i].x + 10, objects[i].y + 35 + (15 * j));
}
pop();
pop();
}
}
break;
case 5:
background(0);
topButtons();
image(sampleImage, 0, 40);
break;
}
}
function changeSample() {
sampleButton.hide();
sceneNum = 5;
check1.hide();
check2.hide();
nCheck1.hide();
nCheck2.hide();
}
function shutter() {
pg.image(video, 0, 0);
changeMode = true;
objectDetector.detect(pg, gotResult);
}
function changeBG() {
console.log("scene 0");
sceneNum += 1;
button1.hide();
}
function changeUF() {
sceneNum = 4;
button4.hide();
check1.hide();
check2.hide();
nCheck1.hide();
nCheck2.hide();
}
function changeTC() {
sceneNum += 1;
button2.hide();
check1.hide();
check2.hide();
nCheck1.hide();
nCheck2.hide();
}
function myCheckedEvent1() {
if (this.checked()) {
flag1 = true;
} else {
flag1 = false;
}
}
function myCheckedEventn1() {
if (this.checked()) {
flag3 = true;
} else {
flag3 = false;
}
}
function myCheckedEvent2() {
if (this.checked()) {
flag2 = true;
} else {
flag2 = false;
}
}
function myCheckedEventn2() {
if (this.checked()) {
flag4 = true;
} else {
flag4 = false;
}
}
function modelReady() {
console.log("model Ready!")
status = true;
}
// A function to run when we get any errors and the results
function gotResult(err, results) {
if (err) {
console.log(err);
}
// console.log(results)
objects = results;
}
function resetScreen() {
changeMode = false;
}
function buttonSection() {
textSize(14);
textFont(iMed);
//Shutter Button
noFill();
stroke(40);
strokeWeight(5);
ellipse(width / 2, 530 + 45, 50);
noStroke();
fill(240);
ellipse(width / 2, 530 + 45, 50);
textAlign(CENTER);
fill(255);
text('Shutter', width / 2, 575 + 45);
if (dist(mouseX, mouseY, width / 2, 530 + 45) < 20) {
fill(200);
ellipse(width / 2, 530 + 45, 50);
}
//Clear Button
noFill();
stroke(40);
strokeWeight(5);
ellipse(width / 2 - 200, 530 + 45, 30);
noStroke();
fill(40);
ellipse(width / 2 - 200, 530 + 45, 30);
fill(255);
text('Clear', width / 2 - 200, 565 + 45);
if (dist(mouseX, mouseY, width / 2 - 200, 530 + 45) < 15) {
fill(200);
ellipse(width / 2 - 200, 530 + 45, 30);
}
//Save Button
noFill();
stroke(40);
strokeWeight(5);
ellipse(width / 2 + 200, 530 + 45, 30);
noStroke();
fill(140);
ellipse(width / 2 + 200, 530 + 45, 30);
fill(255);
text('Save', width / 2 + 200, 565 + 45);
if (dist(mouseX, mouseY, width / 2 + 200, 530 + 45) < 15) {
fill(200);
ellipse(width / 2 + 200, 530 + 45, 30);
}
}
function topButtons() {
noStroke();
fill(0);
rect(0, 0, 640, 40);
if (dist(mouseX, mouseY, 620, 20) < 15) {
fill(150, 0, 0);
rect(600, 0, 100, 40);
fill(250);
textAlign(CENTER);
textSize(20);
textFont(iMed);
text('X', 620, 28);
} else {
fill(250);
rect(600, 0, 100, 40);
fill(150, 0, 0);
textSize(20);
textFont(iMed);
textAlign(CENTER);
text('X', 620, 28);
}
textSize(18);
textFont(iBold);
textAlign(LEFT);
fill(255);
text("Questioning Camera", 20, 25);
stroke(255);
strokeWeight(2);
line(0, 41, width, 41);
noStroke();
}
function processImg() {
button5.hide();
processCheck = true;
if (!objectDetector) {
objectDetector = ml5.objectDetector('cocossd', modelReady1);
} else {
console.log("model Ready!");
modelReady1();
}
}
function modelReady1() {
console.log("model Ready!");
status = true;
console.log('Detecting')
objectDetector.detect(uploadImage, gotResult);
}
function uploadFile(file) {
if (file.type === 'image') {
processCheck = false;
status = false;
uploadImage = loadImage(file.data);
image(uploadImage, 0, 0);
// pg.image(uploadImage, 0, 0);
button5.show();
downloadButton.show();
} else {
// imageWrite = null;
fill(255);
text("Please upload an image!", 50, 230)
}
}
function downloadImg() {
save("Questioning-Camera.png");
}
function mousePressed() {
if (dist(mouseX, mouseY, width / 2, 530 + 45) < 25) {
fill(140);
shutter();
}
if (dist(mouseX, mouseY, width / 2 - 200, 530 + 45) < 15) {
fill(140);
resetScreen();
}
if (dist(mouseX, mouseY, 620, 20) < 15) {
fill(51);
uploadButton.hide();
downloadButton.hide();
sceneNum = 1;
}
if (dist(mouseX, mouseY, width / 2 + 200, 530 + 45) < 15) {
fill(140);
save("Questioning-Camera.png");
}
}