// recent work from my @VicUniWgtn 3rd year media design students that combines @nulhom's dlib face library with @p5xjs var canvasWidth = 960; var canvasHeight = 500; var button; var curRandomSeed; var mainFace; var faceImages = []; var curFaceIndex = 0; var curTrainIndex = 0; var curValidIndex = 0; var main_canvas; var faceSelector; var drawFaceCheckbox; var faceGuideCheckbox; var facePointsCheckbox; var sliders = []; var NUM_SLIDERS = 12; var sliderTint; var selfieData = [] var trainData = {} var trainDataKeys = [] var trainValues = {} var validData = {} var validDataKeys = [] var faceMapping = null; var loadedSelfieData = []; function preload () { loadedSelfieData = loadJSON('sample_images.json'); trainData = loadJSON('training_images.json'); trainValues = loadJSON('training_values.json'); validData = loadJSON('testing_images.json'); } var allEmbeddingsTree; var allEmbeddings = []; var embeddingDimensions; var curNeighbors = []; function squaredDistance(a, b) { var sum = 0; var length = 128; for(var i=0; i<128; i++) { var diff = a[i] - b[i]; sum += diff * diff; } // print(a.length,diff); // print(sum, a==b); return sum; } var haveStarted = false; function setup () { var loadedSelfieDataArray = Object.values(loadedSelfieData); Array.prototype.unshift.apply(selfieData, loadedSelfieDataArray); // create the drawing canvas, save the canvas element main_canvas = createCanvas(canvasWidth, canvasHeight); main_canvas.parent('canvasContainer'); curRandomSeed = int(focusedRandom(0, 100)); mainFace = new Face(); littleFace = new Face(); for(var i=0; i lastSwapTime + millisPerSwap) { lastSwapTime = millis(); // changeRandomSeed(); } resetFocusedRandom(curRandomSeed); noStroke(); background(bg_color1); var textDisplay = "unknown"; var params = []; for(var i=0; i i) && // (data.embedding[i] != null) && // (typeof data.embedding[i].length !== 'undefined') && // (data.embedding[i].length == 128)) { // // print("Using embedding ", i) // var curEmbedding = data.embedding[i]; // results = getAverageSettingsFrom(curEmbedding); // settings = results[0]; // } push(); translate(x2, y1) translate(scale_x*data_mean[0], scale_y*data_mean[1]); scale(scale_x*data_scale, scale_y*data_scale); rotate(degrees(data_angle)); strokeWeight(1/data_scale); mainFace.setProperties(settings); if (do_draw_face) { mainFace.draw(shifted_positions); } pop(); } if(do_train) { textDisplay = "Train: " + curKey; } else { textDisplay = ""; } } else if (mode == 'NearestNeighbors') { // var keys = Object.keys(trainData); var curKey = trainDataKeys[curTrainIndex]; var data = trainData[curKey]; // Displays the image at its actual size at point (0,0) var img = data.image var x1 = (width/4-250/2); var y1 = (height/3-250/2); image(img, x1, y1, 250, 250); if (curKey in trainValues) { fill(0, 200, 0); } else { fill(200, 0, 0); } ellipse(x1+250/2, y1+250+15, 10, 10); var y2 = (3*height/4-80/2); for(var i=0; i<4; i++) { // var keys = Object.keys(trainData); var curKey = curNeighbors[i]; var nearData = trainData[curKey]; // Displays the image at its actual size at point (0,0) var img = nearData.image var x2 = (width/4 - 200 + i*100); image(img, x2, y2, 80, 80); } for(var i=0; i<1; i++) { // get array of face marker positions [x, y] format var positions = data.landmarks[i]; var shifted_positions = JSON.parse(JSON.stringify(positions)) var data_mean = [0.0, 0.0]; var data_scale = 1.0; var data_angle = 0.0; if ('transform' in positions) { data_mean = positions.transform.center; data_scale = positions.transform.scale; data_angle = positions.transform.angle; delete shifted_positions.transform } var scale_x = 400.0 / img.width; var scale_y = 400.0 / img.height; Object.keys(positions).forEach(function(key) { if (key=='transform') { return; } var curSection = positions[key]; var shiftedSection = shifted_positions[key]; for (var i=0; i= 0) { otherKeys.splice(index, 1); } var answerSlot = int(focusedRandom(0, 4)); var answerKeys = Array(4); for(var j=0; j<4; j++) { if(j == answerSlot) { curKey = trainDataKeys[curTrainIndex]; } else { var guess = int(focusedRandom(0, otherKeys.length)); // if(otherKeys.length > j+2) { // while(answerKeys.indexOf(guess) == -1) { // guess = int(focusedRandom(0, otherKeys.length)); // } // } curKey = otherKeys[guess]; } answerKeys[j] = curKey; // print("Answer", j, " is ", curKey); var x2 = (width/2 - 200 + j*100); var settings = params; if (valid_mode && j == answerSlot) { var curEmbedding = data.embedding[0]; results = getAverageSettingsFrom(curEmbedding); settings = results[0]; var validTrainKeys = results[1]; } else if (curKey in trainValues) { settings = trainValues[curKey]; } push(); translate(x2, y2); translate(scale_x*data_mean[0], scale_y*data_mean[1]); scale(scale_x*data_scale, scale_y*data_scale); rotate(degrees(data_angle)); strokeWeight(1/data_scale); if (typeof settings !== 'undefined') { littleFace.setProperties(settings); } littleFace.draw(shifted_positions); pop(); if(quiz_done && guessed_answer == (j+1)) { push(); translate(x2, y2); noFill(); strokeWeight(4); if(guessed_answer == (answerSlot+1)) { stroke(0, 100, 0); } else { stroke(100, 0, 0); } rect(-10, -10, 100, 100); pop(); } } if(quiz_done) { for(var j=0; j<4; j++) { if (valid_mode && (answerSlot+1) == (j+1)) { for(var k=0; k<4; k++) { var curKey = validTrainKeys[k]; var nearData = trainData[curKey]; // Displays the image at its actual size at point (0,0) var img = nearData.image var x2 = (width/2 - 200 + j*100 + (k%2)*40); var y4 = y3 + (int(k/2))*40; image(img, x2, y4, 40, 40); } } else { var curKey = answerKeys[j]; var nearData = trainData[curKey]; // Displays the image at its actual size at point (0,0) if (typeof nearData !== 'undefined') { var img = nearData.image var x2 = (width/2 - 200 + j*100); image(img, x2, y3, 80, 80); } } } } } if(valid_mode) { if(quiz_done) { textDisplay = "InterpolationQuiz: hit spacebar to continue"; } else { textDisplay = "InterpolationQuiz: hit 1, 2, 3, or 4 to guess"; } } else { if(quiz_done) { textDisplay = "TrainingQuiz: hit spacebar to continue"; } else { textDisplay = "TrainingQuiz: hit 1, 2, 3, or 4 to guess"; } } } fill(255); textSize(32); textAlign(CENTER); text(textDisplay, width/2, height-12); } function keyTyped() { if(!haveStarted) { return; } var mode = faceSelector.value(); if (key == 'q' && mode != 'Faces') { faceSelector.value('Faces'); } else if (key == 'w' && mode != 'Train') { faceSelector.value('Train'); } else if (key == 'e' && mode != 'NearestNeighbors') { faceSelector.value('NearestNeighbors'); } else if (key == 'r' && mode != 'TrainingQuiz') { faceSelector.value('TrainingQuiz'); } else if (key == 't' && mode != 'InterpolationQuiz') { faceSelector.value('InterpolationQuiz'); } if (key == ' ' && (mode == 'TrainingQuiz' || mode == 'InterpolationQuiz') && quiz_done) { quiz_done = false; if(mode == 'TrainingQuiz') { curTrainIndex = (curTrainIndex + 1) % trainDataKeys.length; } else { curValidIndex = (curValidIndex + 1) % validDataKeys.length; } changeRandomSeed(); } else if ((mode == 'TrainingQuiz' || mode == 'InterpolationQuiz') && quiz_done == false) { if(key >= '1' && key <= '4') { guessed_answer = key - '0'; quiz_done = true; } } if (key == 's') { saveCurrentSettings(); } else if (key == 'i') { interpolateCurrent(); } else if (key == 'l') { loadCurrentSettings(); } if (key == '!') { saveBlocksImages(); } else if (key == '@') { saveBlocksImages(true); } } function interpolateCurrent() { var curNeighborSettings = []; for(var i=0; i<4; i++) { neighborKey = curNeighbors[i] if(neighborKey in trainValues) { curNeighborSettings.push(trainValues[neighborKey]); } } for(var i=0; i 0) { settings = curNeighborSettings[0]; for(var i=0; i 0) { settings = curNeighborSettings[0]; for(var i=0; i