├── .gitignore ├── FaceMorphing ├── FaceMorph │ ├── FaceMorph.pde │ ├── Morpher.pde │ ├── code │ │ ├── src │ │ │ └── triangulate │ │ │ │ ├── Edge.java │ │ │ │ ├── EdgePair.java │ │ │ │ ├── Pair.java │ │ │ │ ├── Triangle.java │ │ │ │ ├── TrianglePair.java │ │ │ │ └── Triangulate.java │ │ └── triangulate.jar │ └── data │ │ ├── jolie.jpg │ │ ├── pitt.jpg │ │ ├── points.txt │ │ └── points_backup.txt └── TextureDemo │ ├── TextureDemo.pde │ ├── Triangle.pde │ ├── code │ ├── src │ │ └── triangulate │ │ │ ├── Edge.java │ │ │ ├── EdgePair.java │ │ │ ├── Pair.java │ │ │ ├── Triangle.java │ │ │ ├── TrianglePair.java │ │ │ └── Triangulate.java │ └── triangulate.jar │ └── data │ ├── jolie.jpg │ ├── pitt.jpg │ ├── points.txt │ └── points_backup.txt ├── FaceOSC ├── BlinkParticles │ ├── BlinkParticles.pde │ ├── Particle.pde │ └── ParticleSystem.pde ├── FaceOSCAllPoints │ ├── FaceOSCAllPoints.pde │ └── MeshData.pde ├── FaceOSCDemo │ └── FaceOSCDemo.pde ├── FaceOSCPuppet │ ├── FaceOSCPuppet.pde │ ├── ImageMesh.pde │ ├── MeshData.pde │ ├── Triangle.pde │ └── data │ │ ├── matches.csv │ │ ├── obama.jpg │ │ └── pitt.jpg ├── FaceOSCTriangleMesh │ ├── FaceOSCTriangleMesh.pde │ ├── MeshData.pde │ ├── Triangle.pde │ └── data │ │ └── matches.csv └── triangulation_tests │ ├── MatchTriangles │ ├── MatchTriangles.pde │ ├── Mesh.pde │ ├── code │ │ ├── src │ │ │ └── triangulate │ │ │ │ ├── Edge.java │ │ │ │ ├── EdgePair.java │ │ │ │ ├── Pair.java │ │ │ │ ├── Triangle.java │ │ │ │ ├── TrianglePair.java │ │ │ │ └── Triangulate.java │ │ └── triangulate.jar │ ├── matches.csv │ ├── positions.csv │ └── triangles.csv │ ├── SaveMeshPoints │ ├── MeshData.pde │ ├── SaveMeshPoints.pde │ ├── code │ │ ├── src │ │ │ └── triangulate │ │ │ │ ├── Edge.java │ │ │ │ ├── EdgePair.java │ │ │ │ ├── Pair.java │ │ │ │ ├── Triangle.java │ │ │ │ ├── TrianglePair.java │ │ │ │ └── Triangulate.java │ │ └── triangulate.jar │ └── positions.csv │ └── SaveTriangles │ ├── SaveTriangles.pde │ ├── code │ ├── src │ │ └── triangulate │ │ │ ├── Edge.java │ │ │ ├── EdgePair.java │ │ │ ├── Pair.java │ │ │ ├── Triangle.java │ │ │ ├── TrianglePair.java │ │ │ └── Triangulate.java │ └── triangulate.jar │ ├── positions.csv │ ├── sketch.properties │ └── triangles.csv ├── FaceRekognition ├── FaceDetectExample │ ├── FaceDetectExample.pde │ └── data │ │ ├── obama.jpg │ │ ├── obamas.jpg │ │ ├── pitt-jolie.jpg │ │ ├── pitt.jpg │ │ └── superman.jpg ├── FaceRecognizeExample │ ├── FaceRecognizeExample.pde │ └── data │ │ ├── obama.jpg │ │ ├── obama2.jpg │ │ ├── obamas.jpg │ │ ├── pitt-jolie.jpg │ │ ├── pitt.jpg │ │ └── superman.jpg ├── FaceRecognizeExampleThread │ ├── FaceRecognizeExampleThread.pde │ ├── RecognizeRequest.pde │ └── data │ │ └── obama.jpg ├── FaceTrainExample │ ├── FaceTrainExample.pde │ └── data │ │ ├── obama.jpg │ │ ├── obamas.jpg │ │ ├── pitt-jolie.jpg │ │ ├── pitt.jpg │ │ └── superman.jpg ├── Greeter │ ├── Face.pde │ ├── FaceDetector.pde │ ├── Greeter.pde │ ├── RecognizeRequest.pde │ └── TrainRequest.pde └── RawJSONExample │ ├── RawJSONExample.pde │ └── data │ ├── key.txt │ ├── obama.jpg │ ├── obamas.jpg │ ├── pitt-jolie.jpg │ ├── pitt.jpg │ └── superman.jpg ├── FaceShift └── OSCDemo │ ├── OSCDemo.pde │ └── PossibleMessages.pde ├── OpenCV ├── FaceDetectMemory │ ├── Face.pde │ └── FaceDetectMemory.pde ├── LiveFaceDetect │ └── LiveFaceDetect.pde ├── LiveFaceDetect_saveimages │ └── LiveFaceDetect_saveimages.pde ├── LiveFaceDetect_scaled │ └── LiveFaceDetect_scaled.pde ├── SaveFaces │ ├── Face.pde │ ├── FaceDetector.pde │ └── SaveFaces.pde └── SimpleFaceDetect │ ├── SimpleFaceDetect.pde │ └── data │ └── obama.jpg └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | key.txt 3 | *.jpg 4 | *.png 5 | 6 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/FaceMorph.pde: -------------------------------------------------------------------------------- 1 | // Face Morphing Demo 2 | // Based on: https://ccrma.stanford.edu/~jacobliu/368Report/ 3 | // Daniel Shiffman 4 | 5 | // Two images 6 | PImage a; 7 | PImage b; 8 | 9 | // A Morphing object 10 | Morpher morph; 11 | 12 | // How much to morph, 0 is image A, 1 is image B, everything else in between 13 | float amt = 0; 14 | // Morph bar position 15 | float x = 100; 16 | 17 | void setup() { 18 | size(960, 800, P2D); 19 | 20 | // Load the images 21 | a = loadImage("pitt.jpg"); 22 | b = loadImage("jolie.jpg"); 23 | 24 | // Create the morphing object 25 | morph = new Morpher(a, b); 26 | } 27 | 28 | void draw() { 29 | 30 | 31 | background(0); 32 | 33 | pushMatrix(); 34 | 35 | // Show Image A and its triangles 36 | morph.displayImageA(); 37 | morph.displayTrianglesA(); 38 | 39 | // Show Image B and its triangles 40 | translate(a.width, 0); 41 | morph.displayImageB(); 42 | 43 | 44 | translate(-a.width, a.height); 45 | 46 | // Update the amount according to mouse position when pressed 47 | if (mousePressed && mouseY > a.height) { 48 | x = constrain(mouseX, 100, width-100); 49 | amt = map(x, 100, width-100, 0, 1); 50 | } 51 | 52 | // Morph an amount between 0 and 1 (0 being all of A, 1 being all of B) 53 | morph.drawMorph(amt); 54 | 55 | 56 | popMatrix(); 57 | 58 | // Have you clicked on the images? 59 | if (va != null) { 60 | fill(255, 0, 0); 61 | ellipse(va.x, va.y, 8, 8); 62 | } 63 | if (vb != null) { 64 | fill(255, 0, 0); 65 | ellipse(vb.x, vb.y, 8, 8); 66 | } 67 | 68 | 69 | 70 | // Draw bar at bottom 71 | stroke(255); 72 | line(100, height-50, width-100, height-50); 73 | stroke(255); 74 | line(x, height-75, x, height-25); 75 | 76 | 77 | // Some text instructions 78 | fill(255); 79 | textSize(20); 80 | String s = "Click on left image to set a point then click on right image to set corresponding point."; 81 | s += " For example, click on right eye in left image then right eye in right image. Set as many corresponding points as possible."; 82 | s += "\n\n 's' to save points, 'l' to load points"; 83 | text(s, a.width+10, a.height+20, a.width-20, a.height-10); 84 | } 85 | 86 | // Save or load points based on key presses 87 | void keyPressed() { 88 | if (key == 's') { 89 | morph.savePoints(); 90 | } 91 | else if (key == 'l') { 92 | morph.loadPoints(); 93 | } 94 | } 95 | 96 | // Variables to keep track of mouse interaction 97 | int counter = 0; 98 | PVector va; 99 | PVector vb; 100 | 101 | void mousePressed() { 102 | 103 | 104 | // If we clicked on an image 105 | if (mouseY < a.height) { 106 | // Point on image A first 107 | if (counter == 0) { 108 | va = new PVector(mouseX, mouseY); 109 | } 110 | // Corresponding point on image B 111 | else if (counter == 1) { 112 | PVector vb = new PVector(mouseX-a.width, mouseY); 113 | morph.addPair(va, vb); 114 | } 115 | // Increment click counter 116 | counter++; 117 | if (counter == 2) { 118 | // Start over 119 | counter = 0; 120 | va = null; 121 | vb = null; 122 | } 123 | } 124 | } 125 | 126 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/Morpher.pde: -------------------------------------------------------------------------------- 1 | // Face Morphing Demo 2 | // Based on: https://ccrma.stanford.edu/~jacobliu/368Report/ 3 | // Daniel Shiffman 4 | 5 | // The triangulate package is in the "code" folder and helps create the polygons 6 | // It's a modified version of: http://wiki.processing.org/w/Triangulation 7 | 8 | import triangulate.*; 9 | 10 | class Morpher { 11 | 12 | 13 | // A list of edges (each one is a pair of PVectors, one on each image) 14 | ArrayList pairs = new ArrayList(); 15 | // A list of triangles (each one is a pair of Triangles, one on each image) 16 | ArrayList tiles; 17 | 18 | // The two images 19 | PImage imgA; 20 | PImage imgB; 21 | 22 | Morpher(PImage imgA_, PImage imgB_) { 23 | imgA = imgA_; 24 | imgB = imgB_; 25 | 26 | // Start off with some boring default points along the edges of the image 27 | pairs.add(new Pair(0, 0)); 28 | pairs.add(new Pair(imgA.width/2, 0)); 29 | pairs.add(new Pair(imgA.width, 0)); 30 | pairs.add(new Pair(0, imgA.height/2)); 31 | pairs.add(new Pair(imgA.width, imgA.height/2)); 32 | pairs.add(new Pair(0, imgA.height)); 33 | pairs.add(new Pair(imgA.width/2, imgA.height)); 34 | pairs.add(new Pair(imgA.width, imgA.height)); 35 | makeTriangles(); 36 | } 37 | 38 | // Add a pair of points, one on each image 39 | void addPair(PVector a, PVector b) { 40 | pairs.add(new Pair(a.get(), b.get())); 41 | makeTriangles(); 42 | } 43 | 44 | // Create an array of triangle pairs 45 | void makeTriangles() { 46 | tiles = Triangulate.triangulatePairs(pairs); 47 | } 48 | 49 | // Here's how we draw an image 50 | void displayImageA() { 51 | // Look at every triangle 52 | for (TrianglePair t : tiles) { 53 | noTint(); 54 | noStroke(); 55 | noFill(); 56 | textureMode(IMAGE); 57 | // Draw as a shape with three points and textured from the image 58 | beginShape(); 59 | texture(imgA); 60 | // This is awkard, but getting point "a" from each point of the triangle 61 | PVector a = t.p1.a; 62 | PVector b = t.p2.a; 63 | PVector c = t.p3.a; 64 | vertex(a.x, a.y, a.x, a.y); 65 | vertex(b.x, b.y, b.x, b.y); 66 | vertex(c.x, c.y, c.x, c.y); 67 | endShape(); 68 | } 69 | } 70 | 71 | // Same method for drawing image B 72 | void displayImageB() { 73 | for (TrianglePair t : tiles) { 74 | noTint(); 75 | noStroke(); 76 | noFill(); 77 | textureMode(IMAGE); 78 | beginShape(); 79 | texture(imgB); 80 | PVector a = t.p1.b; 81 | PVector b = t.p2.b; 82 | PVector c = t.p3.b; 83 | vertex(a.x, a.y, a.x, a.y); 84 | vertex(b.x, b.y, b.x, b.y); 85 | vertex(c.x, c.y, c.x, c.y); 86 | endShape(); 87 | } 88 | } 89 | 90 | 91 | // In case we want to see the triangles themselves 92 | void displayTrianglesA() { 93 | for (TrianglePair t : tiles) { 94 | stroke(255); 95 | strokeWeight(1); 96 | noFill(); 97 | beginShape(); 98 | PVector a = t.p1.a; 99 | PVector b = t.p2.a; 100 | PVector c = t.p3.a; 101 | vertex(a.x, a.y); 102 | vertex(b.x, b.y); 103 | vertex(c.x, c.y); 104 | endShape(CLOSE); 105 | } 106 | } 107 | 108 | void displayTrianglesB() { 109 | for (TrianglePair t : tiles) { 110 | stroke(255); 111 | strokeWeight(1); 112 | noFill(); 113 | beginShape(); 114 | PVector a = t.p1.b; 115 | PVector b = t.p2.b; 116 | PVector c = t.p3.b; 117 | vertex(a.x, a.y); 118 | vertex(b.x, b.y); 119 | vertex(c.x, c.y); 120 | endShape(CLOSE); 121 | } 122 | } 123 | 124 | 125 | // Ok here is hte harder one, we're going to display the morphed image 126 | void drawMorph(float amt) { 127 | 128 | // For every triangle 129 | for (int i = 0; i < tiles.size(); i++) { 130 | 131 | // Let's get the pair 132 | TrianglePair tp = tiles.get(i); 133 | // We make a new triangle which interpolates 134 | Triangle t = tp.mix(amt); 135 | 136 | // Draw the first image 137 | tint(255); 138 | // stroke(255); // show triangles 139 | noStroke(); 140 | noFill(); 141 | textureMode(IMAGE); 142 | beginShape(); 143 | texture(imgA); 144 | // Use morphed triangle with corresponding texture points on original triangle 145 | vertex(t.p1.x, t.p1.y, tp.p1.a.x, tp.p1.a.y); 146 | vertex(t.p2.x, t.p2.y, tp.p2.a.x, tp.p2.a.y); 147 | vertex(t.p3.x, t.p3.y, tp.p3.a.x, tp.p3.a.y); 148 | endShape(); 149 | 150 | // Draw the second image blended with first 151 | noStroke(); 152 | noFill(); 153 | tint(255, amt*255); 154 | //tint(255,255); // Try showing ImageB always 155 | //stroke(255); // Try showing show triangles 156 | textureMode(IMAGE); 157 | beginShape(); 158 | texture(imgB); 159 | // Use morphed triangle with corresponding texture points on original triangle 160 | vertex(t.p1.x, t.p1.y, tp.p1.b.x, tp.p1.b.y); 161 | vertex(t.p2.x, t.p2.y, tp.p2.b.x, tp.p2.b.y); 162 | vertex(t.p3.x, t.p3.y, tp.p3.b.x, tp.p3.b.y); 163 | endShape(); 164 | } 165 | } 166 | 167 | 168 | void savePoints() { 169 | PrintWriter pw = createWriter("data/points.txt"); 170 | for (Pair p : pairs) { 171 | String s = p.a.x + "," + p.a.y + "," + p.b.x + "," + p.b.y; 172 | pw.println(s); 173 | } 174 | pw.flush(); 175 | pw.close(); 176 | } 177 | 178 | void loadPoints() { 179 | pairs.clear(); 180 | String[] lines = loadStrings("data/points.txt"); 181 | for (int i = 0; i < lines.length; i++) { 182 | float[] vals = float(split(lines[i], ",")); 183 | addPair(new PVector(vals[0], vals[1]), new PVector(vals[2], vals[3])); 184 | } 185 | } 186 | } 187 | 188 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/src/triangulate/Edge.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | 6 | package triangulate; 7 | 8 | import processing.core.PVector; 9 | 10 | public class Edge { 11 | 12 | public PVector p1, p2; 13 | 14 | public Edge() { 15 | p1=null; 16 | p2=null; 17 | } 18 | 19 | public Edge(PVector p1, PVector p2) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/src/triangulate/EdgePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class EdgePair { 10 | 11 | public Pair p1, p2; 12 | 13 | public EdgePair() { 14 | p1=null; 15 | p2=null; 16 | } 17 | 18 | public EdgePair(Pair p1, Pair p2) { 19 | this.p1 = p1; 20 | this.p2 = p2; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/src/triangulate/Pair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Pair { 10 | public PVector a; 11 | public PVector b; 12 | 13 | public Pair(PVector v) { 14 | a = v.get(); 15 | b = v.get(); 16 | } 17 | 18 | public Pair(PVector a_, PVector b_) { 19 | a = a_; 20 | b = b_; 21 | } 22 | 23 | public Pair(float x, float y) { 24 | a = new PVector(x,y); 25 | b = new PVector(x,y); 26 | } 27 | 28 | public Pair(float x, float y, float z) { 29 | a = new PVector(x,y,z); 30 | b = new PVector(x,y,z); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/src/triangulate/Triangle.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Triangle { 10 | 11 | public PVector p1, p2, p3; 12 | 13 | public Triangle() { 14 | p1=new PVector(); 15 | p2=new PVector(); 16 | p3=new PVector(); 17 | } 18 | 19 | public Triangle(PVector p1, PVector p2, PVector p3) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | this.p3 = p3; 23 | } 24 | 25 | public boolean sharesVertex(Triangle other) { 26 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 27 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 28 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/src/triangulate/TrianglePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class TrianglePair { 10 | 11 | public Pair p1, p2, p3; 12 | 13 | Triangle triangleA; 14 | Triangle mixed; 15 | 16 | public TrianglePair() { 17 | p1=null; 18 | p2=null; 19 | p3=null; 20 | } 21 | 22 | public TrianglePair(Pair p1, Pair p2, Pair p3) { 23 | this.p1 = p1; 24 | this.p2 = p2; 25 | this.p3 = p3; 26 | } 27 | 28 | public boolean sharesVertex(TrianglePair other) { 29 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 30 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 31 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 32 | } 33 | 34 | public Triangle getTriangleA() { 35 | if (triangleA == null) triangleA = new Triangle(p1.a,p2.a,p3.a); 36 | return triangleA; 37 | } 38 | 39 | public Triangle mix(float amt) { 40 | if (mixed == null) mixed = new Triangle(); 41 | 42 | mixed.p1.x = p1.a.x*(1-amt) + p1.b.x*amt; 43 | mixed.p1.y = p1.a.y*(1-amt) + p1.b.y*amt; 44 | 45 | mixed.p2.x = p2.a.x*(1-amt) + p2.b.x*amt; 46 | mixed.p2.y = p2.a.y*(1-amt) + p2.b.y*amt; 47 | 48 | mixed.p3.x = p3.a.x*(1-amt) + p3.b.x*amt; 49 | mixed.p3.y = p3.a.y*(1-amt) + p3.b.y*amt; 50 | 51 | return mixed; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/src/triangulate/Triangulate.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | /* 8 | * ported from p bourke's triangulate.c 9 | * http://astronomy.swin.edu.au/~pbourke/modelling/triangulate/ 10 | * 11 | * fjenett, 20th february 2005, offenbach-germany. 12 | * contact: http://www.florianjenett.de/ 13 | * 14 | * adapted to take a Vector of Point3f objects and return a Vector of Triangles 15 | * (and generally be more Java-like and less C-like in usage - 16 | * and probably less efficient but who's benchmarking?) 17 | * Tom Carden, tom (at) tom-carden.co.uk 17th January 2006 18 | * 19 | * adapted to get rid of those ugly Vector and Point3f objects. it now takes an 20 | * ArrayList of PVector objects and return an ArrayList of Triangles objects. 21 | * see what Sun thinks about Vector objects here: 22 | * http://java.sun.com/developer/technicalArticles/Collections/Using/index.html 23 | * antiplastik, 28 june 2010, paris-france 24 | * 25 | */ 26 | 27 | import java.util.ArrayList; 28 | import java.util.Comparator; 29 | import java.util.Collections; 30 | import java.util.HashSet; 31 | import java.util.Iterator; 32 | import processing.core.PApplet; 33 | import processing.core.PVector; 34 | 35 | public class Triangulate { 36 | 37 | /* 38 | From P Bourke's C prototype - 39 | 40 | qsort(p,nv,sizeof(XYZ),XYZCompare); 41 | 42 | int XYZCompare(void *v1,void *v2) { 43 | XYZ *p1,*p2; 44 | p1 = v1; 45 | p2 = v2; 46 | if (p1->x < p2->x) 47 | return(-1); 48 | else if (p1->x > p2->x) 49 | return(1); 50 | else 51 | return(0); 52 | } 53 | */ 54 | private static class XComparator implements Comparator { 55 | 56 | public int compare(PVector p1, PVector p2) { 57 | if (p1.x < p2.x) { 58 | return -1; 59 | } 60 | else if (p1.x > p2.x) { 61 | return 1; 62 | } 63 | else { 64 | return 0; 65 | } 66 | } 67 | } 68 | 69 | private static class XPairComparator implements Comparator { 70 | 71 | public int compare(Pair p1, Pair p2) { 72 | if (p1.a.x < p2.a.x) { 73 | return -1; 74 | } 75 | else if (p1.a.x > p2.a.x) { 76 | return 1; 77 | } 78 | else { 79 | return 0; 80 | } 81 | } 82 | } 83 | 84 | /* 85 | Return TRUE if a point (xp,yp) is inside the circumcircle made up 86 | of the points (x1,y1), (x2,y2), (x3,y3) 87 | The circumcircle centre is returned in (xc,yc) and the radius r 88 | NOTE: A point on the edge is inside the circumcircle 89 | */ 90 | private static boolean circumCircle(PVector p, Triangle t, PVector circle) { 91 | 92 | float m1,m2,mx1,mx2,my1,my2; 93 | float dx,dy,rsqr,drsqr; 94 | 95 | /* Check for coincident points */ 96 | if ( PApplet.abs(t.p1.y-t.p2.y) < PApplet.EPSILON && PApplet.abs(t.p2.y-t.p3.y) < PApplet.EPSILON ) { 97 | System.err.println("CircumCircle: Points are coincident."); 98 | return false; 99 | } 100 | 101 | if ( PApplet.abs(t.p2.y-t.p1.y) < PApplet.EPSILON ) { 102 | m2 = - (t.p3.x-t.p2.x) / (t.p3.y-t.p2.y); 103 | mx2 = (t.p2.x + t.p3.x) / 2.0f; 104 | my2 = (t.p2.y + t.p3.y) / 2.0f; 105 | circle.x = (t.p2.x + t.p1.x) / 2.0f; 106 | circle.y = m2 * (circle.x - mx2) + my2; 107 | } 108 | else if ( PApplet.abs(t.p3.y-t.p2.y) < PApplet.EPSILON ) { 109 | m1 = - (t.p2.x-t.p1.x) / (t.p2.y-t.p1.y); 110 | mx1 = (t.p1.x + t.p2.x) / 2.0f; 111 | my1 = (t.p1.y + t.p2.y) / 2.0f; 112 | circle.x = (t.p3.x + t.p2.x) / 2.0f; 113 | circle.y = m1 * (circle.x - mx1) + my1; 114 | } 115 | else { 116 | m1 = - (t.p2.x-t.p1.x) / (t.p2.y-t.p1.y); 117 | m2 = - (t.p3.x-t.p2.x) / (t.p3.y-t.p2.y); 118 | mx1 = (t.p1.x + t.p2.x) / 2.0f; 119 | mx2 = (t.p2.x + t.p3.x) / 2.0f; 120 | my1 = (t.p1.y + t.p2.y) / 2.0f; 121 | my2 = (t.p2.y + t.p3.y) / 2.0f; 122 | circle.x = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); 123 | circle.y = m1 * (circle.x - mx1) + my1; 124 | } 125 | 126 | dx = t.p2.x - circle.x; 127 | dy = t.p2.y - circle.y; 128 | rsqr = dx*dx + dy*dy; 129 | circle.z = PApplet.sqrt(rsqr); 130 | 131 | dx = p.x - circle.x; 132 | dy = p.y - circle.y; 133 | drsqr = dx*dx + dy*dy; 134 | 135 | return drsqr <= rsqr; 136 | } 137 | 138 | 139 | 140 | /* 141 | Triangulation subroutine 142 | Takes as input vertices (PVectors) in ArrayList pxyz 143 | Returned is a list of triangular faces in the ArrayList triangles 144 | These triangles are arranged in a consistent clockwise order. 145 | */ 146 | public static ArrayList triangulate( ArrayList pxyz ) { 147 | 148 | // sort vertex array in increasing x values 149 | Collections.sort(pxyz, new XComparator()); 150 | 151 | /* 152 | Find the maximum and minimum vertex bounds. 153 | This is to allow calculation of the bounding triangle 154 | */ 155 | float xmin = ((PVector)pxyz.get(0)).x; 156 | float ymin = ((PVector)pxyz.get(0)).y; 157 | float xmax = xmin; 158 | float ymax = ymin; 159 | 160 | Iterator pIter = pxyz.iterator(); 161 | while (pIter.hasNext()) { 162 | PVector p = (PVector)pIter.next(); 163 | if (p.x < xmin) xmin = p.x; 164 | if (p.x > xmax) xmax = p.x; 165 | if (p.y < ymin) ymin = p.y; 166 | if (p.y > ymax) ymax = p.y; 167 | } 168 | 169 | float dx = xmax - xmin; 170 | float dy = ymax - ymin; 171 | float dmax = (dx > dy) ? dx : dy; 172 | float xmid = (xmax + xmin) / 2.0f; 173 | float ymid = (ymax + ymin) / 2.0f; 174 | 175 | ArrayList triangles = new ArrayList(); // for the Triangles 176 | HashSet complete = new HashSet(); // for complete Triangles 177 | 178 | /* 179 | Set up the supertriangle 180 | This is a triangle which encompasses all the sample points. 181 | The supertriangle coordinates are added to the end of the 182 | vertex list. The supertriangle is the first triangle in 183 | the triangle list. 184 | */ 185 | Triangle superTriangle = new Triangle(); 186 | superTriangle.p1 = new PVector( xmid - 2.0f * dmax, ymid - dmax, 0.0f ); 187 | superTriangle.p2 = new PVector( xmid, ymid + 2.0f * dmax, 0.0f ); 188 | superTriangle.p3 = new PVector( xmid + 2.0f * dmax, ymid - dmax, 0.0f ); 189 | triangles.add(superTriangle); 190 | 191 | /* 192 | Include each point one at a time into the existing mesh 193 | */ 194 | ArrayList edges = new ArrayList(); 195 | pIter = pxyz.iterator(); 196 | while (pIter.hasNext()) { 197 | 198 | PVector p = (PVector)pIter.next(); 199 | 200 | edges.clear(); 201 | 202 | /* 203 | Set up the edge buffer. 204 | If the point (xp,yp) lies inside the circumcircle then the 205 | three edges of that triangle are added to the edge buffer 206 | and that triangle is removed. 207 | */ 208 | PVector circle = new PVector(); 209 | 210 | for (int j = triangles.size()-1; j >= 0; j--) { 211 | 212 | Triangle t = (Triangle)triangles.get(j); 213 | if (complete.contains(t)) { 214 | continue; 215 | } 216 | 217 | boolean inside = circumCircle( p, t, circle ); 218 | 219 | if (circle.x + circle.z < p.x) { 220 | complete.add(t); 221 | } 222 | if (inside) { 223 | edges.add(new Edge(t.p1, t.p2)); 224 | edges.add(new Edge(t.p2, t.p3)); 225 | edges.add(new Edge(t.p3, t.p1)); 226 | triangles.remove(j); 227 | } 228 | 229 | } 230 | 231 | /* 232 | Tag multiple edges 233 | Note: if all triangles are specified anticlockwise then all 234 | interior edges are opposite pointing in direction. 235 | */ 236 | for (int j=0; j= 0; i--) { 275 | Triangle t = (Triangle)triangles.get(i); 276 | if (t.sharesVertex(superTriangle)) { 277 | triangles.remove(i); 278 | } 279 | } 280 | 281 | return triangles; 282 | } 283 | 284 | 285 | /* 286 | Triangulation subroutine 287 | Takes as input vertices (Pairs) in ArrayList pairs 288 | Returned is a list of triangular faces in the ArrayList triangles 289 | These triangles are arranged in a consistent clockwise order. 290 | */ 291 | public static ArrayList triangulatePairs( ArrayList pairs ) { 292 | 293 | // sort vertex array in increasing x values 294 | Collections.sort(pairs, new XPairComparator()); 295 | 296 | /* 297 | Find the maximum and minimum vertex bounds. 298 | This is to allow calculation of the bounding triangle 299 | */ 300 | float xmin = pairs.get(0).a.x; 301 | float ymin = pairs.get(0).a.y; 302 | float xmax = xmin; 303 | float ymax = ymin; 304 | 305 | Iterator pIter = pairs.iterator(); 306 | while (pIter.hasNext()) { 307 | Pair p = pIter.next(); 308 | if (p.a.x < xmin) xmin = p.a.x; 309 | if (p.a.x > xmax) xmax = p.a.x; 310 | if (p.a.y < ymin) ymin = p.a.y; 311 | if (p.a.y > ymax) ymax = p.a.y; 312 | } 313 | 314 | float dx = xmax - xmin; 315 | float dy = ymax - ymin; 316 | float dmax = (dx > dy) ? dx : dy; 317 | float xmid = (xmax + xmin) / 2.0f; 318 | float ymid = (ymax + ymin) / 2.0f; 319 | 320 | ArrayList triangles = new ArrayList(); // for the Triangles 321 | HashSet complete = new HashSet(); // for complete Triangles 322 | 323 | /* 324 | Set up the supertriangle 325 | This is a triangle which encompasses all the sample points. 326 | The supertriangle coordinates are added to the end of the 327 | vertex list. The supertriangle is the first triangle in 328 | the triangle list. 329 | */ 330 | TrianglePair superTriangle = new TrianglePair(); 331 | superTriangle.p1 = new Pair( xmid - 2.0f * dmax, ymid - dmax, 0.0f ); 332 | superTriangle.p2 = new Pair( xmid, ymid + 2.0f * dmax, 0.0f ); 333 | superTriangle.p3 = new Pair( xmid + 2.0f * dmax, ymid - dmax, 0.0f ); 334 | triangles.add(superTriangle); 335 | 336 | /* 337 | Include each point one at a time into the existing mesh 338 | */ 339 | ArrayList edges = new ArrayList(); 340 | pIter = pairs.iterator(); 341 | while (pIter.hasNext()) { 342 | 343 | Pair p = (Pair)pIter.next(); 344 | 345 | edges.clear(); 346 | 347 | /* 348 | Set up the edge buffer. 349 | If the point (xp,yp) lies inside the circumcircle then the 350 | three edges of that triangle are added to the edge buffer 351 | and that triangle is removed. 352 | */ 353 | PVector circle = new PVector(); 354 | 355 | for (int j = triangles.size()-1; j >= 0; j--) { 356 | 357 | TrianglePair t = triangles.get(j); 358 | if (complete.contains(t)) { 359 | continue; 360 | } 361 | 362 | boolean inside = circumCircle( p.a, t.getTriangleA(), circle ); 363 | 364 | if (circle.x + circle.z < p.a.x) { 365 | complete.add(t); 366 | } 367 | if (inside) { 368 | edges.add(new EdgePair(t.p1, t.p2)); 369 | edges.add(new EdgePair(t.p2, t.p3)); 370 | edges.add(new EdgePair(t.p3, t.p1)); 371 | triangles.remove(j); 372 | } 373 | 374 | } 375 | 376 | /* 377 | Tag multiple edges 378 | Note: if all triangles are specified anticlockwise then all 379 | interior edges are opposite pointing in direction. 380 | */ 381 | for (int j=0; j= 0; i--) { 420 | TrianglePair t = triangles.get(i); 421 | if (t.sharesVertex(superTriangle)) { 422 | triangles.remove(i); 423 | } 424 | } 425 | 426 | return triangles; 427 | } 428 | 429 | 430 | } 431 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/code/triangulate.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceMorphing/FaceMorph/code/triangulate.jar -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/data/jolie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceMorphing/FaceMorph/data/jolie.jpg -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceMorphing/FaceMorph/data/pitt.jpg -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/data/points.txt: -------------------------------------------------------------------------------- 1 | 0.0,0.0,0.0,0.0 2 | 0.0,180.0,0.0,180.0 3 | 0.0,360.0,0.0,360.0 4 | 120.0,71.0,141.0,64.0 5 | 146.0,162.0,166.0,106.0 6 | 168.0,156.0,188.0,97.0 7 | 174.0,175.0,183.0,121.0 8 | 182.0,253.0,199.0,193.0 9 | 190.0,154.0,202.0,95.0 10 | 195.0,313.0,206.0,227.0 11 | 208.0,211.0,223.0,149.0 12 | 212.0,66.0,210.0,33.0 13 | 229.0,321.0,225.0,233.0 14 | 236.0,146.0,239.0,95.0 15 | 240.0,0.0,240.0,0.0 16 | 240.0,360.0,240.0,360.0 17 | 256.0,166.0,251.0,112.0 18 | 259.0,307.0,254.0,225.0 19 | 260.0,246.0,258.0,185.0 20 | 264.0,143.0,263.0,86.0 21 | 282.0,152.0,283.0,99.0 22 | 300.0,68.0,278.0,50.0 23 | 340.0,145.0,315.0,112.0 24 | 340.0,194.0,310.0,157.0 25 | 480.0,0.0,480.0,0.0 26 | 480.0,180.0,480.0,180.0 27 | 480.0,360.0,480.0,360.0 28 | -------------------------------------------------------------------------------- /FaceMorphing/FaceMorph/data/points_backup.txt: -------------------------------------------------------------------------------- 1 | 0.0,0.0,0.0,0.0 2 | 0.0,180.0,0.0,180.0 3 | 0.0,360.0,0.0,360.0 4 | 168.0,168.0,169.0,160.0 5 | 175.0,51.0,178.0,42.0 6 | 180.0,86.0,184.0,90.0 7 | 201.0,127.0,200.0,126.0 8 | 201.0,221.0,208.0,242.0 9 | 212.0,153.0,208.0,152.0 10 | 225.0,182.0,219.0,189.0 11 | 232.0,35.0,224.0,18.0 12 | 239.0,78.0,239.0,85.0 13 | 240.0,0.0,240.0,0.0 14 | 240.0,360.0,240.0,360.0 15 | 240.0,203.0,240.0,215.0 16 | 241.0,172.0,234.0,179.0 17 | 243.0,227.0,243.0,248.0 18 | 257.0,175.0,255.0,182.0 19 | 264.0,147.0,266.0,142.0 20 | 277.0,125.0,273.0,122.0 21 | 285.0,213.0,281.0,229.0 22 | 292.0,40.0,296.0,37.0 23 | 304.0,76.0,299.0,81.0 24 | 318.0,164.0,318.0,164.0 25 | 480.0,0.0,480.0,0.0 26 | 480.0,180.0,480.0,180.0 27 | 480.0,360.0,480.0,360.0 28 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/TextureDemo.pde: -------------------------------------------------------------------------------- 1 | // Face Morphing Demo 2 | // Based on: https://ccrma.stanford.edu/~jacobliu/368Report/ 3 | // Daniel Shiffman 4 | 5 | // Two images 6 | PImage pittimg; 7 | PImage jolieimg; 8 | 9 | // Triangle on each image, plus the morphed one 10 | Triangle pitt; 11 | Triangle jolie; 12 | Triangle morph; 13 | 14 | // How much to morph, 0 is image A, 1 is image B, everything else in between 15 | float amt = 0; 16 | // Morph bar position 17 | float x = 100; 18 | 19 | void setup() { 20 | size(960, 800, P2D); 21 | 22 | // Load the images 23 | pittimg = loadImage("pitt.jpg"); 24 | jolieimg = loadImage("jolie.jpg"); 25 | 26 | // Make up some triangles 27 | pitt = new Triangle(177, 172, 260, 167, 217, 256); 28 | jolie = new Triangle(188, 121, 257, 115, 226, 189); 29 | morph = new Triangle(0, 0, 0, 0, 0, 0); 30 | } 31 | 32 | void draw() { 33 | 34 | noTint(); 35 | 36 | background(0); 37 | slider(); 38 | textureMode(IMAGE); 39 | pushMatrix(); 40 | pitt(); 41 | jolie(); 42 | translate(-pittimg.width, pittimg.height); 43 | 44 | // Morph an amount between 0 and 1 (0 being all of A, 1 being all of B) 45 | // This "morphs" the vertices 46 | morph.a = PVector.lerp(pitt.a, jolie.a, amt); 47 | morph.b = PVector.lerp(pitt.b, jolie.b, amt); 48 | morph.c = PVector.lerp(pitt.c, jolie.c, amt); 49 | 50 | 51 | // Draw the triangle with jolie's face but morphed points 52 | beginShape(); 53 | texture(jolieimg); 54 | tint(255, amt*255); 55 | vertex(morph.a.x, morph.a.y, jolie.a.x, jolie.a.y); 56 | vertex(morph.b.x, morph.b.y, jolie.b.x, jolie.b.y); 57 | vertex(morph.c.x, morph.c.y, jolie.c.x, jolie.c.y); 58 | endShape(); 59 | 60 | // Blend on top of that the triangle with pitt's face but morphed points 61 | beginShape(); 62 | texture(pittimg); 63 | tint(255, 255-amt*255); 64 | vertex(morph.a.x, morph.a.y, pitt.a.x, pitt.a.y); 65 | vertex(morph.b.x, morph.b.y, pitt.b.x, pitt.b.y); 66 | vertex(morph.c.x, morph.c.y, pitt.c.x, pitt.c.y); 67 | endShape(); 68 | 69 | // Triangle edges 70 | beginShape(); 71 | vertex(morph.a.x, morph.a.y); 72 | vertex(morph.b.x, morph.b.y); 73 | vertex(morph.c.x, morph.c.y); 74 | endShape(CLOSE); 75 | 76 | popMatrix(); 77 | 78 | // Draw bar at bottom 79 | stroke(255); 80 | line(100, height-50, width-100, height-50); 81 | stroke(255); 82 | line(x, height-75, x, height-25); 83 | } 84 | 85 | void pitt() { 86 | // Show Image A and its triangles 87 | image(pittimg, 0, 0); 88 | beginShape(); 89 | texture(pittimg); 90 | vertex(pitt.a.x, pitt.a.y, pitt.a.x, pitt.a.y); 91 | vertex(pitt.b.x, pitt.b.y, pitt.b.x, pitt.b.y); 92 | vertex(pitt.c.x, pitt.c.y, pitt.c.x, pitt.c.y); 93 | endShape(); 94 | 95 | beginShape(); 96 | noFill(); 97 | stroke(255); 98 | vertex(pitt.a.x, pitt.a.y); 99 | vertex(pitt.b.x, pitt.b.y); 100 | vertex(pitt.c.x, pitt.c.y); 101 | endShape(CLOSE); 102 | } 103 | 104 | void jolie() { 105 | // Show Image B and its triangles 106 | translate(pittimg.width, 0); 107 | image(jolieimg, 0, 0); 108 | 109 | beginShape(); 110 | texture(jolieimg); 111 | vertex(jolie.a.x, jolie.a.y, jolie.a.x, jolie.a.y); 112 | vertex(jolie.b.x, jolie.b.y, jolie.b.x, jolie.b.y); 113 | vertex(jolie.c.x, jolie.c.y, jolie.c.x, jolie.c.y); 114 | endShape(); 115 | 116 | beginShape(); 117 | vertex(jolie.a.x, jolie.a.y); 118 | vertex(jolie.b.x, jolie.b.y); 119 | vertex(jolie.c.x, jolie.c.y); 120 | endShape(CLOSE); 121 | } 122 | 123 | void slider() { 124 | // Update the amount according to mouse position when pressed 125 | if (mousePressed && mouseY > pittimg.height) { 126 | x = constrain(mouseX, 100, width-100); 127 | amt = map(x, 100, width-100, 0, 1); 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/Triangle.pde: -------------------------------------------------------------------------------- 1 | 2 | class Triangle { 3 | 4 | PVector a; 5 | PVector b; 6 | PVector c; 7 | 8 | Triangle(float x1, float y1, float x2, float y2, float x3, float y3) { 9 | a = new PVector(x1, y1); 10 | b = new PVector(x2, y2); 11 | c = new PVector(x3, y3); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/code/src/triangulate/Edge.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | 6 | package triangulate; 7 | 8 | import processing.core.PVector; 9 | 10 | public class Edge { 11 | 12 | public PVector p1, p2; 13 | 14 | public Edge() { 15 | p1=null; 16 | p2=null; 17 | } 18 | 19 | public Edge(PVector p1, PVector p2) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/code/src/triangulate/EdgePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class EdgePair { 10 | 11 | public Pair p1, p2; 12 | 13 | public EdgePair() { 14 | p1=null; 15 | p2=null; 16 | } 17 | 18 | public EdgePair(Pair p1, Pair p2) { 19 | this.p1 = p1; 20 | this.p2 = p2; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/code/src/triangulate/Pair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Pair { 10 | public PVector a; 11 | public PVector b; 12 | 13 | public Pair(PVector v) { 14 | a = v.get(); 15 | b = v.get(); 16 | } 17 | 18 | public Pair(PVector a_, PVector b_) { 19 | a = a_; 20 | b = b_; 21 | } 22 | 23 | public Pair(float x, float y) { 24 | a = new PVector(x,y); 25 | b = new PVector(x,y); 26 | } 27 | 28 | public Pair(float x, float y, float z) { 29 | a = new PVector(x,y,z); 30 | b = new PVector(x,y,z); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/code/src/triangulate/Triangle.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Triangle { 10 | 11 | public PVector p1, p2, p3; 12 | 13 | public Triangle() { 14 | p1=new PVector(); 15 | p2=new PVector(); 16 | p3=new PVector(); 17 | } 18 | 19 | public Triangle(PVector p1, PVector p2, PVector p3) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | this.p3 = p3; 23 | } 24 | 25 | public boolean sharesVertex(Triangle other) { 26 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 27 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 28 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/code/src/triangulate/TrianglePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class TrianglePair { 10 | 11 | public Pair p1, p2, p3; 12 | 13 | Triangle triangleA; 14 | Triangle mixed; 15 | 16 | public TrianglePair() { 17 | p1=null; 18 | p2=null; 19 | p3=null; 20 | } 21 | 22 | public TrianglePair(Pair p1, Pair p2, Pair p3) { 23 | this.p1 = p1; 24 | this.p2 = p2; 25 | this.p3 = p3; 26 | } 27 | 28 | public boolean sharesVertex(TrianglePair other) { 29 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 30 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 31 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 32 | } 33 | 34 | public Triangle getTriangleA() { 35 | if (triangleA == null) triangleA = new Triangle(p1.a,p2.a,p3.a); 36 | return triangleA; 37 | } 38 | 39 | public Triangle mix(float amt) { 40 | if (mixed == null) mixed = new Triangle(); 41 | 42 | mixed.p1.x = p1.a.x*(1-amt) + p1.b.x*amt; 43 | mixed.p1.y = p1.a.y*(1-amt) + p1.b.y*amt; 44 | 45 | mixed.p2.x = p2.a.x*(1-amt) + p2.b.x*amt; 46 | mixed.p2.y = p2.a.y*(1-amt) + p2.b.y*amt; 47 | 48 | mixed.p3.x = p3.a.x*(1-amt) + p3.b.x*amt; 49 | mixed.p3.y = p3.a.y*(1-amt) + p3.b.y*amt; 50 | 51 | return mixed; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/code/triangulate.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceMorphing/TextureDemo/code/triangulate.jar -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/data/jolie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceMorphing/TextureDemo/data/jolie.jpg -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceMorphing/TextureDemo/data/pitt.jpg -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/data/points.txt: -------------------------------------------------------------------------------- 1 | 0.0,0.0,0.0,0.0 2 | 0.0,180.0,0.0,180.0 3 | 0.0,360.0,0.0,360.0 4 | 120.0,71.0,141.0,64.0 5 | 146.0,162.0,166.0,106.0 6 | 168.0,156.0,188.0,97.0 7 | 174.0,175.0,183.0,121.0 8 | 182.0,253.0,199.0,193.0 9 | 190.0,154.0,202.0,95.0 10 | 195.0,313.0,206.0,227.0 11 | 208.0,211.0,223.0,149.0 12 | 212.0,66.0,210.0,33.0 13 | 229.0,321.0,225.0,233.0 14 | 236.0,146.0,239.0,95.0 15 | 240.0,0.0,240.0,0.0 16 | 240.0,360.0,240.0,360.0 17 | 256.0,166.0,251.0,112.0 18 | 259.0,307.0,254.0,225.0 19 | 260.0,246.0,258.0,185.0 20 | 264.0,143.0,263.0,86.0 21 | 282.0,152.0,283.0,99.0 22 | 300.0,68.0,278.0,50.0 23 | 340.0,145.0,315.0,112.0 24 | 340.0,194.0,310.0,157.0 25 | 480.0,0.0,480.0,0.0 26 | 480.0,180.0,480.0,180.0 27 | 480.0,360.0,480.0,360.0 28 | -------------------------------------------------------------------------------- /FaceMorphing/TextureDemo/data/points_backup.txt: -------------------------------------------------------------------------------- 1 | 0.0,0.0,0.0,0.0 2 | 0.0,180.0,0.0,180.0 3 | 0.0,360.0,0.0,360.0 4 | 168.0,168.0,169.0,160.0 5 | 175.0,51.0,178.0,42.0 6 | 180.0,86.0,184.0,90.0 7 | 201.0,127.0,200.0,126.0 8 | 201.0,221.0,208.0,242.0 9 | 212.0,153.0,208.0,152.0 10 | 225.0,182.0,219.0,189.0 11 | 232.0,35.0,224.0,18.0 12 | 239.0,78.0,239.0,85.0 13 | 240.0,0.0,240.0,0.0 14 | 240.0,360.0,240.0,360.0 15 | 240.0,203.0,240.0,215.0 16 | 241.0,172.0,234.0,179.0 17 | 243.0,227.0,243.0,248.0 18 | 257.0,175.0,255.0,182.0 19 | 264.0,147.0,266.0,142.0 20 | 277.0,125.0,273.0,122.0 21 | 285.0,213.0,281.0,229.0 22 | 292.0,40.0,296.0,37.0 23 | 304.0,76.0,299.0,81.0 24 | 318.0,164.0,318.0,164.0 25 | 480.0,0.0,480.0,0.0 26 | 480.0,180.0,480.0,180.0 27 | 480.0,360.0,480.0,360.0 28 | -------------------------------------------------------------------------------- /FaceOSC/BlinkParticles/BlinkParticles.pde: -------------------------------------------------------------------------------- 1 | 2 | // Face It 3 | // ITP Fall 2013 4 | // Daniel Shiffman 5 | 6 | // Blinking Particles 7 | // Using: https://github.com/kylemcdonald/ofxFaceTracker/downloads 8 | 9 | import oscP5.*; 10 | OscP5 oscP5; 11 | 12 | ParticleSystem ps; 13 | 14 | void setup() { 15 | size(640, 480); 16 | 17 | // Make a particle system 18 | ps = new ParticleSystem(new PVector(width/2, 50)); 19 | 20 | oscP5 = new OscP5(this, 8338); 21 | // Plug in the blink gesture 22 | oscP5.plug(this, "blink", "/gesture/blink"); 23 | } 24 | 25 | 26 | 27 | void draw() { 28 | background(0); 29 | ps.run(); 30 | } 31 | 32 | void blink(int state) { 33 | // When you blink add 100 new particles! 34 | if (state == 1) { 35 | ps.addParticle(100); 36 | } 37 | } 38 | 39 | void oscEvent(OscMessage theOscMessage) { 40 | if (theOscMessage.isPlugged()==false) { 41 | //println("UNPLUGGED: " + theOscMessage); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /FaceOSC/BlinkParticles/Particle.pde: -------------------------------------------------------------------------------- 1 | // A simple Particle class 2 | 3 | class Particle { 4 | PVector location; 5 | PVector velocity; 6 | PVector acceleration; 7 | float lifespan; 8 | 9 | Particle(PVector l) { 10 | acceleration = new PVector(0,0.5); 11 | velocity = PVector.random2D(); 12 | velocity.mult(random(0.5,4)); 13 | location = l.get(); 14 | lifespan = 255.0; 15 | } 16 | 17 | void run() { 18 | update(); 19 | display(); 20 | } 21 | 22 | // Method to update location 23 | void update() { 24 | velocity.add(acceleration); 25 | location.add(velocity); 26 | lifespan -= 1.0; 27 | } 28 | 29 | // Method to display 30 | void display() { 31 | stroke(255,lifespan); 32 | fill(255,lifespan); 33 | ellipse(location.x,location.y,8,8); 34 | } 35 | 36 | // Is the particle still useful? 37 | boolean isDead() { 38 | if (lifespan < 0.0) { 39 | return true; 40 | } else { 41 | return false; 42 | } 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /FaceOSC/BlinkParticles/ParticleSystem.pde: -------------------------------------------------------------------------------- 1 | // A class to describe a group of Particles 2 | // An ArrayList is used to manage the list of Particles 3 | 4 | class ParticleSystem { 5 | ArrayList particles; 6 | PVector origin; 7 | 8 | ParticleSystem(PVector location) { 9 | origin = location.get(); 10 | particles = new ArrayList(); 11 | } 12 | 13 | void addParticle(int number) { 14 | for (int i = 0; i < number; i++) { 15 | particles.add(new Particle(origin)); 16 | } 17 | } 18 | 19 | void run() { 20 | for (int i = particles.size()-1; i >= 0; i--) { 21 | Particle p = particles.get(i); 22 | p.run(); 23 | if (p.isDead()) { 24 | particles.remove(i); 25 | } 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCAllPoints/FaceOSCAllPoints.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Face It 4 | ITP Fall 2013 5 | Daniel Shiffman 6 | 7 | Slightly modified rom Greg Borenstein (https://github.com/atduskgreg) 8 | 9 | This example uses the extended version of FaceOSC to draw 10 | all of the face points tracked by FaceOSC and to display the 11 | original camera image via Syphon 12 | 13 | Download the extended version here: 14 | 15 | https://github.com/downloads/kylemcdonald/ofxFaceTracker/FaceOSC-osx+Syphon.zip 16 | 17 | Download the Syphon library for Processing here: 18 | 19 | http://code.google.com/p/syphon-implementations/downloads/list 20 | 21 | NOTE WELL: this example will not work with the standard FaceOSC app, 22 | which does not send the necessary OSC messages with all of the face points 23 | and does not publish the camera feed over Syphon. 24 | 25 | */ 26 | 27 | import oscP5.*; 28 | import codeanticode.syphon.*; 29 | 30 | OscP5 oscP5; 31 | SyphonClient client; 32 | 33 | PGraphics canvas; 34 | 35 | boolean found; 36 | PVector[] meshPoints; 37 | 38 | 39 | void setup() { 40 | size(640, 480, P3D); 41 | frameRate(30); 42 | initMesh(); 43 | 44 | oscP5 = new OscP5(this, 8338); 45 | 46 | // USE THESE 2 EVENTS TO DRAW THE 47 | // FULL FACE MESH: 48 | oscP5.plug(this, "found", "/found"); 49 | oscP5.plug(this, "loadMesh", "/raw"); 50 | 51 | // initialize the syphon client with the name of the server 52 | client = new SyphonClient(this, "FaceOSC"); 53 | // prep the PGraphics object to receive the camera image 54 | canvas = createGraphics(640, 480, P3D); 55 | } 56 | 57 | void draw() { 58 | background(0); 59 | stroke(255); 60 | background(0); 61 | 62 | image(canvas, 0, 0, width, height); 63 | 64 | if (client.available()) { 65 | canvas = client.getGraphics(canvas); 66 | } 67 | 68 | if (found) { 69 | fill(100); 70 | drawFeature(faceOutline); 71 | drawFeature(leftEyebrow); 72 | drawFeature(rightEyebrow); 73 | drawFeature(nosePart1); 74 | drawFeature(nosePart2); 75 | drawFeature(leftEye); 76 | drawFeature(rightEye); 77 | drawFeature(mouthPart1); 78 | drawFeature(mouthPart2); 79 | drawFeature(mouthPart3); 80 | } 81 | } 82 | 83 | void drawFeature(int[] featurePointList) { 84 | for (int i = 0; i < featurePointList.length; i++) { 85 | PVector meshVertex = meshPoints[featurePointList[i]]; 86 | if (i > 0) { 87 | PVector prevMeshVertex = meshPoints[featurePointList[i-1]]; 88 | line(meshVertex.x, meshVertex.y, prevMeshVertex.x, prevMeshVertex.y); 89 | } 90 | ellipse(meshVertex.x, meshVertex.y, 3, 3); 91 | } 92 | } 93 | 94 | public void found(int i) { 95 | // println("found: " + i); // 1 == found, 0 == not found 96 | found = i == 1; 97 | } 98 | 99 | void oscEvent(OscMessage theOscMessage) { 100 | if (theOscMessage.isPlugged()==false) { 101 | // For any unplugged messages 102 | println("UNPLUGGED: " + theOscMessage); 103 | } 104 | } 105 | 106 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCAllPoints/MeshData.pde: -------------------------------------------------------------------------------- 1 | // LISTS OF INDICES FOR EACH FACE PART 2 | int[] faceOutline = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 3 | int[] leftEyebrow = {17, 18, 19, 20, 21}; 4 | int[] rightEyebrow = {22, 23, 24, 25, 26}; 5 | int[] nosePart1 = {27, 28, 29, 30}; 6 | int[] nosePart2 = {31, 32, 33, 34, 35}; 7 | int[] leftEye = {36, 37, 38, 39, 40, 41, 36}; 8 | int[] rightEye = {42, 43, 44, 45, 46, 47, 42}; 9 | int[] mouthPart1 = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 48}; 10 | int[] mouthPart2 = {60, 65}; 11 | int[] mouthPart3 = {60, 61, 62, 63, 64, 65}; 12 | 13 | 14 | void initMesh() { 15 | // initialize meshPoints array with PVectors 16 | meshPoints = new PVector[66]; 17 | for (int i = 0; i < meshPoints.length; i++) { 18 | meshPoints[i] = new PVector(); 19 | } 20 | } 21 | 22 | // this method was generated programmatically. It's fugly. 23 | public void loadMesh(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float x5, float y5, float x6, float y6, float x7, float y7, float x8, float y8, float x9, float y9, float x10, float y10, float x11, float y11, float x12, float y12, float x13, float y13, float x14, float y14, float x15, float y15, float x16, float y16, float x17, float y17, float x18, float y18, float x19, float y19, float x20, float y20, float x21, float y21, float x22, float y22, float x23, float y23, float x24, float y24, float x25, float y25, float x26, float y26, float x27, float y27, float x28, float y28, float x29, float y29, float x30, float y30, float x31, float y31, float x32, float y32, float x33, float y33, float x34, float y34, float x35, float y35, float x36, float y36, float x37, float y37, float x38, float y38, float x39, float y39, float x40, float y40, float x41, float y41, float x42, float y42, float x43, float y43, float x44, float y44, float x45, float y45, float x46, float y46, float x47, float y47, float x48, float y48, float x49, float y49, float x50, float y50, float x51, float y51, float x52, float y52, float x53, float y53, float x54, float y54, float x55, float y55, float x56, float y56, float x57, float y57, float x58, float y58, float x59, float y59, float x60, float y60, float x61, float y61, float x62, float y62, float x63, float y63, float x64, float y64, float x65, float y65) { 24 | //println("loading mesh..."); 25 | 26 | meshPoints[0].x = x0; 27 | meshPoints[0].y = y0; 28 | meshPoints[1].x = x1; 29 | meshPoints[1].y = y1; 30 | meshPoints[2].x = x2; 31 | meshPoints[2].y = y2; 32 | meshPoints[3].x = x3; 33 | meshPoints[3].y = y3; 34 | meshPoints[4].x = x4; 35 | meshPoints[4].y = y4; 36 | meshPoints[5].x = x5; 37 | meshPoints[5].y = y5; 38 | meshPoints[6].x = x6; 39 | meshPoints[6].y = y6; 40 | meshPoints[7].x = x7; 41 | meshPoints[7].y = y7; 42 | meshPoints[8].x = x8; 43 | meshPoints[8].y = y8; 44 | meshPoints[9].x = x9; 45 | meshPoints[9].y = y9; 46 | meshPoints[10].x = x10; 47 | meshPoints[10].y = y10; 48 | meshPoints[11].x = x11; 49 | meshPoints[11].y = y11; 50 | meshPoints[12].x = x12; 51 | meshPoints[12].y = y12; 52 | meshPoints[13].x = x13; 53 | meshPoints[13].y = y13; 54 | meshPoints[14].x = x14; 55 | meshPoints[14].y = y14; 56 | meshPoints[15].x = x15; 57 | meshPoints[15].y = y15; 58 | meshPoints[16].x = x16; 59 | meshPoints[16].y = y16; 60 | meshPoints[17].x = x17; 61 | meshPoints[17].y = y17; 62 | meshPoints[18].x = x18; 63 | meshPoints[18].y = y18; 64 | meshPoints[19].x = x19; 65 | meshPoints[19].y = y19; 66 | meshPoints[20].x = x20; 67 | meshPoints[20].y = y20; 68 | meshPoints[21].x = x21; 69 | meshPoints[21].y = y21; 70 | meshPoints[22].x = x22; 71 | meshPoints[22].y = y22; 72 | meshPoints[23].x = x23; 73 | meshPoints[23].y = y23; 74 | meshPoints[24].x = x24; 75 | meshPoints[24].y = y24; 76 | meshPoints[25].x = x25; 77 | meshPoints[25].y = y25; 78 | meshPoints[26].x = x26; 79 | meshPoints[26].y = y26; 80 | meshPoints[27].x = x27; 81 | meshPoints[27].y = y27; 82 | meshPoints[28].x = x28; 83 | meshPoints[28].y = y28; 84 | meshPoints[29].x = x29; 85 | meshPoints[29].y = y29; 86 | meshPoints[30].x = x30; 87 | meshPoints[30].y = y30; 88 | meshPoints[31].x = x31; 89 | meshPoints[31].y = y31; 90 | meshPoints[32].x = x32; 91 | meshPoints[32].y = y32; 92 | meshPoints[33].x = x33; 93 | meshPoints[33].y = y33; 94 | meshPoints[34].x = x34; 95 | meshPoints[34].y = y34; 96 | meshPoints[35].x = x35; 97 | meshPoints[35].y = y35; 98 | meshPoints[36].x = x36; 99 | meshPoints[36].y = y36; 100 | meshPoints[37].x = x37; 101 | meshPoints[37].y = y37; 102 | meshPoints[38].x = x38; 103 | meshPoints[38].y = y38; 104 | meshPoints[39].x = x39; 105 | meshPoints[39].y = y39; 106 | meshPoints[40].x = x40; 107 | meshPoints[40].y = y40; 108 | meshPoints[41].x = x41; 109 | meshPoints[41].y = y41; 110 | meshPoints[42].x = x42; 111 | meshPoints[42].y = y42; 112 | meshPoints[43].x = x43; 113 | meshPoints[43].y = y43; 114 | meshPoints[44].x = x44; 115 | meshPoints[44].y = y44; 116 | meshPoints[45].x = x45; 117 | meshPoints[45].y = y45; 118 | meshPoints[46].x = x46; 119 | meshPoints[46].y = y46; 120 | meshPoints[47].x = x47; 121 | meshPoints[47].y = y47; 122 | meshPoints[48].x = x48; 123 | meshPoints[48].y = y48; 124 | meshPoints[49].x = x49; 125 | meshPoints[49].y = y49; 126 | meshPoints[50].x = x50; 127 | meshPoints[50].y = y50; 128 | meshPoints[51].x = x51; 129 | meshPoints[51].y = y51; 130 | meshPoints[52].x = x52; 131 | meshPoints[52].y = y52; 132 | meshPoints[53].x = x53; 133 | meshPoints[53].y = y53; 134 | meshPoints[54].x = x54; 135 | meshPoints[54].y = y54; 136 | meshPoints[55].x = x55; 137 | meshPoints[55].y = y55; 138 | meshPoints[56].x = x56; 139 | meshPoints[56].y = y56; 140 | meshPoints[57].x = x57; 141 | meshPoints[57].y = y57; 142 | meshPoints[58].x = x58; 143 | meshPoints[58].y = y58; 144 | meshPoints[59].x = x59; 145 | meshPoints[59].y = y59; 146 | meshPoints[60].x = x60; 147 | meshPoints[60].y = y60; 148 | meshPoints[61].x = x61; 149 | meshPoints[61].y = y61; 150 | meshPoints[62].x = x62; 151 | meshPoints[62].y = y62; 152 | meshPoints[63].x = x63; 153 | meshPoints[63].y = y63; 154 | meshPoints[64].x = x64; 155 | meshPoints[64].y = y64; 156 | meshPoints[65].x = x65; 157 | meshPoints[65].y = y65; 158 | } 159 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCDemo/FaceOSCDemo.pde: -------------------------------------------------------------------------------- 1 | 2 | // Face It 3 | // ITP Fall 2013 4 | // Daniel Shiffman 5 | 6 | // FaceOSC Example 7 | // Adapted from Greg Borenstein: https://gist.github.com/atduskgreg/1603230 8 | 9 | // Use with: https://github.com/downloads/kylemcdonald/ofxFaceTracker/FaceOSC.zip 10 | 11 | import oscP5.*; 12 | OscP5 oscP5; 13 | 14 | PVector posePosition; 15 | PVector poseOrientation; 16 | 17 | boolean found; 18 | float eyeLeftHeight; 19 | float eyeRightHeight; 20 | float mouthHeight; 21 | float mouthWidth; 22 | float nostrilHeight; 23 | float leftEyebrowHeight; 24 | float rightEyebrowHeight; 25 | 26 | float poseScale; 27 | 28 | void setup() { 29 | size(640, 480); 30 | frameRate(30); 31 | 32 | posePosition = new PVector(); 33 | poseOrientation = new PVector(); 34 | 35 | oscP5 = new OscP5(this, 8338); 36 | oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width"); 37 | oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height"); 38 | oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left"); 39 | oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right"); 40 | oscP5.plug(this, "eyeLeftReceived", "/gesture/eye/left"); 41 | oscP5.plug(this, "eyeRightReceived", "/gesture/eye/right"); 42 | oscP5.plug(this, "jawReceived", "/gesture/jaw"); 43 | oscP5.plug(this, "nostrilsReceived", "/gesture/nostrils"); 44 | oscP5.plug(this, "found", "/found"); 45 | oscP5.plug(this, "poseOrientation", "/pose/orientation"); 46 | oscP5.plug(this, "posePosition", "/pose/position"); 47 | oscP5.plug(this, "poseScale", "/pose/scale"); 48 | } 49 | 50 | void draw() { 51 | background(255); 52 | stroke(0); 53 | if (found) { 54 | //translate(posePosition.x, posePosition.y); 55 | translate(width/2, height/2); 56 | scale(poseScale); 57 | noFill(); 58 | // ellipse(0,0, 3,3); 59 | ellipse(-20, eyeLeftHeight * -9, 20, 7); 60 | ellipse(20, eyeRightHeight * -9, 20, 7); 61 | ellipse(0, 20, mouthWidth* 3, mouthHeight * 3); 62 | ellipse(-5, nostrilHeight * -1, 7, 3); 63 | ellipse(5, nostrilHeight * -1, 7, 3); 64 | rectMode(CENTER); 65 | fill(0); 66 | rect(-20, leftEyebrowHeight * -5, 25, 5); 67 | rect(20, rightEyebrowHeight * -5, 25, 5); 68 | } 69 | } 70 | 71 | public void mouthWidthReceived(float w) { 72 | //println("mouth Width: " + w); 73 | mouthWidth = w; 74 | } 75 | 76 | public void mouthHeightReceived(float h) { 77 | //println("mouth height: " + h); 78 | mouthHeight = h; 79 | } 80 | 81 | public void eyebrowLeftReceived(float h) { 82 | //println("eyebrow left: " + h); 83 | leftEyebrowHeight = h; 84 | } 85 | 86 | public void eyebrowRightReceived(float h) { 87 | //println("eyebrow right: " + h); 88 | rightEyebrowHeight = h; 89 | } 90 | 91 | public void eyeLeftReceived(float h) { 92 | //println("eye left: " + h); 93 | eyeLeftHeight = h; 94 | } 95 | 96 | public void eyeRightReceived(float h) { 97 | //println("eye right: " + h); 98 | eyeRightHeight = h; 99 | } 100 | 101 | public void jawReceived(float h) { 102 | //println("jaw: " + h); 103 | } 104 | 105 | public void nostrilsReceived(float h) { 106 | //println("nostrils: " + h); 107 | nostrilHeight = h; 108 | } 109 | 110 | public void found(int i) { 111 | //println("found: " + i); // 1 == found, 0 == not found 112 | found = i == 1; 113 | } 114 | 115 | public void posePosition(float x, float y) { 116 | //println("pose position\tX: " + x + " Y: " + y ); 117 | posePosition.x = x; 118 | posePosition.y = y; 119 | } 120 | 121 | public void poseScale(float s) { 122 | //println("scale: " + s); 123 | poseScale = s; 124 | } 125 | 126 | public void poseOrientation(float x, float y, float z) { 127 | //println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z); 128 | poseOrientation.x = x; 129 | poseOrientation.y = y; 130 | poseOrientation.z = z; 131 | } 132 | 133 | 134 | void oscEvent(OscMessage theOscMessage) { 135 | if (theOscMessage.isPlugged()==false) { 136 | //println("UNPLUGGED: " + theOscMessage); 137 | } 138 | } 139 | 140 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/FaceOSCPuppet.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Face It 4 | ITP Fall 2013 5 | Daniel Shiffman 6 | 7 | Based off of the work of Greg Borenstein (https://github.com/atduskgreg) 8 | 9 | This example uses the extended version of FaceOSC to draw 10 | face mesh tracked by FaceOSC and to display the 11 | original camera image via Syphon 12 | 13 | Download the extended version here: 14 | https://github.com/downloads/kylemcdonald/ofxFaceTracker/FaceOSC-osx+Syphon.zip 15 | 16 | Also requires FaceOSC-img 17 | https://www.dropbox.com/s/sh6s75w6cdz8np7/FaceOSC-img.zip 18 | 19 | Download the Syphon library for Processing here: 20 | http://code.google.com/p/syphon-implementations/downloads/list 21 | 22 | NOTE WELL: this example will not work with the standard FaceOSC app, 23 | which does not send the necessary OSC messages with all of the face points 24 | and does not publish the camera feed over Syphon. 25 | 26 | */ 27 | 28 | import oscP5.*; 29 | import netP5.*; 30 | 31 | import codeanticode.syphon.*; 32 | 33 | OscP5 oscP5; 34 | SyphonClient client; 35 | 36 | NetAddress remote; 37 | 38 | PGraphics canvas; 39 | 40 | boolean found; 41 | 42 | 43 | PImage img; 44 | String path; 45 | 46 | void setup() { 47 | size(1280, 480, P3D); 48 | frameRate(30); 49 | 50 | oscP5 = new OscP5(this, 8338); 51 | remote = new NetAddress("localhost", 9005); 52 | 53 | path = dataPath("obama.jpg"); 54 | img = loadImage(path); 55 | requestTracker(path); 56 | 57 | // USE THESE 2 EVENTS TO DRAW THE 58 | // FULL FACE MESH: 59 | oscP5.plug(this, "found", "/found"); 60 | oscP5.plug(this, "loadMesh", "/raw"); 61 | oscP5.plug(this, "loadMeshImg", "/raw_img"); 62 | 63 | 64 | initMesh(); 65 | initMesh2(); 66 | 67 | // initialize the syphon client with the name of the server 68 | client = new SyphonClient(this, "FaceOSC"); 69 | // prep the PGraphics object to receive the camera image 70 | canvas = createGraphics(640, 480, P3D); 71 | } 72 | 73 | void mousePressed() { 74 | path = dataPath("pitt.jpg"); 75 | img = loadImage(path); 76 | requestTracker(path); 77 | } 78 | 79 | void requestTracker(String s) { 80 | OscMessage msg = new OscMessage("/filepath"); 81 | msg.add(s); 82 | oscP5.send(msg, remote); 83 | } 84 | 85 | void draw() { 86 | stroke(255); 87 | background(0); 88 | 89 | image(canvas, 0, 0); 90 | 91 | if (client.available()) { 92 | canvas = client.getGraphics(canvas); 93 | } 94 | 95 | if (found) { 96 | for (Triangle t : triangles) { 97 | noFill(); 98 | stroke(255); 99 | beginShape(TRIANGLES); 100 | vertex(t.a.x, t.a.y); 101 | vertex(t.b.x, t.b.y); 102 | vertex(t.c.x, t.c.y); 103 | endShape(); 104 | } 105 | } 106 | 107 | translate(640, 0); 108 | image(img, 0, 0, 128, 96); 109 | 110 | 111 | for (int i = 0; i < triangles.length; i++) { 112 | Triangle t1 = triangles[i]; 113 | Triangle t2 = triangles2[i]; 114 | noFill(); 115 | noStroke(); 116 | beginShape(TRIANGLES); 117 | texture(img); 118 | vertex(t1.a.x, t1.a.y, t2.a.x, t2.a.y); 119 | vertex(t1.b.x, t1.b.y, t2.b.x, t2.b.y); 120 | vertex(t1.c.x, t1.c.y, t2.c.x, t2.c.y); 121 | endShape(); 122 | } 123 | } 124 | 125 | public void found(int i) { 126 | // println("found: " + i); // 1 == found, 0 == not found 127 | found = i == 1; 128 | } 129 | 130 | void oscEvent(OscMessage theOscMessage) { 131 | if (theOscMessage.isPlugged()==false) { 132 | // For any unplugged messages 133 | // println("UNPLUGGED: " + theOscMessage); 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/ImageMesh.pde: -------------------------------------------------------------------------------- 1 | PVector[] meshPoints2; 2 | Triangle[] triangles2; 3 | 4 | void initMesh2() { 5 | // initialize meshPoints2 array with PVectors 6 | meshPoints2 = new PVector[66]; 7 | for (int i = 0; i < meshPoints.length; i++) { 8 | meshPoints2[i] = new PVector(); 9 | } 10 | /*Table table = loadTable("obama.csv", "header"); 11 | int count = 0; 12 | for (TableRow row : table.rows()) { 13 | meshPoints2[count] = new PVector(row.getFloat("x"), row.getFloat("y")); 14 | count++; 15 | }*/ 16 | 17 | triangles2 = new Triangle[108]; 18 | for (int i = 0; i < triangles2.length; i++) { 19 | triangles2[i] = new Triangle(); 20 | } 21 | 22 | Table table = loadTable("matches.csv", "header"); 23 | for (TableRow row : table.rows()) { 24 | int pi = row.getInt("p"); 25 | int ti = row.getInt("t"); 26 | String s = row.getString("abc"); 27 | 28 | Triangle t = triangles2[ti]; 29 | PVector p = meshPoints2[pi]; 30 | if (s.equals("a")) t.a = p; 31 | if (s.equals("b")) t.b = p; 32 | if (s.equals("c")) t.c = p; 33 | } 34 | } 35 | 36 | // this method was generated programmatically. It's fugly. 37 | public void loadMeshImg(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float x5, float y5, float x6, float y6, float x7, float y7, float x8, float y8, float x9, float y9, float x10, float y10, float x11, float y11, float x12, float y12, float x13, float y13, float x14, float y14, float x15, float y15, float x16, float y16, float x17, float y17, float x18, float y18, float x19, float y19, float x20, float y20, float x21, float y21, float x22, float y22, float x23, float y23, float x24, float y24, float x25, float y25, float x26, float y26, float x27, float y27, float x28, float y28, float x29, float y29, float x30, float y30, float x31, float y31, float x32, float y32, float x33, float y33, float x34, float y34, float x35, float y35, float x36, float y36, float x37, float y37, float x38, float y38, float x39, float y39, float x40, float y40, float x41, float y41, float x42, float y42, float x43, float y43, float x44, float y44, float x45, float y45, float x46, float y46, float x47, float y47, float x48, float y48, float x49, float y49, float x50, float y50, float x51, float y51, float x52, float y52, float x53, float y53, float x54, float y54, float x55, float y55, float x56, float y56, float x57, float y57, float x58, float y58, float x59, float y59, float x60, float y60, float x61, float y61, float x62, float y62, float x63, float y63, float x64, float y64, float x65, float y65) { 38 | //println("loading mesh..."); 39 | 40 | meshPoints2[0].x = x0; 41 | meshPoints2[0].y = y0; 42 | meshPoints2[1].x = x1; 43 | meshPoints2[1].y = y1; 44 | meshPoints2[2].x = x2; 45 | meshPoints2[2].y = y2; 46 | meshPoints2[3].x = x3; 47 | meshPoints2[3].y = y3; 48 | meshPoints2[4].x = x4; 49 | meshPoints2[4].y = y4; 50 | meshPoints2[5].x = x5; 51 | meshPoints2[5].y = y5; 52 | meshPoints2[6].x = x6; 53 | meshPoints2[6].y = y6; 54 | meshPoints2[7].x = x7; 55 | meshPoints2[7].y = y7; 56 | meshPoints2[8].x = x8; 57 | meshPoints2[8].y = y8; 58 | meshPoints2[9].x = x9; 59 | meshPoints2[9].y = y9; 60 | meshPoints2[10].x = x10; 61 | meshPoints2[10].y = y10; 62 | meshPoints2[11].x = x11; 63 | meshPoints2[11].y = y11; 64 | meshPoints2[12].x = x12; 65 | meshPoints2[12].y = y12; 66 | meshPoints2[13].x = x13; 67 | meshPoints2[13].y = y13; 68 | meshPoints2[14].x = x14; 69 | meshPoints2[14].y = y14; 70 | meshPoints2[15].x = x15; 71 | meshPoints2[15].y = y15; 72 | meshPoints2[16].x = x16; 73 | meshPoints2[16].y = y16; 74 | meshPoints2[17].x = x17; 75 | meshPoints2[17].y = y17; 76 | meshPoints2[18].x = x18; 77 | meshPoints2[18].y = y18; 78 | meshPoints2[19].x = x19; 79 | meshPoints2[19].y = y19; 80 | meshPoints2[20].x = x20; 81 | meshPoints2[20].y = y20; 82 | meshPoints2[21].x = x21; 83 | meshPoints2[21].y = y21; 84 | meshPoints2[22].x = x22; 85 | meshPoints2[22].y = y22; 86 | meshPoints2[23].x = x23; 87 | meshPoints2[23].y = y23; 88 | meshPoints2[24].x = x24; 89 | meshPoints2[24].y = y24; 90 | meshPoints2[25].x = x25; 91 | meshPoints2[25].y = y25; 92 | meshPoints2[26].x = x26; 93 | meshPoints2[26].y = y26; 94 | meshPoints2[27].x = x27; 95 | meshPoints2[27].y = y27; 96 | meshPoints2[28].x = x28; 97 | meshPoints2[28].y = y28; 98 | meshPoints2[29].x = x29; 99 | meshPoints2[29].y = y29; 100 | meshPoints2[30].x = x30; 101 | meshPoints2[30].y = y30; 102 | meshPoints2[31].x = x31; 103 | meshPoints2[31].y = y31; 104 | meshPoints2[32].x = x32; 105 | meshPoints2[32].y = y32; 106 | meshPoints2[33].x = x33; 107 | meshPoints2[33].y = y33; 108 | meshPoints2[34].x = x34; 109 | meshPoints2[34].y = y34; 110 | meshPoints2[35].x = x35; 111 | meshPoints2[35].y = y35; 112 | meshPoints2[36].x = x36; 113 | meshPoints2[36].y = y36; 114 | meshPoints2[37].x = x37; 115 | meshPoints2[37].y = y37; 116 | meshPoints2[38].x = x38; 117 | meshPoints2[38].y = y38; 118 | meshPoints2[39].x = x39; 119 | meshPoints2[39].y = y39; 120 | meshPoints2[40].x = x40; 121 | meshPoints2[40].y = y40; 122 | meshPoints2[41].x = x41; 123 | meshPoints2[41].y = y41; 124 | meshPoints2[42].x = x42; 125 | meshPoints2[42].y = y42; 126 | meshPoints2[43].x = x43; 127 | meshPoints2[43].y = y43; 128 | meshPoints2[44].x = x44; 129 | meshPoints2[44].y = y44; 130 | meshPoints2[45].x = x45; 131 | meshPoints2[45].y = y45; 132 | meshPoints2[46].x = x46; 133 | meshPoints2[46].y = y46; 134 | meshPoints2[47].x = x47; 135 | meshPoints2[47].y = y47; 136 | meshPoints2[48].x = x48; 137 | meshPoints2[48].y = y48; 138 | meshPoints2[49].x = x49; 139 | meshPoints2[49].y = y49; 140 | meshPoints2[50].x = x50; 141 | meshPoints2[50].y = y50; 142 | meshPoints2[51].x = x51; 143 | meshPoints2[51].y = y51; 144 | meshPoints2[52].x = x52; 145 | meshPoints2[52].y = y52; 146 | meshPoints2[53].x = x53; 147 | meshPoints2[53].y = y53; 148 | meshPoints2[54].x = x54; 149 | meshPoints2[54].y = y54; 150 | meshPoints2[55].x = x55; 151 | meshPoints2[55].y = y55; 152 | meshPoints2[56].x = x56; 153 | meshPoints2[56].y = y56; 154 | meshPoints2[57].x = x57; 155 | meshPoints2[57].y = y57; 156 | meshPoints2[58].x = x58; 157 | meshPoints2[58].y = y58; 158 | meshPoints2[59].x = x59; 159 | meshPoints2[59].y = y59; 160 | meshPoints2[60].x = x60; 161 | meshPoints2[60].y = y60; 162 | meshPoints2[61].x = x61; 163 | meshPoints2[61].y = y61; 164 | meshPoints2[62].x = x62; 165 | meshPoints2[62].y = y62; 166 | meshPoints2[63].x = x63; 167 | meshPoints2[63].y = y63; 168 | meshPoints2[64].x = x64; 169 | meshPoints2[64].y = y64; 170 | meshPoints2[65].x = x65; 171 | meshPoints2[65].y = y65; 172 | } 173 | 174 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/MeshData.pde: -------------------------------------------------------------------------------- 1 | PVector[] meshPoints; 2 | Triangle[] triangles; 3 | 4 | void initMesh() { 5 | // initialize meshPoints array with PVectors 6 | meshPoints = new PVector[66]; 7 | for (int i = 0; i < meshPoints.length; i++) { 8 | meshPoints[i] = new PVector(); 9 | } 10 | 11 | triangles = new Triangle[108]; 12 | for (int i = 0; i < triangles.length; i++) { 13 | triangles[i] = new Triangle(); 14 | } 15 | 16 | 17 | Table table = loadTable("matches.csv","header"); 18 | for (TableRow row : table.rows()) { 19 | int pi = row.getInt("p"); 20 | int ti = row.getInt("t"); 21 | String s = row.getString("abc"); 22 | 23 | Triangle t = triangles[ti]; 24 | PVector p = meshPoints[pi]; 25 | if (s.equals("a")) t.a = p; 26 | if (s.equals("b")) t.b = p; 27 | if (s.equals("c")) t.c = p; 28 | } 29 | } 30 | 31 | // this method was generated programmatically. It's fugly. 32 | public void loadMesh(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float x5, float y5, float x6, float y6, float x7, float y7, float x8, float y8, float x9, float y9, float x10, float y10, float x11, float y11, float x12, float y12, float x13, float y13, float x14, float y14, float x15, float y15, float x16, float y16, float x17, float y17, float x18, float y18, float x19, float y19, float x20, float y20, float x21, float y21, float x22, float y22, float x23, float y23, float x24, float y24, float x25, float y25, float x26, float y26, float x27, float y27, float x28, float y28, float x29, float y29, float x30, float y30, float x31, float y31, float x32, float y32, float x33, float y33, float x34, float y34, float x35, float y35, float x36, float y36, float x37, float y37, float x38, float y38, float x39, float y39, float x40, float y40, float x41, float y41, float x42, float y42, float x43, float y43, float x44, float y44, float x45, float y45, float x46, float y46, float x47, float y47, float x48, float y48, float x49, float y49, float x50, float y50, float x51, float y51, float x52, float y52, float x53, float y53, float x54, float y54, float x55, float y55, float x56, float y56, float x57, float y57, float x58, float y58, float x59, float y59, float x60, float y60, float x61, float y61, float x62, float y62, float x63, float y63, float x64, float y64, float x65, float y65) { 33 | //println("loading mesh..."); 34 | 35 | meshPoints[0].x = x0; 36 | meshPoints[0].y = y0; 37 | meshPoints[1].x = x1; 38 | meshPoints[1].y = y1; 39 | meshPoints[2].x = x2; 40 | meshPoints[2].y = y2; 41 | meshPoints[3].x = x3; 42 | meshPoints[3].y = y3; 43 | meshPoints[4].x = x4; 44 | meshPoints[4].y = y4; 45 | meshPoints[5].x = x5; 46 | meshPoints[5].y = y5; 47 | meshPoints[6].x = x6; 48 | meshPoints[6].y = y6; 49 | meshPoints[7].x = x7; 50 | meshPoints[7].y = y7; 51 | meshPoints[8].x = x8; 52 | meshPoints[8].y = y8; 53 | meshPoints[9].x = x9; 54 | meshPoints[9].y = y9; 55 | meshPoints[10].x = x10; 56 | meshPoints[10].y = y10; 57 | meshPoints[11].x = x11; 58 | meshPoints[11].y = y11; 59 | meshPoints[12].x = x12; 60 | meshPoints[12].y = y12; 61 | meshPoints[13].x = x13; 62 | meshPoints[13].y = y13; 63 | meshPoints[14].x = x14; 64 | meshPoints[14].y = y14; 65 | meshPoints[15].x = x15; 66 | meshPoints[15].y = y15; 67 | meshPoints[16].x = x16; 68 | meshPoints[16].y = y16; 69 | meshPoints[17].x = x17; 70 | meshPoints[17].y = y17; 71 | meshPoints[18].x = x18; 72 | meshPoints[18].y = y18; 73 | meshPoints[19].x = x19; 74 | meshPoints[19].y = y19; 75 | meshPoints[20].x = x20; 76 | meshPoints[20].y = y20; 77 | meshPoints[21].x = x21; 78 | meshPoints[21].y = y21; 79 | meshPoints[22].x = x22; 80 | meshPoints[22].y = y22; 81 | meshPoints[23].x = x23; 82 | meshPoints[23].y = y23; 83 | meshPoints[24].x = x24; 84 | meshPoints[24].y = y24; 85 | meshPoints[25].x = x25; 86 | meshPoints[25].y = y25; 87 | meshPoints[26].x = x26; 88 | meshPoints[26].y = y26; 89 | meshPoints[27].x = x27; 90 | meshPoints[27].y = y27; 91 | meshPoints[28].x = x28; 92 | meshPoints[28].y = y28; 93 | meshPoints[29].x = x29; 94 | meshPoints[29].y = y29; 95 | meshPoints[30].x = x30; 96 | meshPoints[30].y = y30; 97 | meshPoints[31].x = x31; 98 | meshPoints[31].y = y31; 99 | meshPoints[32].x = x32; 100 | meshPoints[32].y = y32; 101 | meshPoints[33].x = x33; 102 | meshPoints[33].y = y33; 103 | meshPoints[34].x = x34; 104 | meshPoints[34].y = y34; 105 | meshPoints[35].x = x35; 106 | meshPoints[35].y = y35; 107 | meshPoints[36].x = x36; 108 | meshPoints[36].y = y36; 109 | meshPoints[37].x = x37; 110 | meshPoints[37].y = y37; 111 | meshPoints[38].x = x38; 112 | meshPoints[38].y = y38; 113 | meshPoints[39].x = x39; 114 | meshPoints[39].y = y39; 115 | meshPoints[40].x = x40; 116 | meshPoints[40].y = y40; 117 | meshPoints[41].x = x41; 118 | meshPoints[41].y = y41; 119 | meshPoints[42].x = x42; 120 | meshPoints[42].y = y42; 121 | meshPoints[43].x = x43; 122 | meshPoints[43].y = y43; 123 | meshPoints[44].x = x44; 124 | meshPoints[44].y = y44; 125 | meshPoints[45].x = x45; 126 | meshPoints[45].y = y45; 127 | meshPoints[46].x = x46; 128 | meshPoints[46].y = y46; 129 | meshPoints[47].x = x47; 130 | meshPoints[47].y = y47; 131 | meshPoints[48].x = x48; 132 | meshPoints[48].y = y48; 133 | meshPoints[49].x = x49; 134 | meshPoints[49].y = y49; 135 | meshPoints[50].x = x50; 136 | meshPoints[50].y = y50; 137 | meshPoints[51].x = x51; 138 | meshPoints[51].y = y51; 139 | meshPoints[52].x = x52; 140 | meshPoints[52].y = y52; 141 | meshPoints[53].x = x53; 142 | meshPoints[53].y = y53; 143 | meshPoints[54].x = x54; 144 | meshPoints[54].y = y54; 145 | meshPoints[55].x = x55; 146 | meshPoints[55].y = y55; 147 | meshPoints[56].x = x56; 148 | meshPoints[56].y = y56; 149 | meshPoints[57].x = x57; 150 | meshPoints[57].y = y57; 151 | meshPoints[58].x = x58; 152 | meshPoints[58].y = y58; 153 | meshPoints[59].x = x59; 154 | meshPoints[59].y = y59; 155 | meshPoints[60].x = x60; 156 | meshPoints[60].y = y60; 157 | meshPoints[61].x = x61; 158 | meshPoints[61].y = y61; 159 | meshPoints[62].x = x62; 160 | meshPoints[62].y = y62; 161 | meshPoints[63].x = x63; 162 | meshPoints[63].y = y63; 163 | meshPoints[64].x = x64; 164 | meshPoints[64].y = y64; 165 | meshPoints[65].x = x65; 166 | meshPoints[65].y = y65; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/Triangle.pde: -------------------------------------------------------------------------------- 1 | class Triangle { 2 | PVector a; 3 | PVector b; 4 | PVector c; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/data/matches.csv: -------------------------------------------------------------------------------- 1 | p,t,abc 2 | 0,64,a 3 | 0,66,a 4 | 1,64,b 5 | 1,80,a 6 | 1,82,a 7 | 2,48,a 8 | 2,49,a 9 | 2,82,b 10 | 2,83,a 11 | 3,47,a 12 | 3,48,b 13 | 4,46,a 14 | 4,47,b 15 | 5,46,b 16 | 5,50,a 17 | 6,30,a 18 | 6,32,a 19 | 6,50,b 20 | 7,26,a 21 | 7,29,a 22 | 7,30,b 23 | 8,23,a 24 | 8,24,a 25 | 8,29,b 26 | 9,18,a 27 | 9,20,a 28 | 9,24,b 29 | 10,17,a 30 | 10,18,b 31 | 10,38,a 32 | 10,42,a 33 | 11,42,b 34 | 11,43,a 35 | 12,41,a 36 | 12,43,b 37 | 13,41,b 38 | 13,44,a 39 | 13,61,a 40 | 14,61,b 41 | 14,98,a 42 | 14,100,a 43 | 15,94,a 44 | 15,99,a 45 | 15,100,b 46 | 16,94,b 47 | 16,96,a 48 | 17,65,a 49 | 17,66,b 50 | 18,65,b 51 | 18,67,a 52 | 18,68,a 53 | 19,54,a 54 | 19,55,a 55 | 19,68,b 56 | 19,69,a 57 | 19,71,a 58 | 20,51,a 59 | 20,53,a 60 | 20,54,b 61 | 20,70,a 62 | 20,71,b 63 | 21,51,b 64 | 21,52,a 65 | 21,56,a 66 | 21,70,b 67 | 21,72,a 68 | 21,76,a 69 | 22,52,b 70 | 22,56,b 71 | 22,87,a 72 | 22,89,a 73 | 22,90,a 74 | 23,51,c 75 | 23,52,c 76 | 23,53,b 77 | 23,90,b 78 | 23,92,a 79 | 23,93,a 80 | 24,53,c 81 | 24,54,c 82 | 24,55,b 83 | 24,91,a 84 | 24,92,b 85 | 25,55,c 86 | 25,91,b 87 | 25,95,a 88 | 25,97,a 89 | 26,96,b 90 | 26,97,b 91 | 27,56,c 92 | 27,72,b 93 | 27,74,a 94 | 27,87,b 95 | 27,88,a 96 | 28,73,a 97 | 28,74,b 98 | 28,86,a 99 | 28,88,b 100 | 29,57,a 101 | 29,63,a 102 | 29,73,b 103 | 29,75,a 104 | 29,86,b 105 | 29,103,a 106 | 29,104,a 107 | 30,57,b 108 | 30,58,a 109 | 30,59,a 110 | 30,60,a 111 | 30,62,a 112 | 30,63,b 113 | 31,0,a 114 | 31,4,a 115 | 31,45,a 116 | 31,49,b 117 | 31,57,c 118 | 31,58,b 119 | 31,75,b 120 | 31,77,a 121 | 31,81,a 122 | 31,83,b 123 | 32,0,b 124 | 32,1,a 125 | 32,7,a 126 | 32,58,c 127 | 32,59,b 128 | 33,7,b 129 | 33,8,a 130 | 33,59,c 131 | 33,60,b 132 | 34,6,a 133 | 34,8,b 134 | 34,10,a 135 | 34,60,c 136 | 34,62,b 137 | 35,10,b 138 | 35,11,a 139 | 35,40,a 140 | 35,44,b 141 | 35,61,c 142 | 35,62,c 143 | 35,63,c 144 | 35,98,b 145 | 35,104,b 146 | 35,106,a 147 | 36,64,c 148 | 36,65,c 149 | 36,66,c 150 | 36,67,b 151 | 36,80,b 152 | 36,84,a 153 | 37,67,c 154 | 37,68,c 155 | 37,69,b 156 | 37,78,a 157 | 37,84,b 158 | 37,85,a 159 | 38,69,c 160 | 38,70,c 161 | 38,71,c 162 | 38,76,b 163 | 38,78,b 164 | 38,79,a 165 | 39,72,c 166 | 39,73,c 167 | 39,74,c 168 | 39,75,c 169 | 39,76,c 170 | 39,77,b 171 | 39,79,b 172 | 40,77,c 173 | 40,78,c 174 | 40,79,c 175 | 40,81,b 176 | 40,85,b 177 | 41,80,c 178 | 41,81,c 179 | 41,82,c 180 | 41,83,c 181 | 41,84,c 182 | 41,85,c 183 | 42,86,c 184 | 42,87,c 185 | 42,88,c 186 | 42,89,b 187 | 42,103,b 188 | 42,105,a 189 | 43,89,c 190 | 43,90,c 191 | 43,93,b 192 | 43,102,a 193 | 43,105,b 194 | 44,91,c 195 | 44,92,c 196 | 44,93,c 197 | 44,95,b 198 | 44,101,a 199 | 44,102,b 200 | 44,107,a 201 | 45,94,c 202 | 45,95,c 203 | 45,96,c 204 | 45,97,c 205 | 45,99,b 206 | 45,101,b 207 | 46,98,c 208 | 46,99,c 209 | 46,100,c 210 | 46,101,c 211 | 46,106,b 212 | 46,107,b 213 | 47,102,c 214 | 47,103,c 215 | 47,104,c 216 | 47,105,c 217 | 47,106,c 218 | 47,107,c 219 | 48,31,a 220 | 48,32,b 221 | 48,45,b 222 | 48,46,c 223 | 48,47,c 224 | 48,48,c 225 | 48,49,c 226 | 48,50,c 227 | 49,3,a 228 | 49,4,b 229 | 49,25,a 230 | 49,27,a 231 | 49,31,b 232 | 49,34,a 233 | 49,45,c 234 | 50,3,b 235 | 50,5,a 236 | 50,34,b 237 | 50,35,a 238 | 51,15,a 239 | 51,19,a 240 | 51,22,a 241 | 51,28,a 242 | 51,33,a 243 | 51,37,a 244 | 52,12,a 245 | 52,13,a 246 | 52,16,a 247 | 52,21,a 248 | 52,36,a 249 | 53,11,b 250 | 53,13,b 251 | 53,14,a 252 | 53,21,b 253 | 53,39,a 254 | 53,40,b 255 | 54,38,b 256 | 54,39,b 257 | 54,40,c 258 | 54,41,c 259 | 54,42,c 260 | 54,43,c 261 | 54,44,c 262 | 55,14,b 263 | 55,17,b 264 | 55,38,c 265 | 55,39,c 266 | 56,16,b 267 | 56,19,b 268 | 56,36,b 269 | 56,37,b 270 | 57,2,a 271 | 57,5,b 272 | 57,9,a 273 | 57,12,b 274 | 57,33,b 275 | 57,35,b 276 | 57,36,c 277 | 57,37,c 278 | 58,25,b 279 | 58,28,b 280 | 58,33,c 281 | 58,34,c 282 | 58,35,c 283 | 59,26,b 284 | 59,27,b 285 | 59,30,c 286 | 59,31,c 287 | 59,32,c 288 | 60,22,b 289 | 60,23,b 290 | 60,25,c 291 | 60,26,c 292 | 60,27,c 293 | 60,28,c 294 | 60,29,c 295 | 61,15,b 296 | 61,20,b 297 | 61,22,c 298 | 61,23,c 299 | 61,24,c 300 | 62,14,c 301 | 62,15,c 302 | 62,16,c 303 | 62,17,c 304 | 62,18,c 305 | 62,19,c 306 | 62,20,c 307 | 62,21,c 308 | 63,6,b 309 | 63,9,b 310 | 63,10,c 311 | 63,11,c 312 | 63,12,c 313 | 63,13,c 314 | 64,1,b 315 | 64,2,b 316 | 64,6,c 317 | 64,7,c 318 | 64,8,c 319 | 64,9,c 320 | 65,0,c 321 | 65,1,c 322 | 65,2,c 323 | 65,3,c 324 | 65,4,c 325 | 65,5,c 326 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceOSC/FaceOSCPuppet/data/obama.jpg -------------------------------------------------------------------------------- /FaceOSC/FaceOSCPuppet/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceOSC/FaceOSCPuppet/data/pitt.jpg -------------------------------------------------------------------------------- /FaceOSC/FaceOSCTriangleMesh/FaceOSCTriangleMesh.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Face It 4 | ITP Fall 2013 5 | Daniel Shiffman 6 | 7 | Based off of the work of Greg Borenstein (https://github.com/atduskgreg) 8 | 9 | This example uses the extended version of FaceOSC to draw 10 | face mesh tracked by FaceOSC and to display the 11 | original camera image via Syphon 12 | 13 | Download the extended version here: 14 | 15 | https://github.com/downloads/kylemcdonald/ofxFaceTracker/FaceOSC-osx+Syphon.zip 16 | 17 | Download the Syphon library for Processing here: 18 | 19 | http://code.google.com/p/syphon-implementations/downloads/list 20 | 21 | NOTE WELL: this example will not work with the standard FaceOSC app, 22 | which does not send the necessary OSC messages with all of the face points 23 | and does not publish the camera feed over Syphon. 24 | 25 | */ 26 | 27 | import oscP5.*; 28 | import codeanticode.syphon.*; 29 | 30 | OscP5 oscP5; 31 | SyphonClient client; 32 | 33 | PGraphics canvas; 34 | 35 | boolean found; 36 | PVector[] meshPoints; 37 | Triangle[] triangles; 38 | 39 | void setup() { 40 | size(640, 480, P3D); 41 | frameRate(30); 42 | 43 | oscP5 = new OscP5(this, 8338); 44 | 45 | // USE THESE 2 EVENTS TO DRAW THE 46 | // FULL FACE MESH: 47 | oscP5.plug(this, "found", "/found"); 48 | oscP5.plug(this, "loadMesh", "/raw"); 49 | 50 | initMesh(); 51 | 52 | // initialize the syphon client with the name of the server 53 | client = new SyphonClient(this, "FaceOSC"); 54 | // prep the PGraphics object to receive the camera image 55 | canvas = createGraphics(640, 480, P3D); 56 | } 57 | 58 | void draw() { 59 | stroke(255); 60 | background(0); 61 | 62 | image(canvas, 0, 0, width, height); 63 | 64 | if (client.available()) { 65 | canvas = client.getGraphics(canvas); 66 | } 67 | 68 | if (found) { 69 | for (Triangle t : triangles) { 70 | noFill(); 71 | stroke(255); 72 | beginShape(TRIANGLES); 73 | vertex(t.a.x,t.a.y); 74 | vertex(t.b.x,t.b.y); 75 | vertex(t.c.x,t.c.y); 76 | endShape(); 77 | } 78 | } 79 | } 80 | 81 | public void found(int i) { 82 | // println("found: " + i); // 1 == found, 0 == not found 83 | found = i == 1; 84 | } 85 | 86 | void oscEvent(OscMessage theOscMessage) { 87 | if (theOscMessage.isPlugged()==false) { 88 | // For any unplugged messages 89 | // println("UNPLUGGED: " + theOscMessage); 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCTriangleMesh/MeshData.pde: -------------------------------------------------------------------------------- 1 | void initMesh() { 2 | // initialize meshPoints array with PVectors 3 | meshPoints = new PVector[66]; 4 | for (int i = 0; i < meshPoints.length; i++) { 5 | meshPoints[i] = new PVector(); 6 | } 7 | 8 | triangles = new Triangle[108]; 9 | for (int i = 0; i < triangles.length; i++) { 10 | triangles[i] = new Triangle(); 11 | } 12 | 13 | 14 | Table table = loadTable("matches.csv","header"); 15 | for (TableRow row : table.rows()) { 16 | int pi = row.getInt("p"); 17 | int ti = row.getInt("t"); 18 | String s = row.getString("abc"); 19 | 20 | Triangle t = triangles[ti]; 21 | PVector p = meshPoints[pi]; 22 | if (s.equals("a")) t.a = p; 23 | if (s.equals("b")) t.b = p; 24 | if (s.equals("c")) t.c = p; 25 | } 26 | } 27 | 28 | // this method was generated programmatically. It's fugly. 29 | public void loadMesh(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float x5, float y5, float x6, float y6, float x7, float y7, float x8, float y8, float x9, float y9, float x10, float y10, float x11, float y11, float x12, float y12, float x13, float y13, float x14, float y14, float x15, float y15, float x16, float y16, float x17, float y17, float x18, float y18, float x19, float y19, float x20, float y20, float x21, float y21, float x22, float y22, float x23, float y23, float x24, float y24, float x25, float y25, float x26, float y26, float x27, float y27, float x28, float y28, float x29, float y29, float x30, float y30, float x31, float y31, float x32, float y32, float x33, float y33, float x34, float y34, float x35, float y35, float x36, float y36, float x37, float y37, float x38, float y38, float x39, float y39, float x40, float y40, float x41, float y41, float x42, float y42, float x43, float y43, float x44, float y44, float x45, float y45, float x46, float y46, float x47, float y47, float x48, float y48, float x49, float y49, float x50, float y50, float x51, float y51, float x52, float y52, float x53, float y53, float x54, float y54, float x55, float y55, float x56, float y56, float x57, float y57, float x58, float y58, float x59, float y59, float x60, float y60, float x61, float y61, float x62, float y62, float x63, float y63, float x64, float y64, float x65, float y65) { 30 | //println("loading mesh..."); 31 | 32 | meshPoints[0].x = x0; 33 | meshPoints[0].y = y0; 34 | meshPoints[1].x = x1; 35 | meshPoints[1].y = y1; 36 | meshPoints[2].x = x2; 37 | meshPoints[2].y = y2; 38 | meshPoints[3].x = x3; 39 | meshPoints[3].y = y3; 40 | meshPoints[4].x = x4; 41 | meshPoints[4].y = y4; 42 | meshPoints[5].x = x5; 43 | meshPoints[5].y = y5; 44 | meshPoints[6].x = x6; 45 | meshPoints[6].y = y6; 46 | meshPoints[7].x = x7; 47 | meshPoints[7].y = y7; 48 | meshPoints[8].x = x8; 49 | meshPoints[8].y = y8; 50 | meshPoints[9].x = x9; 51 | meshPoints[9].y = y9; 52 | meshPoints[10].x = x10; 53 | meshPoints[10].y = y10; 54 | meshPoints[11].x = x11; 55 | meshPoints[11].y = y11; 56 | meshPoints[12].x = x12; 57 | meshPoints[12].y = y12; 58 | meshPoints[13].x = x13; 59 | meshPoints[13].y = y13; 60 | meshPoints[14].x = x14; 61 | meshPoints[14].y = y14; 62 | meshPoints[15].x = x15; 63 | meshPoints[15].y = y15; 64 | meshPoints[16].x = x16; 65 | meshPoints[16].y = y16; 66 | meshPoints[17].x = x17; 67 | meshPoints[17].y = y17; 68 | meshPoints[18].x = x18; 69 | meshPoints[18].y = y18; 70 | meshPoints[19].x = x19; 71 | meshPoints[19].y = y19; 72 | meshPoints[20].x = x20; 73 | meshPoints[20].y = y20; 74 | meshPoints[21].x = x21; 75 | meshPoints[21].y = y21; 76 | meshPoints[22].x = x22; 77 | meshPoints[22].y = y22; 78 | meshPoints[23].x = x23; 79 | meshPoints[23].y = y23; 80 | meshPoints[24].x = x24; 81 | meshPoints[24].y = y24; 82 | meshPoints[25].x = x25; 83 | meshPoints[25].y = y25; 84 | meshPoints[26].x = x26; 85 | meshPoints[26].y = y26; 86 | meshPoints[27].x = x27; 87 | meshPoints[27].y = y27; 88 | meshPoints[28].x = x28; 89 | meshPoints[28].y = y28; 90 | meshPoints[29].x = x29; 91 | meshPoints[29].y = y29; 92 | meshPoints[30].x = x30; 93 | meshPoints[30].y = y30; 94 | meshPoints[31].x = x31; 95 | meshPoints[31].y = y31; 96 | meshPoints[32].x = x32; 97 | meshPoints[32].y = y32; 98 | meshPoints[33].x = x33; 99 | meshPoints[33].y = y33; 100 | meshPoints[34].x = x34; 101 | meshPoints[34].y = y34; 102 | meshPoints[35].x = x35; 103 | meshPoints[35].y = y35; 104 | meshPoints[36].x = x36; 105 | meshPoints[36].y = y36; 106 | meshPoints[37].x = x37; 107 | meshPoints[37].y = y37; 108 | meshPoints[38].x = x38; 109 | meshPoints[38].y = y38; 110 | meshPoints[39].x = x39; 111 | meshPoints[39].y = y39; 112 | meshPoints[40].x = x40; 113 | meshPoints[40].y = y40; 114 | meshPoints[41].x = x41; 115 | meshPoints[41].y = y41; 116 | meshPoints[42].x = x42; 117 | meshPoints[42].y = y42; 118 | meshPoints[43].x = x43; 119 | meshPoints[43].y = y43; 120 | meshPoints[44].x = x44; 121 | meshPoints[44].y = y44; 122 | meshPoints[45].x = x45; 123 | meshPoints[45].y = y45; 124 | meshPoints[46].x = x46; 125 | meshPoints[46].y = y46; 126 | meshPoints[47].x = x47; 127 | meshPoints[47].y = y47; 128 | meshPoints[48].x = x48; 129 | meshPoints[48].y = y48; 130 | meshPoints[49].x = x49; 131 | meshPoints[49].y = y49; 132 | meshPoints[50].x = x50; 133 | meshPoints[50].y = y50; 134 | meshPoints[51].x = x51; 135 | meshPoints[51].y = y51; 136 | meshPoints[52].x = x52; 137 | meshPoints[52].y = y52; 138 | meshPoints[53].x = x53; 139 | meshPoints[53].y = y53; 140 | meshPoints[54].x = x54; 141 | meshPoints[54].y = y54; 142 | meshPoints[55].x = x55; 143 | meshPoints[55].y = y55; 144 | meshPoints[56].x = x56; 145 | meshPoints[56].y = y56; 146 | meshPoints[57].x = x57; 147 | meshPoints[57].y = y57; 148 | meshPoints[58].x = x58; 149 | meshPoints[58].y = y58; 150 | meshPoints[59].x = x59; 151 | meshPoints[59].y = y59; 152 | meshPoints[60].x = x60; 153 | meshPoints[60].y = y60; 154 | meshPoints[61].x = x61; 155 | meshPoints[61].y = y61; 156 | meshPoints[62].x = x62; 157 | meshPoints[62].y = y62; 158 | meshPoints[63].x = x63; 159 | meshPoints[63].y = y63; 160 | meshPoints[64].x = x64; 161 | meshPoints[64].y = y64; 162 | meshPoints[65].x = x65; 163 | meshPoints[65].y = y65; 164 | } 165 | 166 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCTriangleMesh/Triangle.pde: -------------------------------------------------------------------------------- 1 | class Triangle { 2 | PVector a; 3 | PVector b; 4 | PVector c; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /FaceOSC/FaceOSCTriangleMesh/data/matches.csv: -------------------------------------------------------------------------------- 1 | p,t,abc 2 | 0,64,a 3 | 0,66,a 4 | 1,64,b 5 | 1,80,a 6 | 1,82,a 7 | 2,48,a 8 | 2,49,a 9 | 2,82,b 10 | 2,83,a 11 | 3,47,a 12 | 3,48,b 13 | 4,46,a 14 | 4,47,b 15 | 5,46,b 16 | 5,50,a 17 | 6,30,a 18 | 6,32,a 19 | 6,50,b 20 | 7,26,a 21 | 7,29,a 22 | 7,30,b 23 | 8,23,a 24 | 8,24,a 25 | 8,29,b 26 | 9,18,a 27 | 9,20,a 28 | 9,24,b 29 | 10,17,a 30 | 10,18,b 31 | 10,38,a 32 | 10,42,a 33 | 11,42,b 34 | 11,43,a 35 | 12,41,a 36 | 12,43,b 37 | 13,41,b 38 | 13,44,a 39 | 13,61,a 40 | 14,61,b 41 | 14,98,a 42 | 14,100,a 43 | 15,94,a 44 | 15,99,a 45 | 15,100,b 46 | 16,94,b 47 | 16,96,a 48 | 17,65,a 49 | 17,66,b 50 | 18,65,b 51 | 18,67,a 52 | 18,68,a 53 | 19,54,a 54 | 19,55,a 55 | 19,68,b 56 | 19,69,a 57 | 19,71,a 58 | 20,51,a 59 | 20,53,a 60 | 20,54,b 61 | 20,70,a 62 | 20,71,b 63 | 21,51,b 64 | 21,52,a 65 | 21,56,a 66 | 21,70,b 67 | 21,72,a 68 | 21,76,a 69 | 22,52,b 70 | 22,56,b 71 | 22,87,a 72 | 22,89,a 73 | 22,90,a 74 | 23,51,c 75 | 23,52,c 76 | 23,53,b 77 | 23,90,b 78 | 23,92,a 79 | 23,93,a 80 | 24,53,c 81 | 24,54,c 82 | 24,55,b 83 | 24,91,a 84 | 24,92,b 85 | 25,55,c 86 | 25,91,b 87 | 25,95,a 88 | 25,97,a 89 | 26,96,b 90 | 26,97,b 91 | 27,56,c 92 | 27,72,b 93 | 27,74,a 94 | 27,87,b 95 | 27,88,a 96 | 28,73,a 97 | 28,74,b 98 | 28,86,a 99 | 28,88,b 100 | 29,57,a 101 | 29,63,a 102 | 29,73,b 103 | 29,75,a 104 | 29,86,b 105 | 29,103,a 106 | 29,104,a 107 | 30,57,b 108 | 30,58,a 109 | 30,59,a 110 | 30,60,a 111 | 30,62,a 112 | 30,63,b 113 | 31,0,a 114 | 31,4,a 115 | 31,45,a 116 | 31,49,b 117 | 31,57,c 118 | 31,58,b 119 | 31,75,b 120 | 31,77,a 121 | 31,81,a 122 | 31,83,b 123 | 32,0,b 124 | 32,1,a 125 | 32,7,a 126 | 32,58,c 127 | 32,59,b 128 | 33,7,b 129 | 33,8,a 130 | 33,59,c 131 | 33,60,b 132 | 34,6,a 133 | 34,8,b 134 | 34,10,a 135 | 34,60,c 136 | 34,62,b 137 | 35,10,b 138 | 35,11,a 139 | 35,40,a 140 | 35,44,b 141 | 35,61,c 142 | 35,62,c 143 | 35,63,c 144 | 35,98,b 145 | 35,104,b 146 | 35,106,a 147 | 36,64,c 148 | 36,65,c 149 | 36,66,c 150 | 36,67,b 151 | 36,80,b 152 | 36,84,a 153 | 37,67,c 154 | 37,68,c 155 | 37,69,b 156 | 37,78,a 157 | 37,84,b 158 | 37,85,a 159 | 38,69,c 160 | 38,70,c 161 | 38,71,c 162 | 38,76,b 163 | 38,78,b 164 | 38,79,a 165 | 39,72,c 166 | 39,73,c 167 | 39,74,c 168 | 39,75,c 169 | 39,76,c 170 | 39,77,b 171 | 39,79,b 172 | 40,77,c 173 | 40,78,c 174 | 40,79,c 175 | 40,81,b 176 | 40,85,b 177 | 41,80,c 178 | 41,81,c 179 | 41,82,c 180 | 41,83,c 181 | 41,84,c 182 | 41,85,c 183 | 42,86,c 184 | 42,87,c 185 | 42,88,c 186 | 42,89,b 187 | 42,103,b 188 | 42,105,a 189 | 43,89,c 190 | 43,90,c 191 | 43,93,b 192 | 43,102,a 193 | 43,105,b 194 | 44,91,c 195 | 44,92,c 196 | 44,93,c 197 | 44,95,b 198 | 44,101,a 199 | 44,102,b 200 | 44,107,a 201 | 45,94,c 202 | 45,95,c 203 | 45,96,c 204 | 45,97,c 205 | 45,99,b 206 | 45,101,b 207 | 46,98,c 208 | 46,99,c 209 | 46,100,c 210 | 46,101,c 211 | 46,106,b 212 | 46,107,b 213 | 47,102,c 214 | 47,103,c 215 | 47,104,c 216 | 47,105,c 217 | 47,106,c 218 | 47,107,c 219 | 48,31,a 220 | 48,32,b 221 | 48,45,b 222 | 48,46,c 223 | 48,47,c 224 | 48,48,c 225 | 48,49,c 226 | 48,50,c 227 | 49,3,a 228 | 49,4,b 229 | 49,25,a 230 | 49,27,a 231 | 49,31,b 232 | 49,34,a 233 | 49,45,c 234 | 50,3,b 235 | 50,5,a 236 | 50,34,b 237 | 50,35,a 238 | 51,15,a 239 | 51,19,a 240 | 51,22,a 241 | 51,28,a 242 | 51,33,a 243 | 51,37,a 244 | 52,12,a 245 | 52,13,a 246 | 52,16,a 247 | 52,21,a 248 | 52,36,a 249 | 53,11,b 250 | 53,13,b 251 | 53,14,a 252 | 53,21,b 253 | 53,39,a 254 | 53,40,b 255 | 54,38,b 256 | 54,39,b 257 | 54,40,c 258 | 54,41,c 259 | 54,42,c 260 | 54,43,c 261 | 54,44,c 262 | 55,14,b 263 | 55,17,b 264 | 55,38,c 265 | 55,39,c 266 | 56,16,b 267 | 56,19,b 268 | 56,36,b 269 | 56,37,b 270 | 57,2,a 271 | 57,5,b 272 | 57,9,a 273 | 57,12,b 274 | 57,33,b 275 | 57,35,b 276 | 57,36,c 277 | 57,37,c 278 | 58,25,b 279 | 58,28,b 280 | 58,33,c 281 | 58,34,c 282 | 58,35,c 283 | 59,26,b 284 | 59,27,b 285 | 59,30,c 286 | 59,31,c 287 | 59,32,c 288 | 60,22,b 289 | 60,23,b 290 | 60,25,c 291 | 60,26,c 292 | 60,27,c 293 | 60,28,c 294 | 60,29,c 295 | 61,15,b 296 | 61,20,b 297 | 61,22,c 298 | 61,23,c 299 | 61,24,c 300 | 62,14,c 301 | 62,15,c 302 | 62,16,c 303 | 62,17,c 304 | 62,18,c 305 | 62,19,c 306 | 62,20,c 307 | 62,21,c 308 | 63,6,b 309 | 63,9,b 310 | 63,10,c 311 | 63,11,c 312 | 63,12,c 313 | 63,13,c 314 | 64,1,b 315 | 64,2,b 316 | 64,6,c 317 | 64,7,c 318 | 64,8,c 319 | 64,9,c 320 | 65,0,c 321 | 65,1,c 322 | 65,2,c 323 | 65,3,c 324 | 65,4,c 325 | 65,5,c 326 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/MatchTriangles.pde: -------------------------------------------------------------------------------- 1 | 2 | ArrayList triangles; 3 | ArrayList points; 4 | 5 | void setup() { 6 | size(640, 480); 7 | 8 | triangles = new ArrayList(); 9 | points = new ArrayList(); 10 | 11 | Table table = loadTable("positions.csv", "header"); 12 | for (TableRow row : table.rows()) { 13 | PVector v = new PVector(row.getFloat("x"), row.getFloat("y")); 14 | points.add(v); 15 | } 16 | 17 | table = loadTable("triangles.csv", "header"); 18 | for (TableRow row : table.rows()) { 19 | Triangle t = new Triangle(); 20 | t.a = new PVector(row.getFloat("ax"), row.getFloat("ay")); 21 | t.b = new PVector(row.getFloat("bx"), row.getFloat("by")); 22 | t.c = new PVector(row.getFloat("cx"), row.getFloat("cy")); 23 | triangles.add(t); 24 | } 25 | 26 | PrintWriter output = createWriter("matches.csv"); 27 | output.println("p,t,abc"); 28 | 29 | for (int i = 0; i < points.size(); i++) { 30 | PVector p = points.get(i); 31 | for (int j = 0; j < triangles.size(); j++) { 32 | Triangle t = triangles.get(j); 33 | if (equals(p, t.a)) { 34 | //println("Point " + i + " is a of triangle " + j); 35 | output.println(i+","+j+",a"); 36 | } 37 | if (equals(p, t.b)) { 38 | //println("Point " + i + " is b of triangle " + j); 39 | output.println(i+","+j+",b"); 40 | 41 | } 42 | if (equals(p, t.c)) { 43 | //println("Point " + i + " is c of triangle " + j); 44 | output.println(i+","+j+",c"); 45 | } 46 | } 47 | } 48 | 49 | output.flush(); // Writes the remaining data to the file 50 | output.close(); // Finishes the file 51 | } 52 | 53 | boolean equals(PVector a, PVector b) { 54 | if (a.x == b.x && a.y == b.y) { 55 | return true; 56 | } 57 | return false; 58 | } 59 | 60 | void draw() { 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/Mesh.pde: -------------------------------------------------------------------------------- 1 | 2 | class Triangle { 3 | PVector a; 4 | PVector b; 5 | PVector c; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/code/src/triangulate/Edge.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | 6 | package triangulate; 7 | 8 | import processing.core.PVector; 9 | 10 | public class Edge { 11 | 12 | public PVector p1, p2; 13 | 14 | public Edge() { 15 | p1=null; 16 | p2=null; 17 | } 18 | 19 | public Edge(PVector p1, PVector p2) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/code/src/triangulate/EdgePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class EdgePair { 10 | 11 | public Pair p1, p2; 12 | 13 | public EdgePair() { 14 | p1=null; 15 | p2=null; 16 | } 17 | 18 | public EdgePair(Pair p1, Pair p2) { 19 | this.p1 = p1; 20 | this.p2 = p2; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/code/src/triangulate/Pair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Pair { 10 | public PVector a; 11 | public PVector b; 12 | 13 | public Pair(PVector v) { 14 | a = v.get(); 15 | b = v.get(); 16 | } 17 | 18 | public Pair(PVector a_, PVector b_) { 19 | a = a_; 20 | b = b_; 21 | } 22 | 23 | public Pair(float x, float y) { 24 | a = new PVector(x,y); 25 | b = new PVector(x,y); 26 | } 27 | 28 | public Pair(float x, float y, float z) { 29 | a = new PVector(x,y,z); 30 | b = new PVector(x,y,z); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/code/src/triangulate/Triangle.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Triangle { 10 | 11 | public PVector p1, p2, p3; 12 | 13 | public Triangle() { 14 | p1=new PVector(); 15 | p2=new PVector(); 16 | p3=new PVector(); 17 | } 18 | 19 | public Triangle(PVector p1, PVector p2, PVector p3) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | this.p3 = p3; 23 | } 24 | 25 | public boolean sharesVertex(Triangle other) { 26 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 27 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 28 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/code/src/triangulate/TrianglePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class TrianglePair { 10 | 11 | public Pair p1, p2, p3; 12 | 13 | Triangle triangleA; 14 | Triangle mixed; 15 | 16 | public TrianglePair() { 17 | p1=null; 18 | p2=null; 19 | p3=null; 20 | } 21 | 22 | public TrianglePair(Pair p1, Pair p2, Pair p3) { 23 | this.p1 = p1; 24 | this.p2 = p2; 25 | this.p3 = p3; 26 | } 27 | 28 | public boolean sharesVertex(TrianglePair other) { 29 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 30 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 31 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 32 | } 33 | 34 | public Triangle getTriangleA() { 35 | if (triangleA == null) triangleA = new Triangle(p1.a,p2.a,p3.a); 36 | return triangleA; 37 | } 38 | 39 | public Triangle mix(float amt) { 40 | if (mixed == null) mixed = new Triangle(); 41 | 42 | mixed.p1.x = p1.a.x*(1-amt) + p1.b.x*amt; 43 | mixed.p1.y = p1.a.y*(1-amt) + p1.b.y*amt; 44 | 45 | mixed.p2.x = p2.a.x*(1-amt) + p2.b.x*amt; 46 | mixed.p2.y = p2.a.y*(1-amt) + p2.b.y*amt; 47 | 48 | mixed.p3.x = p3.a.x*(1-amt) + p3.b.x*amt; 49 | mixed.p3.y = p3.a.y*(1-amt) + p3.b.y*amt; 50 | 51 | return mixed; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/code/triangulate.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceOSC/triangulation_tests/MatchTriangles/code/triangulate.jar -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/matches.csv: -------------------------------------------------------------------------------- 1 | p,t,abc 2 | 0,64,a 3 | 0,66,a 4 | 1,64,b 5 | 1,80,a 6 | 1,82,a 7 | 2,48,a 8 | 2,49,a 9 | 2,82,b 10 | 2,83,a 11 | 3,47,a 12 | 3,48,b 13 | 4,46,a 14 | 4,47,b 15 | 5,46,b 16 | 5,50,a 17 | 6,30,a 18 | 6,32,a 19 | 6,50,b 20 | 7,26,a 21 | 7,29,a 22 | 7,30,b 23 | 8,23,a 24 | 8,24,a 25 | 8,29,b 26 | 9,18,a 27 | 9,20,a 28 | 9,24,b 29 | 10,17,a 30 | 10,18,b 31 | 10,38,a 32 | 10,42,a 33 | 11,42,b 34 | 11,43,a 35 | 12,41,a 36 | 12,43,b 37 | 13,41,b 38 | 13,44,a 39 | 13,61,a 40 | 14,61,b 41 | 14,98,a 42 | 14,100,a 43 | 15,94,a 44 | 15,99,a 45 | 15,100,b 46 | 16,94,b 47 | 16,96,a 48 | 17,65,a 49 | 17,66,b 50 | 18,65,b 51 | 18,67,a 52 | 18,68,a 53 | 19,54,a 54 | 19,55,a 55 | 19,68,b 56 | 19,69,a 57 | 19,71,a 58 | 20,51,a 59 | 20,53,a 60 | 20,54,b 61 | 20,70,a 62 | 20,71,b 63 | 21,51,b 64 | 21,52,a 65 | 21,56,a 66 | 21,70,b 67 | 21,72,a 68 | 21,76,a 69 | 22,52,b 70 | 22,56,b 71 | 22,87,a 72 | 22,89,a 73 | 22,90,a 74 | 23,51,c 75 | 23,52,c 76 | 23,53,b 77 | 23,90,b 78 | 23,92,a 79 | 23,93,a 80 | 24,53,c 81 | 24,54,c 82 | 24,55,b 83 | 24,91,a 84 | 24,92,b 85 | 25,55,c 86 | 25,91,b 87 | 25,95,a 88 | 25,97,a 89 | 26,96,b 90 | 26,97,b 91 | 27,56,c 92 | 27,72,b 93 | 27,74,a 94 | 27,87,b 95 | 27,88,a 96 | 28,73,a 97 | 28,74,b 98 | 28,86,a 99 | 28,88,b 100 | 29,57,a 101 | 29,63,a 102 | 29,73,b 103 | 29,75,a 104 | 29,86,b 105 | 29,103,a 106 | 29,104,a 107 | 30,57,b 108 | 30,58,a 109 | 30,59,a 110 | 30,60,a 111 | 30,62,a 112 | 30,63,b 113 | 31,0,a 114 | 31,4,a 115 | 31,45,a 116 | 31,49,b 117 | 31,57,c 118 | 31,58,b 119 | 31,75,b 120 | 31,77,a 121 | 31,81,a 122 | 31,83,b 123 | 32,0,b 124 | 32,1,a 125 | 32,7,a 126 | 32,58,c 127 | 32,59,b 128 | 33,7,b 129 | 33,8,a 130 | 33,59,c 131 | 33,60,b 132 | 34,6,a 133 | 34,8,b 134 | 34,10,a 135 | 34,60,c 136 | 34,62,b 137 | 35,10,b 138 | 35,11,a 139 | 35,40,a 140 | 35,44,b 141 | 35,61,c 142 | 35,62,c 143 | 35,63,c 144 | 35,98,b 145 | 35,104,b 146 | 35,106,a 147 | 36,64,c 148 | 36,65,c 149 | 36,66,c 150 | 36,67,b 151 | 36,80,b 152 | 36,84,a 153 | 37,67,c 154 | 37,68,c 155 | 37,69,b 156 | 37,78,a 157 | 37,84,b 158 | 37,85,a 159 | 38,69,c 160 | 38,70,c 161 | 38,71,c 162 | 38,76,b 163 | 38,78,b 164 | 38,79,a 165 | 39,72,c 166 | 39,73,c 167 | 39,74,c 168 | 39,75,c 169 | 39,76,c 170 | 39,77,b 171 | 39,79,b 172 | 40,77,c 173 | 40,78,c 174 | 40,79,c 175 | 40,81,b 176 | 40,85,b 177 | 41,80,c 178 | 41,81,c 179 | 41,82,c 180 | 41,83,c 181 | 41,84,c 182 | 41,85,c 183 | 42,86,c 184 | 42,87,c 185 | 42,88,c 186 | 42,89,b 187 | 42,103,b 188 | 42,105,a 189 | 43,89,c 190 | 43,90,c 191 | 43,93,b 192 | 43,102,a 193 | 43,105,b 194 | 44,91,c 195 | 44,92,c 196 | 44,93,c 197 | 44,95,b 198 | 44,101,a 199 | 44,102,b 200 | 44,107,a 201 | 45,94,c 202 | 45,95,c 203 | 45,96,c 204 | 45,97,c 205 | 45,99,b 206 | 45,101,b 207 | 46,98,c 208 | 46,99,c 209 | 46,100,c 210 | 46,101,c 211 | 46,106,b 212 | 46,107,b 213 | 47,102,c 214 | 47,103,c 215 | 47,104,c 216 | 47,105,c 217 | 47,106,c 218 | 47,107,c 219 | 48,31,a 220 | 48,32,b 221 | 48,45,b 222 | 48,46,c 223 | 48,47,c 224 | 48,48,c 225 | 48,49,c 226 | 48,50,c 227 | 49,3,a 228 | 49,4,b 229 | 49,25,a 230 | 49,27,a 231 | 49,31,b 232 | 49,34,a 233 | 49,45,c 234 | 50,3,b 235 | 50,5,a 236 | 50,34,b 237 | 50,35,a 238 | 51,15,a 239 | 51,19,a 240 | 51,22,a 241 | 51,28,a 242 | 51,33,a 243 | 51,37,a 244 | 52,12,a 245 | 52,13,a 246 | 52,16,a 247 | 52,21,a 248 | 52,36,a 249 | 53,11,b 250 | 53,13,b 251 | 53,14,a 252 | 53,21,b 253 | 53,39,a 254 | 53,40,b 255 | 54,38,b 256 | 54,39,b 257 | 54,40,c 258 | 54,41,c 259 | 54,42,c 260 | 54,43,c 261 | 54,44,c 262 | 55,14,b 263 | 55,17,b 264 | 55,38,c 265 | 55,39,c 266 | 56,16,b 267 | 56,19,b 268 | 56,36,b 269 | 56,37,b 270 | 57,2,a 271 | 57,5,b 272 | 57,9,a 273 | 57,12,b 274 | 57,33,b 275 | 57,35,b 276 | 57,36,c 277 | 57,37,c 278 | 58,25,b 279 | 58,28,b 280 | 58,33,c 281 | 58,34,c 282 | 58,35,c 283 | 59,26,b 284 | 59,27,b 285 | 59,30,c 286 | 59,31,c 287 | 59,32,c 288 | 60,22,b 289 | 60,23,b 290 | 60,25,c 291 | 60,26,c 292 | 60,27,c 293 | 60,28,c 294 | 60,29,c 295 | 61,15,b 296 | 61,20,b 297 | 61,22,c 298 | 61,23,c 299 | 61,24,c 300 | 62,14,c 301 | 62,15,c 302 | 62,16,c 303 | 62,17,c 304 | 62,18,c 305 | 62,19,c 306 | 62,20,c 307 | 62,21,c 308 | 63,6,b 309 | 63,9,b 310 | 63,10,c 311 | 63,11,c 312 | 63,12,c 313 | 63,13,c 314 | 64,1,b 315 | 64,2,b 316 | 64,6,c 317 | 64,7,c 318 | 64,8,c 319 | 64,9,c 320 | 65,0,c 321 | 65,1,c 322 | 65,2,c 323 | 65,3,c 324 | 65,4,c 325 | 65,5,c 326 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/positions.csv: -------------------------------------------------------------------------------- 1 | x,y 2 | 299.08893,164.74057 3 | 301.30582,189.55695 4 | 304.26617,214.28986 5 | 307.95618,238.73737 6 | 315.3756,261.25656 7 | 330.6629,278.62048 8 | 350.76428,290.2533 9 | 372.62952,298.12228 10 | 395.25723,300.11725 11 | 416.9297,296.81058 12 | 436.1811,286.09015 13 | 452.3709,271.2371 14 | 464.05197,252.71567 15 | 470.64133,232.60219 16 | 474.09012,212.57681 17 | 476.58157,192.74352 18 | 477.49774,172.76054 19 | 322.48676,138.09131 20 | 336.01453,133.57887 21 | 350.41904,134.08093 22 | 364.184,137.16174 23 | 377.3321,142.04865 24 | 417.4188,146.50505 25 | 428.08154,143.83206 26 | 439.1411,142.32083 27 | 450.58142,142.07886 28 | 461.08148,145.99599 29 | 400.1331,161.07535 30 | 400.39926,175.90788 31 | 400.59744,190.68872 32 | 400.74222,205.39075 33 | 384.6855,217.37843 34 | 392.5355,220.07782 35 | 400.76154,221.46434 36 | 407.25098,220.46706 37 | 413.21912,218.12556 38 | 340.36783,156.78625 39 | 349.261,152.10577 40 | 359.32895,152.16278 41 | 367.3816,158.52827 42 | 358.2363,159.96458 43 | 348.8472,159.60637 44 | 421.32654,162.23616 45 | 429.11005,157.54149 46 | 438.43033,157.67789 47 | 445.938,163.11424 48 | 437.91425,165.13153 49 | 429.27686,164.34004 50 | 363.60416,246.29636 51 | 377.36978,245.90425 52 | 388.75546,245.35033 53 | 398.72083,248.39954 54 | 407.42184,245.8633 55 | 417.01328,246.71156 56 | 428.0971,248.2806 57 | 417.89084,249.16891 58 | 407.00327,246.67743 59 | 398.5081,245.29918 60 | 388.70685,245.954 61 | 376.39044,247.63272 62 | 387.83463,251.43526 63 | 398.74838,254.14891 64 | 408.44757,252.12071 65 | 408.46194,238.75095 66 | 399.20215,235.93478 67 | 388.60944,238.10654 68 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/MatchTriangles/triangles.csv: -------------------------------------------------------------------------------- 1 | ax,ay,bx,by,cx,cy 2 | 384.6855,217.37843,392.5355,220.07782,388.60944,238.10654, 3 | 392.5355,220.07782,399.20215,235.93478,388.60944,238.10654, 4 | 398.5081,245.29918,399.20215,235.93478,388.60944,238.10654, 5 | 377.36978,245.90425,388.75546,245.35033,388.60944,238.10654, 6 | 384.6855,217.37843,377.36978,245.90425,388.60944,238.10654, 7 | 388.75546,245.35033,398.5081,245.29918,388.60944,238.10654, 8 | 407.25098,220.46706,408.46194,238.75095,399.20215,235.93478, 9 | 392.5355,220.07782,400.76154,221.46434,399.20215,235.93478, 10 | 400.76154,221.46434,407.25098,220.46706,399.20215,235.93478, 11 | 398.5081,245.29918,408.46194,238.75095,399.20215,235.93478, 12 | 407.25098,220.46706,413.21912,218.12556,408.46194,238.75095, 13 | 413.21912,218.12556,417.01328,246.71156,408.46194,238.75095, 14 | 407.42184,245.8633,398.5081,245.29918,408.46194,238.75095, 15 | 407.42184,245.8633,417.01328,246.71156,408.46194,238.75095, 16 | 417.01328,246.71156,417.89084,249.16891,408.44757,252.12071, 17 | 398.72083,248.39954,398.74838,254.14891,408.44757,252.12071, 18 | 407.42184,245.8633,407.00327,246.67743,408.44757,252.12071, 19 | 436.1811,286.09015,417.89084,249.16891,408.44757,252.12071, 20 | 416.9297,296.81058,436.1811,286.09015,408.44757,252.12071, 21 | 398.72083,248.39954,407.00327,246.67743,408.44757,252.12071, 22 | 416.9297,296.81058,398.74838,254.14891,408.44757,252.12071, 23 | 407.42184,245.8633,417.01328,246.71156,408.44757,252.12071, 24 | 398.72083,248.39954,387.83463,251.43526,398.74838,254.14891, 25 | 395.25723,300.11725,387.83463,251.43526,398.74838,254.14891, 26 | 395.25723,300.11725,416.9297,296.81058,398.74838,254.14891, 27 | 377.36978,245.90425,388.70685,245.954,387.83463,251.43526, 28 | 372.62952,298.12228,376.39044,247.63272,387.83463,251.43526, 29 | 377.36978,245.90425,376.39044,247.63272,387.83463,251.43526, 30 | 398.72083,248.39954,388.70685,245.954,387.83463,251.43526, 31 | 372.62952,298.12228,395.25723,300.11725,387.83463,251.43526, 32 | 350.76428,290.2533,372.62952,298.12228,376.39044,247.63272, 33 | 363.60416,246.29636,377.36978,245.90425,376.39044,247.63272, 34 | 350.76428,290.2533,363.60416,246.29636,376.39044,247.63272, 35 | 398.72083,248.39954,398.5081,245.29918,388.70685,245.954, 36 | 377.36978,245.90425,388.75546,245.35033,388.70685,245.954, 37 | 388.75546,245.35033,398.5081,245.29918,388.70685,245.954, 38 | 407.42184,245.8633,407.00327,246.67743,398.5081,245.29918, 39 | 398.72083,248.39954,407.00327,246.67743,398.5081,245.29918, 40 | 436.1811,286.09015,428.0971,248.2806,417.89084,249.16891, 41 | 417.01328,246.71156,428.0971,248.2806,417.89084,249.16891, 42 | 413.21912,218.12556,417.01328,246.71156,428.0971,248.2806, 43 | 464.05197,252.71567,470.64133,232.60219,428.0971,248.2806, 44 | 436.1811,286.09015,452.3709,271.2371,428.0971,248.2806, 45 | 452.3709,271.2371,464.05197,252.71567,428.0971,248.2806, 46 | 470.64133,232.60219,413.21912,218.12556,428.0971,248.2806, 47 | 384.6855,217.37843,363.60416,246.29636,377.36978,245.90425, 48 | 315.3756,261.25656,330.6629,278.62048,363.60416,246.29636, 49 | 307.95618,238.73737,315.3756,261.25656,363.60416,246.29636, 50 | 304.26617,214.28986,307.95618,238.73737,363.60416,246.29636, 51 | 304.26617,214.28986,384.6855,217.37843,363.60416,246.29636, 52 | 330.6629,278.62048,350.76428,290.2533,363.60416,246.29636, 53 | 364.184,137.16174,377.3321,142.04865,428.08154,143.83206, 54 | 377.3321,142.04865,417.4188,146.50505,428.08154,143.83206, 55 | 364.184,137.16174,428.08154,143.83206,439.1411,142.32083, 56 | 350.41904,134.08093,364.184,137.16174,439.1411,142.32083, 57 | 350.41904,134.08093,439.1411,142.32083,450.58142,142.07886, 58 | 377.3321,142.04865,417.4188,146.50505,400.1331,161.07535, 59 | 400.59744,190.68872,400.74222,205.39075,384.6855,217.37843, 60 | 400.74222,205.39075,384.6855,217.37843,392.5355,220.07782, 61 | 400.74222,205.39075,392.5355,220.07782,400.76154,221.46434, 62 | 400.74222,205.39075,400.76154,221.46434,407.25098,220.46706, 63 | 470.64133,232.60219,474.09012,212.57681,413.21912,218.12556, 64 | 400.74222,205.39075,407.25098,220.46706,413.21912,218.12556, 65 | 400.59744,190.68872,400.74222,205.39075,413.21912,218.12556, 66 | 299.08893,164.74057,301.30582,189.55695,340.36783,156.78625, 67 | 322.48676,138.09131,336.01453,133.57887,340.36783,156.78625, 68 | 299.08893,164.74057,322.48676,138.09131,340.36783,156.78625, 69 | 336.01453,133.57887,340.36783,156.78625,349.261,152.10577, 70 | 336.01453,133.57887,350.41904,134.08093,349.261,152.10577, 71 | 350.41904,134.08093,349.261,152.10577,359.32895,152.16278, 72 | 364.184,137.16174,377.3321,142.04865,359.32895,152.16278, 73 | 350.41904,134.08093,364.184,137.16174,359.32895,152.16278, 74 | 377.3321,142.04865,400.1331,161.07535,367.3816,158.52827, 75 | 400.39926,175.90788,400.59744,190.68872,367.3816,158.52827, 76 | 400.1331,161.07535,400.39926,175.90788,367.3816,158.52827, 77 | 400.59744,190.68872,384.6855,217.37843,367.3816,158.52827, 78 | 377.3321,142.04865,359.32895,152.16278,367.3816,158.52827, 79 | 384.6855,217.37843,367.3816,158.52827,358.2363,159.96458, 80 | 349.261,152.10577,359.32895,152.16278,358.2363,159.96458, 81 | 359.32895,152.16278,367.3816,158.52827,358.2363,159.96458, 82 | 301.30582,189.55695,340.36783,156.78625,348.8472,159.60637, 83 | 384.6855,217.37843,358.2363,159.96458,348.8472,159.60637, 84 | 301.30582,189.55695,304.26617,214.28986,348.8472,159.60637, 85 | 304.26617,214.28986,384.6855,217.37843,348.8472,159.60637, 86 | 340.36783,156.78625,349.261,152.10577,348.8472,159.60637, 87 | 349.261,152.10577,358.2363,159.96458,348.8472,159.60637, 88 | 400.39926,175.90788,400.59744,190.68872,421.32654,162.23616, 89 | 417.4188,146.50505,400.1331,161.07535,421.32654,162.23616, 90 | 400.1331,161.07535,400.39926,175.90788,421.32654,162.23616, 91 | 417.4188,146.50505,421.32654,162.23616,429.11005,157.54149, 92 | 417.4188,146.50505,428.08154,143.83206,429.11005,157.54149, 93 | 439.1411,142.32083,450.58142,142.07886,438.43033,157.67789, 94 | 428.08154,143.83206,439.1411,142.32083,438.43033,157.67789, 95 | 428.08154,143.83206,429.11005,157.54149,438.43033,157.67789, 96 | 476.58157,192.74352,477.49774,172.76054,445.938,163.11424, 97 | 450.58142,142.07886,438.43033,157.67789,445.938,163.11424, 98 | 477.49774,172.76054,461.08148,145.99599,445.938,163.11424, 99 | 450.58142,142.07886,461.08148,145.99599,445.938,163.11424, 100 | 474.09012,212.57681,413.21912,218.12556,437.91425,165.13153, 101 | 476.58157,192.74352,445.938,163.11424,437.91425,165.13153, 102 | 474.09012,212.57681,476.58157,192.74352,437.91425,165.13153, 103 | 438.43033,157.67789,445.938,163.11424,437.91425,165.13153, 104 | 429.11005,157.54149,438.43033,157.67789,429.27686,164.34004, 105 | 400.59744,190.68872,421.32654,162.23616,429.27686,164.34004, 106 | 400.59744,190.68872,413.21912,218.12556,429.27686,164.34004, 107 | 421.32654,162.23616,429.11005,157.54149,429.27686,164.34004, 108 | 413.21912,218.12556,437.91425,165.13153,429.27686,164.34004, 109 | 438.43033,157.67789,437.91425,165.13153,429.27686,164.34004, 110 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/MeshData.pde: -------------------------------------------------------------------------------- 1 | // LISTS OF INDICES FOR EACH FACE PART 2 | int[] faceOutline = { 3 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 4 | }; 5 | int[] leftEyebrow = { 6 | 17, 18, 19, 20, 21 7 | }; 8 | int[] rightEyebrow = { 9 | 22, 23, 24, 25, 26 10 | }; 11 | int[] nosePart1 = { 12 | 27, 28, 29, 30 13 | }; 14 | int[] nosePart2 = { 15 | 31, 32, 33, 34, 35 16 | }; 17 | int[] leftEye = { 18 | 36, 37, 38, 39, 40, 41, 36 19 | }; 20 | int[] rightEye = { 21 | 42, 43, 44, 45, 46, 47, 42 22 | }; 23 | int[] mouthPart1 = { 24 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 48 25 | }; 26 | int[] mouthPart2 = { 27 | 60, 65 28 | }; 29 | int[] mouthPart3 = { 30 | 60, 61, 62, 63, 64, 65 31 | }; 32 | 33 | ArrayList meshPoints; 34 | 35 | void initMeshPoints() { 36 | // initialize meshPoints array with PVectors 37 | meshPoints = new ArrayList(66); 38 | for (int i = 0; i <66; i++) { 39 | meshPoints.add(new PVector()); 40 | } 41 | } 42 | 43 | // this method was generated programmatically. It's fugly. 44 | public void loadMesh(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float x5, float y5, float x6, float y6, float x7, float y7, float x8, float y8, float x9, float y9, float x10, float y10, float x11, float y11, float x12, float y12, float x13, float y13, float x14, float y14, float x15, float y15, float x16, float y16, float x17, float y17, float x18, float y18, float x19, float y19, float x20, float y20, float x21, float y21, float x22, float y22, float x23, float y23, float x24, float y24, float x25, float y25, float x26, float y26, float x27, float y27, float x28, float y28, float x29, float y29, float x30, float y30, float x31, float y31, float x32, float y32, float x33, float y33, float x34, float y34, float x35, float y35, float x36, float y36, float x37, float y37, float x38, float y38, float x39, float y39, float x40, float y40, float x41, float y41, float x42, float y42, float x43, float y43, float x44, float y44, float x45, float y45, float x46, float y46, float x47, float y47, float x48, float y48, float x49, float y49, float x50, float y50, float x51, float y51, float x52, float y52, float x53, float y53, float x54, float y54, float x55, float y55, float x56, float y56, float x57, float y57, float x58, float y58, float x59, float y59, float x60, float y60, float x61, float y61, float x62, float y62, float x63, float y63, float x64, float y64, float x65, float y65) { 45 | //println("loading mesh..."); 46 | 47 | meshPoints.get(0).x = x0; 48 | meshPoints.get(0).y = y0; 49 | meshPoints.get(1).x = x1; 50 | meshPoints.get(1).y = y1; 51 | meshPoints.get(2).x = x2; 52 | meshPoints.get(2).y = y2; 53 | meshPoints.get(3).x = x3; 54 | meshPoints.get(3).y = y3; 55 | meshPoints.get(4).x = x4; 56 | meshPoints.get(4).y = y4; 57 | meshPoints.get(5).x = x5; 58 | meshPoints.get(5).y = y5; 59 | meshPoints.get(6).x = x6; 60 | meshPoints.get(6).y = y6; 61 | meshPoints.get(7).x = x7; 62 | meshPoints.get(7).y = y7; 63 | meshPoints.get(8).x = x8; 64 | meshPoints.get(8).y = y8; 65 | meshPoints.get(9).x = x9; 66 | meshPoints.get(9).y = y9; 67 | meshPoints.get(10).x = x10; 68 | meshPoints.get(10).y = y10; 69 | meshPoints.get(11).x = x11; 70 | meshPoints.get(11).y = y11; 71 | meshPoints.get(12).x = x12; 72 | meshPoints.get(12).y = y12; 73 | meshPoints.get(13).x = x13; 74 | meshPoints.get(13).y = y13; 75 | meshPoints.get(14).x = x14; 76 | meshPoints.get(14).y = y14; 77 | meshPoints.get(15).x = x15; 78 | meshPoints.get(15).y = y15; 79 | meshPoints.get(16).x = x16; 80 | meshPoints.get(16).y = y16; 81 | meshPoints.get(17).x = x17; 82 | meshPoints.get(17).y = y17; 83 | meshPoints.get(18).x = x18; 84 | meshPoints.get(18).y = y18; 85 | meshPoints.get(19).x = x19; 86 | meshPoints.get(19).y = y19; 87 | meshPoints.get(20).x = x20; 88 | meshPoints.get(20).y = y20; 89 | meshPoints.get(21).x = x21; 90 | meshPoints.get(21).y = y21; 91 | meshPoints.get(22).x = x22; 92 | meshPoints.get(22).y = y22; 93 | meshPoints.get(23).x = x23; 94 | meshPoints.get(23).y = y23; 95 | meshPoints.get(24).x = x24; 96 | meshPoints.get(24).y = y24; 97 | meshPoints.get(25).x = x25; 98 | meshPoints.get(25).y = y25; 99 | meshPoints.get(26).x = x26; 100 | meshPoints.get(26).y = y26; 101 | meshPoints.get(27).x = x27; 102 | meshPoints.get(27).y = y27; 103 | meshPoints.get(28).x = x28; 104 | meshPoints.get(28).y = y28; 105 | meshPoints.get(29).x = x29; 106 | meshPoints.get(29).y = y29; 107 | meshPoints.get(30).x = x30; 108 | meshPoints.get(30).y = y30; 109 | meshPoints.get(31).x = x31; 110 | meshPoints.get(31).y = y31; 111 | meshPoints.get(32).x = x32; 112 | meshPoints.get(32).y = y32; 113 | meshPoints.get(33).x = x33; 114 | meshPoints.get(33).y = y33; 115 | meshPoints.get(34).x = x34; 116 | meshPoints.get(34).y = y34; 117 | meshPoints.get(35).x = x35; 118 | meshPoints.get(35).y = y35; 119 | meshPoints.get(36).x = x36; 120 | meshPoints.get(36).y = y36; 121 | meshPoints.get(37).x = x37; 122 | meshPoints.get(37).y = y37; 123 | meshPoints.get(38).x = x38; 124 | meshPoints.get(38).y = y38; 125 | meshPoints.get(39).x = x39; 126 | meshPoints.get(39).y = y39; 127 | meshPoints.get(40).x = x40; 128 | meshPoints.get(40).y = y40; 129 | meshPoints.get(41).x = x41; 130 | meshPoints.get(41).y = y41; 131 | meshPoints.get(42).x = x42; 132 | meshPoints.get(42).y = y42; 133 | meshPoints.get(43).x = x43; 134 | meshPoints.get(43).y = y43; 135 | meshPoints.get(44).x = x44; 136 | meshPoints.get(44).y = y44; 137 | meshPoints.get(45).x = x45; 138 | meshPoints.get(45).y = y45; 139 | meshPoints.get(46).x = x46; 140 | meshPoints.get(46).y = y46; 141 | meshPoints.get(47).x = x47; 142 | meshPoints.get(47).y = y47; 143 | meshPoints.get(48).x = x48; 144 | meshPoints.get(48).y = y48; 145 | meshPoints.get(49).x = x49; 146 | meshPoints.get(49).y = y49; 147 | meshPoints.get(50).x = x50; 148 | meshPoints.get(50).y = y50; 149 | meshPoints.get(51).x = x51; 150 | meshPoints.get(51).y = y51; 151 | meshPoints.get(52).x = x52; 152 | meshPoints.get(52).y = y52; 153 | meshPoints.get(53).x = x53; 154 | meshPoints.get(53).y = y53; 155 | meshPoints.get(54).x = x54; 156 | meshPoints.get(54).y = y54; 157 | meshPoints.get(55).x = x55; 158 | meshPoints.get(55).y = y55; 159 | meshPoints.get(56).x = x56; 160 | meshPoints.get(56).y = y56; 161 | meshPoints.get(57).x = x57; 162 | meshPoints.get(57).y = y57; 163 | meshPoints.get(58).x = x58; 164 | meshPoints.get(58).y = y58; 165 | meshPoints.get(59).x = x59; 166 | meshPoints.get(59).y = y59; 167 | meshPoints.get(60).x = x60; 168 | meshPoints.get(60).y = y60; 169 | meshPoints.get(61).x = x61; 170 | meshPoints.get(61).y = y61; 171 | meshPoints.get(62).x = x62; 172 | meshPoints.get(62).y = y62; 173 | meshPoints.get(63).x = x63; 174 | meshPoints.get(63).y = y63; 175 | meshPoints.get(64).x = x64; 176 | meshPoints.get(64).y = y64; 177 | meshPoints.get(65).x = x65; 178 | meshPoints.get(65).y = y65; 179 | 180 | saveMesh(); 181 | } 182 | 183 | void saveMesh() { 184 | 185 | PrintWriter output = createWriter("positions.csv"); 186 | for (PVector v : meshPoints) { 187 | output.println(v.x+","+v.y); 188 | } 189 | output.flush(); // Writes the remaining data to the file 190 | output.close(); // Finishes the file 191 | } 192 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/SaveMeshPoints.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This example uses the extended version of FaceOSC to draw 4 | all of the face points tracked by FaceOSC and to display the 5 | original camera image via Syphon 6 | 7 | Download the extended version here: 8 | 9 | https://github.com/downloads/kylemcdonald/ofxFaceTracker/FaceOSC-osx+Syphon.zip 10 | 11 | Download the Syphon library for Processing here: 12 | 13 | http://code.google.com/p/syphon-implementations/downloads/list 14 | 15 | NOTE WELL: this example will not work with the standard FaceOSC app, 16 | which does not send the necessary OSC messages with all of the face points 17 | and does not publish the camera feed over Syphon. 18 | 19 | */ 20 | 21 | import oscP5.*; 22 | import codeanticode.syphon.*; 23 | 24 | OscP5 oscP5; 25 | SyphonClient client; 26 | 27 | PGraphics canvas; 28 | 29 | boolean found; 30 | 31 | // UNUSED VARIABLES FOR OTHER, LESS SPECIFIC FACE OSC DATA 32 | /* 33 | PVector posePosition; 34 | float eyeLeftHeight; 35 | float eyeRightHeight; 36 | float mouthHeight; 37 | float mouthWidth; 38 | float nostrilHeight; 39 | float leftEyebrowHeight; 40 | float rightEyebrowHeight; 41 | float poseScale; 42 | */ 43 | 44 | void setup() { 45 | size(640, 480, P3D); 46 | frameRate(30); 47 | 48 | initMeshPoints(); 49 | 50 | oscP5 = new OscP5(this, 8338); 51 | 52 | // USE THESE 2 EVENTS TO DRAW THE 53 | // FULL FACE MESH: 54 | oscP5.plug(this, "found", "/found"); 55 | oscP5.plug(this, "loadMesh", "/raw"); 56 | 57 | // initialize the syphon client with the name of the server 58 | client = new SyphonClient(this, "FaceOSC"); 59 | // prep the PGraphics object to receive the camera image 60 | canvas = createGraphics(640, 480, P3D); 61 | } 62 | 63 | void draw() { 64 | stroke(255); 65 | background(0); 66 | 67 | image(canvas, 0, 0, width, height); 68 | 69 | if (client.available()) { 70 | canvas = client.getGraphics(canvas); 71 | } 72 | 73 | 74 | 75 | if (found) { 76 | fill(100); 77 | drawFeature(faceOutline); 78 | drawFeature(leftEyebrow); 79 | drawFeature(rightEyebrow); 80 | drawFeature(nosePart1); 81 | drawFeature(nosePart2); 82 | drawFeature(leftEye); 83 | drawFeature(rightEye); 84 | drawFeature(mouthPart1); 85 | drawFeature(mouthPart2); 86 | drawFeature(mouthPart3); 87 | } 88 | } 89 | 90 | void drawFeature(int[] featurePointList) { 91 | for (int i = 0; i < featurePointList.length; i++) { 92 | PVector meshVertex = meshPoints.get(featurePointList[i]); 93 | if (i > 0) { 94 | PVector prevMeshVertex = meshPoints.get(featurePointList[i-1]); 95 | line(meshVertex.x, meshVertex.y, prevMeshVertex.x, prevMeshVertex.y); 96 | } 97 | ellipse(meshVertex.x, meshVertex.y, 3, 3); 98 | } 99 | } 100 | 101 | public void found(int i) { 102 | // println("found: " + i); // 1 == found, 0 == not found 103 | found = i == 1; 104 | } 105 | 106 | void oscEvent(OscMessage theOscMessage) { 107 | if (theOscMessage.isPlugged()==false) { 108 | // For any unplugged messages 109 | // println("UNPLUGGED: " + theOscMessage); 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/code/src/triangulate/Edge.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | 6 | package triangulate; 7 | 8 | import processing.core.PVector; 9 | 10 | public class Edge { 11 | 12 | public PVector p1, p2; 13 | 14 | public Edge() { 15 | p1=null; 16 | p2=null; 17 | } 18 | 19 | public Edge(PVector p1, PVector p2) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/code/src/triangulate/EdgePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class EdgePair { 10 | 11 | public Pair p1, p2; 12 | 13 | public EdgePair() { 14 | p1=null; 15 | p2=null; 16 | } 17 | 18 | public EdgePair(Pair p1, Pair p2) { 19 | this.p1 = p1; 20 | this.p2 = p2; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/code/src/triangulate/Pair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Pair { 10 | public PVector a; 11 | public PVector b; 12 | 13 | public Pair(PVector v) { 14 | a = v.get(); 15 | b = v.get(); 16 | } 17 | 18 | public Pair(PVector a_, PVector b_) { 19 | a = a_; 20 | b = b_; 21 | } 22 | 23 | public Pair(float x, float y) { 24 | a = new PVector(x,y); 25 | b = new PVector(x,y); 26 | } 27 | 28 | public Pair(float x, float y, float z) { 29 | a = new PVector(x,y,z); 30 | b = new PVector(x,y,z); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/code/src/triangulate/Triangle.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Triangle { 10 | 11 | public PVector p1, p2, p3; 12 | 13 | public Triangle() { 14 | p1=new PVector(); 15 | p2=new PVector(); 16 | p3=new PVector(); 17 | } 18 | 19 | public Triangle(PVector p1, PVector p2, PVector p3) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | this.p3 = p3; 23 | } 24 | 25 | public boolean sharesVertex(Triangle other) { 26 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 27 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 28 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/code/src/triangulate/TrianglePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class TrianglePair { 10 | 11 | public Pair p1, p2, p3; 12 | 13 | Triangle triangleA; 14 | Triangle mixed; 15 | 16 | public TrianglePair() { 17 | p1=null; 18 | p2=null; 19 | p3=null; 20 | } 21 | 22 | public TrianglePair(Pair p1, Pair p2, Pair p3) { 23 | this.p1 = p1; 24 | this.p2 = p2; 25 | this.p3 = p3; 26 | } 27 | 28 | public boolean sharesVertex(TrianglePair other) { 29 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 30 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 31 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 32 | } 33 | 34 | public Triangle getTriangleA() { 35 | if (triangleA == null) triangleA = new Triangle(p1.a,p2.a,p3.a); 36 | return triangleA; 37 | } 38 | 39 | public Triangle mix(float amt) { 40 | if (mixed == null) mixed = new Triangle(); 41 | 42 | mixed.p1.x = p1.a.x*(1-amt) + p1.b.x*amt; 43 | mixed.p1.y = p1.a.y*(1-amt) + p1.b.y*amt; 44 | 45 | mixed.p2.x = p2.a.x*(1-amt) + p2.b.x*amt; 46 | mixed.p2.y = p2.a.y*(1-amt) + p2.b.y*amt; 47 | 48 | mixed.p3.x = p3.a.x*(1-amt) + p3.b.x*amt; 49 | mixed.p3.y = p3.a.y*(1-amt) + p3.b.y*amt; 50 | 51 | return mixed; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/code/triangulate.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceOSC/triangulation_tests/SaveMeshPoints/code/triangulate.jar -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveMeshPoints/positions.csv: -------------------------------------------------------------------------------- 1 | 273.00284,236.15356 2 | 274.27264,257.5822 3 | 276.8186,278.90625 4 | 281.4093,301.3605 5 | 289.3966,324.81244 6 | 303.656,345.0016 7 | 322.77628,358.54034 8 | 344.3597,366.8697 9 | 366.48477,370.64752 10 | 386.94547,364.2038 11 | 406.21793,353.1882 12 | 422.4216,337.3617 13 | 432.77585,315.71683 14 | 437.09564,291.79633 15 | 438.89255,269.33878 16 | 439.23306,248.22266 17 | 438.22375,227.14691 18 | 292.8522,224.93005 19 | 301.27393,215.49521 20 | 313.7005,210.78279 21 | 327.33868,211.1869 22 | 340.60687,214.99306 23 | 377.0886,213.25485 24 | 389.48975,208.07715 25 | 402.58197,206.21468 26 | 414.9223,209.53142 27 | 423.57004,217.9964 28 | 360.21664,238.39438 29 | 361.11966,250.49745 30 | 362.04266,262.6381 31 | 362.9907,274.71753 32 | 350.87152,285.75217 33 | 356.90433,287.2259 34 | 363.06894,288.04376 35 | 368.80078,286.5329 36 | 374.32233,284.42752 37 | 313.77716,249.89859 38 | 320.71802,246.25249 39 | 328.9522,244.99623 40 | 337.09433,245.87245 41 | 329.83798,249.65207 42 | 321.77283,250.82803 43 | 382.50598,243.46744 44 | 390.63037,241.78114 45 | 398.90668,242.11877 46 | 405.98843,245.01074 47 | 398.1486,246.78448 48 | 390.07654,246.45186 49 | 336.94257,313.20105 50 | 345.3784,308.7243 51 | 354.2128,305.01685 52 | 363.99802,306.52066 53 | 373.22992,303.89026 54 | 381.84454,306.58884 55 | 389.94846,310.16547 56 | 381.07736,312.64377 57 | 372.24863,313.53857 58 | 364.3037,314.6918 59 | 355.87207,314.51996 60 | 346.44012,314.66357 61 | 355.1478,311.69272 62 | 364.23032,312.9614 63 | 372.65955,310.65463 64 | 372.2778,306.088 65 | 363.89847,306.8203 66 | 354.9367,307.13074 67 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/SaveTriangles.pde: -------------------------------------------------------------------------------- 1 | 2 | 3 | ArrayList points = new ArrayList(); 4 | 5 | import toxi.geom.*; 6 | import toxi.geom.mesh2d.*; 7 | 8 | import toxi.util.*; 9 | import toxi.util.datatypes.*; 10 | 11 | import toxi.processing.*; 12 | 13 | import java.util.*; 14 | 15 | 16 | ToxiclibsSupport gfx; 17 | Voronoi voronoi = new Voronoi(); 18 | 19 | List tris; 20 | 21 | void setup() { 22 | size(640, 480, P3D); 23 | 24 | 25 | gfx = new ToxiclibsSupport(this); 26 | 27 | Table t = loadTable("positions.csv", "header"); 28 | for (TableRow row : t.rows()) { 29 | PVector v = new PVector(row.getFloat("x"), row.getFloat("y")); 30 | points.add(v); 31 | voronoi.addPoint(new Vec2D(v.x, v.y)); 32 | } 33 | 34 | tris = voronoi.getTriangles(); 35 | 36 | } 37 | 38 | void draw() { 39 | background(0); 40 | stroke(255); 41 | fill(255); 42 | for (PVector v : points) { 43 | //ellipse(v.x, v.y, 4, 4); 44 | } 45 | 46 | //mesh.display(); 47 | 48 | for (Polygon2D poly : voronoi.getRegions()) { 49 | //gfx.polygon2D(poly); 50 | } 51 | 52 | stroke(0, 0, 255, 50); 53 | beginShape(TRIANGLES); 54 | for (int i = tris.size()-1; i >= 0; i--) { 55 | Triangle2D t = tris.get(i); 56 | if (t.containsPoint(new Vec2D(mouseX, mouseY))) { 57 | fill(255, 0, 0, 50); 58 | if (mousePressed) { 59 | tris.remove(i); 60 | } 61 | } 62 | else { 63 | fill(0, 0, 255, 50); 64 | } 65 | 66 | gfx.triangle(t, true); 67 | } 68 | endShape(); 69 | 70 | fill(255, 0, 255); 71 | noStroke(); 72 | for (Vec2D c : voronoi.getSites()) { 73 | ellipse(c.x, c.y, 5, 5); 74 | } 75 | } 76 | 77 | void keyPressed() { 78 | saveTriangles(); 79 | } 80 | 81 | 82 | void saveTriangles() { 83 | 84 | 85 | PrintWriter output = createWriter("triangles.csv"); 86 | output.println("ax,ay,bx,by,cx,cy"); 87 | for (Triangle2D t : tris) { 88 | output.println(t.a.x+","+t.a.y+","+t.b.x+","+t.b.y+","+t.c.x+","+t.c.y+","); 89 | } 90 | output.flush(); // Writes the remaining data to the file 91 | output.close(); // Finishes the file 92 | } 93 | 94 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/code/src/triangulate/Edge.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | 6 | package triangulate; 7 | 8 | import processing.core.PVector; 9 | 10 | public class Edge { 11 | 12 | public PVector p1, p2; 13 | 14 | public Edge() { 15 | p1=null; 16 | p2=null; 17 | } 18 | 19 | public Edge(PVector p1, PVector p2) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/code/src/triangulate/EdgePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class EdgePair { 10 | 11 | public Pair p1, p2; 12 | 13 | public EdgePair() { 14 | p1=null; 15 | p2=null; 16 | } 17 | 18 | public EdgePair(Pair p1, Pair p2) { 19 | this.p1 = p1; 20 | this.p2 = p2; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/code/src/triangulate/Pair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Pair { 10 | public PVector a; 11 | public PVector b; 12 | 13 | public Pair(PVector v) { 14 | a = v.get(); 15 | b = v.get(); 16 | } 17 | 18 | public Pair(PVector a_, PVector b_) { 19 | a = a_; 20 | b = b_; 21 | } 22 | 23 | public Pair(float x, float y) { 24 | a = new PVector(x,y); 25 | b = new PVector(x,y); 26 | } 27 | 28 | public Pair(float x, float y, float z) { 29 | a = new PVector(x,y,z); 30 | b = new PVector(x,y,z); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/code/src/triangulate/Triangle.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class Triangle { 10 | 11 | public PVector p1, p2, p3; 12 | 13 | public Triangle() { 14 | p1=new PVector(); 15 | p2=new PVector(); 16 | p3=new PVector(); 17 | } 18 | 19 | public Triangle(PVector p1, PVector p2, PVector p3) { 20 | this.p1 = p1; 21 | this.p2 = p2; 22 | this.p3 = p3; 23 | } 24 | 25 | public boolean sharesVertex(Triangle other) { 26 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 27 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 28 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/code/src/triangulate/TrianglePair.java: -------------------------------------------------------------------------------- 1 | // This triangulation code is from: http://wiki.processing.org/w/Triangulation by Tom Carden 2 | // Based on Paul Bourke: http://paulbourke.net/papers/triangulate/ (first Java conversion by Florian Jenett) 3 | // Modified by Daniel Shiffman for Face Morphing example 4 | 5 | package triangulate; 6 | 7 | import processing.core.PVector; 8 | 9 | public class TrianglePair { 10 | 11 | public Pair p1, p2, p3; 12 | 13 | Triangle triangleA; 14 | Triangle mixed; 15 | 16 | public TrianglePair() { 17 | p1=null; 18 | p2=null; 19 | p3=null; 20 | } 21 | 22 | public TrianglePair(Pair p1, Pair p2, Pair p3) { 23 | this.p1 = p1; 24 | this.p2 = p2; 25 | this.p3 = p3; 26 | } 27 | 28 | public boolean sharesVertex(TrianglePair other) { 29 | return p1 == other.p1 || p1 == other.p2 || p1 == other.p3 || 30 | p2 == other.p1 || p2 == other.p2 || p2 == other.p3 || 31 | p3 == other.p1 || p3 == other.p2 || p3 == other.p3; 32 | } 33 | 34 | public Triangle getTriangleA() { 35 | if (triangleA == null) triangleA = new Triangle(p1.a,p2.a,p3.a); 36 | return triangleA; 37 | } 38 | 39 | public Triangle mix(float amt) { 40 | if (mixed == null) mixed = new Triangle(); 41 | 42 | mixed.p1.x = p1.a.x*(1-amt) + p1.b.x*amt; 43 | mixed.p1.y = p1.a.y*(1-amt) + p1.b.y*amt; 44 | 45 | mixed.p2.x = p2.a.x*(1-amt) + p2.b.x*amt; 46 | mixed.p2.y = p2.a.y*(1-amt) + p2.b.y*amt; 47 | 48 | mixed.p3.x = p3.a.x*(1-amt) + p3.b.x*amt; 49 | mixed.p3.y = p3.a.y*(1-amt) + p3.b.y*amt; 50 | 51 | return mixed; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/code/triangulate.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceOSC/triangulation_tests/SaveTriangles/code/triangulate.jar -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/positions.csv: -------------------------------------------------------------------------------- 1 | x,y 2 | 299.08893,164.74057 3 | 301.30582,189.55695 4 | 304.26617,214.28986 5 | 307.95618,238.73737 6 | 315.3756,261.25656 7 | 330.6629,278.62048 8 | 350.76428,290.2533 9 | 372.62952,298.12228 10 | 395.25723,300.11725 11 | 416.9297,296.81058 12 | 436.1811,286.09015 13 | 452.3709,271.2371 14 | 464.05197,252.71567 15 | 470.64133,232.60219 16 | 474.09012,212.57681 17 | 476.58157,192.74352 18 | 477.49774,172.76054 19 | 322.48676,138.09131 20 | 336.01453,133.57887 21 | 350.41904,134.08093 22 | 364.184,137.16174 23 | 377.3321,142.04865 24 | 417.4188,146.50505 25 | 428.08154,143.83206 26 | 439.1411,142.32083 27 | 450.58142,142.07886 28 | 461.08148,145.99599 29 | 400.1331,161.07535 30 | 400.39926,175.90788 31 | 400.59744,190.68872 32 | 400.74222,205.39075 33 | 384.6855,217.37843 34 | 392.5355,220.07782 35 | 400.76154,221.46434 36 | 407.25098,220.46706 37 | 413.21912,218.12556 38 | 340.36783,156.78625 39 | 349.261,152.10577 40 | 359.32895,152.16278 41 | 367.3816,158.52827 42 | 358.2363,159.96458 43 | 348.8472,159.60637 44 | 421.32654,162.23616 45 | 429.11005,157.54149 46 | 438.43033,157.67789 47 | 445.938,163.11424 48 | 437.91425,165.13153 49 | 429.27686,164.34004 50 | 363.60416,246.29636 51 | 377.36978,245.90425 52 | 388.75546,245.35033 53 | 398.72083,248.39954 54 | 407.42184,245.8633 55 | 417.01328,246.71156 56 | 428.0971,248.2806 57 | 417.89084,249.16891 58 | 407.00327,246.67743 59 | 398.5081,245.29918 60 | 388.70685,245.954 61 | 376.39044,247.63272 62 | 387.83463,251.43526 63 | 398.74838,254.14891 64 | 408.44757,252.12071 65 | 408.46194,238.75095 66 | 399.20215,235.93478 67 | 388.60944,238.10654 68 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/sketch.properties: -------------------------------------------------------------------------------- 1 | mode.id=processing.mode.java.JavaMode 2 | mode=Java 3 | -------------------------------------------------------------------------------- /FaceOSC/triangulation_tests/SaveTriangles/triangles.csv: -------------------------------------------------------------------------------- 1 | ax,ay,bx,by,cx,cy 2 | 384.6855,217.37843,392.5355,220.07782,388.60944,238.10654, 3 | 392.5355,220.07782,399.20215,235.93478,388.60944,238.10654, 4 | 398.5081,245.29918,399.20215,235.93478,388.60944,238.10654, 5 | 377.36978,245.90425,388.75546,245.35033,388.60944,238.10654, 6 | 384.6855,217.37843,377.36978,245.90425,388.60944,238.10654, 7 | 388.75546,245.35033,398.5081,245.29918,388.60944,238.10654, 8 | 407.25098,220.46706,408.46194,238.75095,399.20215,235.93478, 9 | 392.5355,220.07782,400.76154,221.46434,399.20215,235.93478, 10 | 400.76154,221.46434,407.25098,220.46706,399.20215,235.93478, 11 | 398.5081,245.29918,408.46194,238.75095,399.20215,235.93478, 12 | 407.25098,220.46706,413.21912,218.12556,408.46194,238.75095, 13 | 413.21912,218.12556,417.01328,246.71156,408.46194,238.75095, 14 | 407.42184,245.8633,398.5081,245.29918,408.46194,238.75095, 15 | 407.42184,245.8633,417.01328,246.71156,408.46194,238.75095, 16 | 417.01328,246.71156,417.89084,249.16891,408.44757,252.12071, 17 | 398.72083,248.39954,398.74838,254.14891,408.44757,252.12071, 18 | 407.42184,245.8633,407.00327,246.67743,408.44757,252.12071, 19 | 436.1811,286.09015,417.89084,249.16891,408.44757,252.12071, 20 | 416.9297,296.81058,436.1811,286.09015,408.44757,252.12071, 21 | 398.72083,248.39954,407.00327,246.67743,408.44757,252.12071, 22 | 416.9297,296.81058,398.74838,254.14891,408.44757,252.12071, 23 | 407.42184,245.8633,417.01328,246.71156,408.44757,252.12071, 24 | 398.72083,248.39954,387.83463,251.43526,398.74838,254.14891, 25 | 395.25723,300.11725,387.83463,251.43526,398.74838,254.14891, 26 | 395.25723,300.11725,416.9297,296.81058,398.74838,254.14891, 27 | 377.36978,245.90425,388.70685,245.954,387.83463,251.43526, 28 | 372.62952,298.12228,376.39044,247.63272,387.83463,251.43526, 29 | 377.36978,245.90425,376.39044,247.63272,387.83463,251.43526, 30 | 398.72083,248.39954,388.70685,245.954,387.83463,251.43526, 31 | 372.62952,298.12228,395.25723,300.11725,387.83463,251.43526, 32 | 350.76428,290.2533,372.62952,298.12228,376.39044,247.63272, 33 | 363.60416,246.29636,377.36978,245.90425,376.39044,247.63272, 34 | 350.76428,290.2533,363.60416,246.29636,376.39044,247.63272, 35 | 398.72083,248.39954,398.5081,245.29918,388.70685,245.954, 36 | 377.36978,245.90425,388.75546,245.35033,388.70685,245.954, 37 | 388.75546,245.35033,398.5081,245.29918,388.70685,245.954, 38 | 407.42184,245.8633,407.00327,246.67743,398.5081,245.29918, 39 | 398.72083,248.39954,407.00327,246.67743,398.5081,245.29918, 40 | 436.1811,286.09015,428.0971,248.2806,417.89084,249.16891, 41 | 417.01328,246.71156,428.0971,248.2806,417.89084,249.16891, 42 | 413.21912,218.12556,417.01328,246.71156,428.0971,248.2806, 43 | 464.05197,252.71567,470.64133,232.60219,428.0971,248.2806, 44 | 436.1811,286.09015,452.3709,271.2371,428.0971,248.2806, 45 | 452.3709,271.2371,464.05197,252.71567,428.0971,248.2806, 46 | 470.64133,232.60219,413.21912,218.12556,428.0971,248.2806, 47 | 384.6855,217.37843,363.60416,246.29636,377.36978,245.90425, 48 | 315.3756,261.25656,330.6629,278.62048,363.60416,246.29636, 49 | 307.95618,238.73737,315.3756,261.25656,363.60416,246.29636, 50 | 304.26617,214.28986,307.95618,238.73737,363.60416,246.29636, 51 | 304.26617,214.28986,384.6855,217.37843,363.60416,246.29636, 52 | 330.6629,278.62048,350.76428,290.2533,363.60416,246.29636, 53 | 364.184,137.16174,377.3321,142.04865,428.08154,143.83206, 54 | 377.3321,142.04865,417.4188,146.50505,428.08154,143.83206, 55 | 364.184,137.16174,428.08154,143.83206,439.1411,142.32083, 56 | 350.41904,134.08093,364.184,137.16174,439.1411,142.32083, 57 | 350.41904,134.08093,439.1411,142.32083,450.58142,142.07886, 58 | 377.3321,142.04865,417.4188,146.50505,400.1331,161.07535, 59 | 400.59744,190.68872,400.74222,205.39075,384.6855,217.37843, 60 | 400.74222,205.39075,384.6855,217.37843,392.5355,220.07782, 61 | 400.74222,205.39075,392.5355,220.07782,400.76154,221.46434, 62 | 400.74222,205.39075,400.76154,221.46434,407.25098,220.46706, 63 | 470.64133,232.60219,474.09012,212.57681,413.21912,218.12556, 64 | 400.74222,205.39075,407.25098,220.46706,413.21912,218.12556, 65 | 400.59744,190.68872,400.74222,205.39075,413.21912,218.12556, 66 | 299.08893,164.74057,301.30582,189.55695,340.36783,156.78625, 67 | 322.48676,138.09131,336.01453,133.57887,340.36783,156.78625, 68 | 299.08893,164.74057,322.48676,138.09131,340.36783,156.78625, 69 | 336.01453,133.57887,340.36783,156.78625,349.261,152.10577, 70 | 336.01453,133.57887,350.41904,134.08093,349.261,152.10577, 71 | 350.41904,134.08093,349.261,152.10577,359.32895,152.16278, 72 | 364.184,137.16174,377.3321,142.04865,359.32895,152.16278, 73 | 350.41904,134.08093,364.184,137.16174,359.32895,152.16278, 74 | 377.3321,142.04865,400.1331,161.07535,367.3816,158.52827, 75 | 400.39926,175.90788,400.59744,190.68872,367.3816,158.52827, 76 | 400.1331,161.07535,400.39926,175.90788,367.3816,158.52827, 77 | 400.59744,190.68872,384.6855,217.37843,367.3816,158.52827, 78 | 377.3321,142.04865,359.32895,152.16278,367.3816,158.52827, 79 | 384.6855,217.37843,367.3816,158.52827,358.2363,159.96458, 80 | 349.261,152.10577,359.32895,152.16278,358.2363,159.96458, 81 | 359.32895,152.16278,367.3816,158.52827,358.2363,159.96458, 82 | 301.30582,189.55695,340.36783,156.78625,348.8472,159.60637, 83 | 384.6855,217.37843,358.2363,159.96458,348.8472,159.60637, 84 | 301.30582,189.55695,304.26617,214.28986,348.8472,159.60637, 85 | 304.26617,214.28986,384.6855,217.37843,348.8472,159.60637, 86 | 340.36783,156.78625,349.261,152.10577,348.8472,159.60637, 87 | 349.261,152.10577,358.2363,159.96458,348.8472,159.60637, 88 | 400.39926,175.90788,400.59744,190.68872,421.32654,162.23616, 89 | 417.4188,146.50505,400.1331,161.07535,421.32654,162.23616, 90 | 400.1331,161.07535,400.39926,175.90788,421.32654,162.23616, 91 | 417.4188,146.50505,421.32654,162.23616,429.11005,157.54149, 92 | 417.4188,146.50505,428.08154,143.83206,429.11005,157.54149, 93 | 439.1411,142.32083,450.58142,142.07886,438.43033,157.67789, 94 | 428.08154,143.83206,439.1411,142.32083,438.43033,157.67789, 95 | 428.08154,143.83206,429.11005,157.54149,438.43033,157.67789, 96 | 476.58157,192.74352,477.49774,172.76054,445.938,163.11424, 97 | 450.58142,142.07886,438.43033,157.67789,445.938,163.11424, 98 | 477.49774,172.76054,461.08148,145.99599,445.938,163.11424, 99 | 450.58142,142.07886,461.08148,145.99599,445.938,163.11424, 100 | 474.09012,212.57681,413.21912,218.12556,437.91425,165.13153, 101 | 476.58157,192.74352,445.938,163.11424,437.91425,165.13153, 102 | 474.09012,212.57681,476.58157,192.74352,437.91425,165.13153, 103 | 438.43033,157.67789,445.938,163.11424,437.91425,165.13153, 104 | 429.11005,157.54149,438.43033,157.67789,429.27686,164.34004, 105 | 400.59744,190.68872,421.32654,162.23616,429.27686,164.34004, 106 | 400.59744,190.68872,413.21912,218.12556,429.27686,164.34004, 107 | 421.32654,162.23616,429.11005,157.54149,429.27686,164.34004, 108 | 413.21912,218.12556,437.91425,165.13153,429.27686,164.34004, 109 | 438.43033,157.67789,437.91425,165.13153,429.27686,164.34004, 110 | -------------------------------------------------------------------------------- /FaceRekognition/FaceDetectExample/FaceDetectExample.pde: -------------------------------------------------------------------------------- 1 | // Detect a Face 2 | // Daniel Shiffman 3 | // https://github.com/shiffman/RekognitionProcessing 4 | // http://rekognition.com/ 5 | 6 | // This example also requires HTTProcessing.zip 7 | // https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip 8 | 9 | // Also, you need an API key. 10 | // Sign up here: http://rekognition.com/register/ 11 | // Make a text file in your data folder called key.txt 12 | // Put your API key on the first line and your API secret on the second line 13 | 14 | import httprocessing.*; 15 | import rekognition.faces.*; 16 | 17 | Rekognition rekog; 18 | 19 | PImage img; 20 | RFace[] faces; 21 | 22 | void setup() { 23 | size(800, 600); 24 | 25 | // load image for drawing 26 | String filename = "obama.jpg"; 27 | img = loadImage(filename); 28 | 29 | // Load the API keys 30 | String[] keys = loadStrings("key.txt"); 31 | String api_key = keys[0]; 32 | String api_secret = keys[1]; 33 | 34 | // Create the face recognizer object 35 | rekog = new Rekognition(this, api_key, api_secret); 36 | 37 | // Detect faces in image 38 | // We will get a list of Face objects 39 | faces = rekog.detect(filename); 40 | } 41 | 42 | void draw() { 43 | background(0); 44 | 45 | // Draw the image 46 | image(img, 0, 0); 47 | 48 | // The face objects have lots of information stored 49 | for (int i = 0; i < faces.length; i++) { 50 | stroke(0, 0, 0); 51 | strokeWeight(1); 52 | noFill(); 53 | rectMode(CENTER); 54 | rect(faces[i].center.x, faces[i].center.y, faces[i].w, faces[i].h); // Face center, with, and height 55 | rect(faces[i].eye_right.x, faces[i].eye_right.y, 4, 4); // Right eye 56 | rect(faces[i].eye_left.x, faces[i].eye_left.y, 4, 4); // Left eye 57 | rect(faces[i].mouth_left.x, faces[i].mouth_left.y, 4, 4); // Mouth Left 58 | rect(faces[i].mouth_right.x, faces[i].mouth_right.y, 4, 4); // Mouth right 59 | rect(faces[i].nose.x, faces[i].nose.y, 4, 4); // Nose 60 | fill(0,255,0); 61 | String display = "Age: " + int(faces[i].age) + "\n\n"; // Age 62 | display += "Gender: " + faces[i].gender + "\n"; // Gender 63 | display += "Gender rating: " + nf(faces[i].gender_rating, 1, 2) + "\n\n"; // Gender from 0 to 1, 1 male, 0 female 64 | display += "Smiling: " + faces[i].smiling + "\n"; // Smiling 65 | display += "Smile rating: " + nf(faces[i].smile_rating, 1, 2) + "\n\n"; // Smiling from 0 to 1 66 | display += "Glasses: " + faces[i].glasses + "\n"; // Glasses 67 | display += "Glasses rating: " + nf(faces[i].glasses_rating, 1, 2) + "\n\n"; // Glasses from 0 to 1 68 | display += "Eyes closed: " + faces[i].eyes_closed + "\n"; // Eyes closed 69 | display += "Eyes closed rating: " + nf(faces[i].eyes_closed_rating, 1, 2) + "\n\n"; // Eyes closed from 0 to 1 70 | text(display, faces[i].left(), faces[i].bottom()+20); // Draw all text below face rectangle 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /FaceRekognition/FaceDetectExample/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceDetectExample/data/obama.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceDetectExample/data/obamas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceDetectExample/data/obamas.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceDetectExample/data/pitt-jolie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceDetectExample/data/pitt-jolie.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceDetectExample/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceDetectExample/data/pitt.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceDetectExample/data/superman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceDetectExample/data/superman.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/FaceRecognizeExample.pde: -------------------------------------------------------------------------------- 1 | // Recognize a Face 2 | // Daniel Shiffman 3 | // https://github.com/shiffman/RekognitionProcessing 4 | // http://rekognition.com/ 5 | 6 | // This example also requires HTTProcessing.zip 7 | // https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip 8 | 9 | // Also, you need an API key. 10 | // Sign up here: http://rekognition.com/register/ 11 | // Make a text file in your data folder called key.txt 12 | // Put your API key on the first line and your API secret on the second line 13 | 14 | import httprocessing.*; 15 | import rekognition.faces.*; 16 | 17 | PImage img; 18 | Rekognition rekog; 19 | RFace[] faces; 20 | 21 | void setup() { 22 | size(800, 400); 23 | 24 | // load image for drawing 25 | String filename = "obama.jpg"; 26 | img = loadImage(filename); 27 | 28 | // Load the API keys 29 | String[] keys = loadStrings("key.txt"); 30 | String api_key = keys[0]; 31 | String api_secret = keys[1]; 32 | 33 | // Create the face recognizer object 34 | rekog = new Rekognition(this, api_key, api_secret); 35 | 36 | // You can set a namespace and userid for this application 37 | rekog.setNamespace("demo"); 38 | rekog.setUserID("processing"); 39 | 40 | // Recognize faces in image 41 | faces = rekog.recognize(filename); 42 | } 43 | 44 | void draw() { 45 | background(0); 46 | 47 | // Draw the image 48 | image(img, 0, 0); 49 | 50 | 51 | // The face objects have lots of information stored 52 | for (int i = 0; i < faces.length; i++) { 53 | stroke(255, 0, 0); 54 | strokeWeight(1); 55 | noFill(); 56 | rectMode(CENTER); 57 | 58 | // Face center, with, and height 59 | // We could also get eye, mouth, and nose positions like in FaceDetect 60 | rect(faces[i].center.x, faces[i].center.y, faces[i].w, faces[i].h); 61 | 62 | // Possible face matches come back in a FloatDict 63 | // A string (name of face) is paired with a float from 0 to 1 (how likely is it that face) 64 | FloatDict matches = faces[i].getMatches(); 65 | fill(255); 66 | String display = ""; 67 | for (String key : matches.keys()) { 68 | float likely = matches.get(key); 69 | display += key + ": " + likely + "\n"; 70 | } 71 | 72 | // We could also get Age, Gender, Smiling, Glasses, and Eyes Closed data like in the FaceDetect example 73 | text(display, img.width+10, 60); 74 | 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExample/data/obama.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/data/obama2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExample/data/obama2.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/data/obamas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExample/data/obamas.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/data/pitt-jolie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExample/data/pitt-jolie.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExample/data/pitt.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExample/data/superman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExample/data/superman.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExampleThread/FaceRecognizeExampleThread.pde: -------------------------------------------------------------------------------- 1 | // Recognize a Face 2 | // Daniel Shiffman 3 | // https://github.com/shiffman/RekognitionProcessing 4 | // http://rekognition.com/ 5 | 6 | // This example also requires HTTProcessing.zip 7 | // https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip 8 | 9 | // Also, you need an API key. 10 | // Sign up here: http://rekognition.com/register/ 11 | // Make a text file in your data folder called key.txt 12 | // Put your API key on the first line and your API secret on the second line 13 | 14 | import httprocessing.*; 15 | import rekognition.faces.*; 16 | 17 | PImage img; 18 | Rekognition rekog; 19 | RFace[] faces; 20 | 21 | RecognizeRequest request; 22 | 23 | void setup() { 24 | size(800, 400); 25 | 26 | // load image for drawing 27 | String filename = "obama.jpg"; 28 | img = loadImage(filename); 29 | 30 | // Load the API keys 31 | String[] keys = loadStrings("key.txt"); 32 | String api_key = keys[0]; 33 | String api_secret = keys[1]; 34 | 35 | // Create the face recognizer object 36 | rekog = new Rekognition(this, api_key, api_secret); 37 | 38 | // You can set a namespace and userid for this application 39 | rekog.setNamespace("demo"); 40 | rekog.setUserID("processing"); 41 | 42 | // Recognize faces in image 43 | request = new RecognizeRequest(filename); 44 | request.start(); 45 | } 46 | 47 | void draw() { 48 | background(0); 49 | 50 | // Draw the image 51 | image(img, 0, 0); 52 | 53 | if (request != null && request.done) { 54 | faces = request.getFaces(); 55 | request = null; 56 | } 57 | else if (request != null) { 58 | String dots = ""; 59 | for (int i = 0; i < frameCount/15 % 4; i++) { 60 | dots += "."; 61 | } 62 | textSize(24); 63 | text("Loading"+dots, img.width+10, 60); 64 | } 65 | 66 | 67 | if (faces != null) { 68 | // The face objects have lots of information stored 69 | for (int i = 0; i < faces.length; i++) { 70 | stroke(255, 0, 0); 71 | strokeWeight(1); 72 | noFill(); 73 | rectMode(CENTER); 74 | 75 | // Face center, with, and height 76 | // We could also get eye, mouth, and nose positions like in FaceDetect 77 | rect(faces[i].center.x, faces[i].center.y, faces[i].w, faces[i].h); 78 | 79 | // Possible face matches come back in a FloatDict 80 | // A string (name of face) is paired with a float from 0 to 1 (how likely is it that face) 81 | FloatDict matches = faces[i].getMatches(); 82 | fill(255); 83 | String display = ""; 84 | for (String key : matches.keys()) { 85 | float likely = matches.get(key); 86 | display += key + ": " + likely + "\n"; 87 | } 88 | 89 | // We could also get Age, Gender, Smiling, Glasses, and Eyes Closed data like in the FaceDetect example 90 | textSize(24); 91 | text(display, img.width+10, 60); 92 | } 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExampleThread/RecognizeRequest.pde: -------------------------------------------------------------------------------- 1 | // Recognize a Face 2 | // Daniel Shiffman 3 | // https://github.com/shiffman/RekognitionProcessing 4 | // http://rekognition.com/ 5 | 6 | // A class to make a request as a separate thread 7 | // This is so that the animation can continue without pausing 8 | // This could also be accomplished with the more simple "thread()" method in Processing 9 | // See: http://wiki.processing.org/w/Threading for more info 10 | 11 | class RecognizeRequest extends Thread { 12 | 13 | // path to recognize 14 | String path; 15 | 16 | // Is the thread done? 17 | boolean done; 18 | 19 | // What matches are there? 20 | FloatDict matches; 21 | 22 | // What faces are there 23 | RFace[] faces; 24 | 25 | // Create the request 26 | RecognizeRequest(String s) { 27 | path = s; 28 | matches = new FloatDict(); 29 | done = false; 30 | } 31 | 32 | // Perform the request 33 | void run () { 34 | faces = rekog.recognize(path); 35 | if (faces != null && faces.length > 0) { 36 | // We are assuming there is just one face in each image 37 | matches = faces[0].getMatches(); 38 | // Sort by most likely 39 | matches.sortValuesReverse(); 40 | } 41 | // Request is complete 42 | done = true; 43 | } 44 | 45 | RFace[] getFaces() { 46 | return faces; 47 | } 48 | 49 | // Return the matches 50 | FloatDict getMatches() { 51 | return matches; 52 | } 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /FaceRekognition/FaceRecognizeExampleThread/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceRecognizeExampleThread/data/obama.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceTrainExample/FaceTrainExample.pde: -------------------------------------------------------------------------------- 1 | // Train a Face 2 | // Daniel Shiffman 3 | // https://github.com/shiffman/RekognitionProcessing 4 | // http://rekognition.com/ 5 | 6 | // This example also requires HTTProcessing.zip 7 | // https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip 8 | 9 | // Also, you need an API key. 10 | // Sign up here: http://rekognition.com/register/ 11 | // Make a text file in your data folder called key.txt 12 | // Put your API key on the first line and your API secret on the second line 13 | 14 | import httprocessing.*; 15 | import rekognition.faces.*; 16 | 17 | PImage img; 18 | 19 | void setup() { 20 | size(300, 200); 21 | 22 | // Load the API keys 23 | String[] keys = loadStrings("key.txt"); 24 | String api_key = keys[0]; 25 | String api_secret = keys[1]; 26 | 27 | Rekognition rekog = new Rekognition(this, api_key, api_secret); 28 | 29 | // You can set a namespace and userid for this application 30 | rekog.setNamespace("demo2"); 31 | rekog.setUserID("processing"); 32 | 33 | // Here we tell Rekognition that the face in this image is associated with this name 34 | rekog.addFace("obama.jpg", "Barack Obama"); 35 | rekog.addFace("pitt.jpg", "Brad Pitt"); 36 | 37 | // We need a second API call to train Rekognition of whatever faces have been added 38 | // Here it's one face, then train, but you could add a lot of faces before training 39 | rekog.train(); 40 | } 41 | 42 | void draw() { 43 | background(0); 44 | // Not doing anything in this example 45 | } 46 | 47 | -------------------------------------------------------------------------------- /FaceRekognition/FaceTrainExample/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceTrainExample/data/obama.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceTrainExample/data/obamas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceTrainExample/data/obamas.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceTrainExample/data/pitt-jolie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceTrainExample/data/pitt-jolie.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceTrainExample/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceTrainExample/data/pitt.jpg -------------------------------------------------------------------------------- /FaceRekognition/FaceTrainExample/data/superman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/FaceTrainExample/data/superman.jpg -------------------------------------------------------------------------------- /FaceRekognition/Greeter/Face.pde: -------------------------------------------------------------------------------- 1 | // Face Recognizer App 2 | // OpenCV + Rekognition API 3 | 4 | // This class keeps track of a Face that is currently on screen 5 | // It can ask Rekognition who it is or tell Rekognition who it is 6 | 7 | // It also matches itself with any new faces from OpenCV to guess which 8 | // face is which over time 9 | 10 | class Face { 11 | 12 | // Let's not use the rectangle, ints in limiting 13 | // Rectangle r; 14 | float x, y, w, h; 15 | 16 | // Am I available? 17 | boolean available; 18 | 19 | // Should I be deleted? 20 | boolean delete; 21 | 22 | // How long should I live if I have disappeared? 23 | int timer = 127; 24 | 25 | // Assign a number to each face 26 | int id; 27 | 28 | 29 | // Keep track of a separate PImage and path to a file 30 | PImage img; 31 | String path; 32 | 33 | // Dictionary of name probabilities 34 | FloatDict matches; 35 | 36 | // User interaction: Am I selected or being rolled over? 37 | boolean selected = false; 38 | boolean rollover = false; 39 | 40 | // Who am I really? 41 | String name = ""; 42 | // Who doe Rekognition think I am? 43 | String guess = ""; 44 | 45 | // Threaded requests to API 46 | RecognizeRequest rreq; 47 | TrainRequest treq; 48 | 49 | 50 | 51 | // Constuctor 52 | Face(Rectangle r, int faceCount) { 53 | x = r.x; 54 | y = r.y; 55 | w = r.width; 56 | h = r.height; 57 | 58 | // We are initially available to OpenCV and should not be deleted 59 | available = true; 60 | delete = false; 61 | id = faceCount; 62 | 63 | // Ask Rekognition who I am 64 | recognize(); 65 | } 66 | 67 | // Save face as an image 68 | // (This is temporary and overwritten each time) 69 | void saveFace(PImage i) { 70 | img = i; 71 | path = "faces/face-"+id+".jpg"; 72 | img.save(path); 73 | } 74 | 75 | // Crop the image into a smaller PImage 76 | PImage cropFace(PImage source) { 77 | PImage img = createImage(int(w*openCVScale), int(h*openCVScale), RGB); 78 | img.copy(source, int(x*openCVScale), int(y*openCVScale), int(w*openCVScale), int(h*openCVScale), 0, 0, int(w*openCVScale), int(h*openCVScale)); 79 | img.updatePixels(); 80 | return img; 81 | } 82 | 83 | // What requests are active and are any done 84 | void checkRequests() { 85 | // Has a rekognition request finished? 86 | if (rreq != null && rreq.done) { 87 | // Get the matches and set back to null 88 | matches = rreq.getMatches(); 89 | rreq = null; 90 | // As long as it found a match the guess it the first one 91 | if (matches.size() > 0) { 92 | guess = matches.keyArray()[0]; 93 | } 94 | // Otherwise no matches, set to null to restart checking 95 | else { 96 | matches = null; 97 | } 98 | } 99 | 100 | // If a training request has completed set that to null and 101 | // start a rekognition request 102 | if (treq != null && treq.done) { 103 | treq = null; 104 | recognize(); 105 | } 106 | 107 | // If we have no matches and no active request 108 | // Let's make a request 109 | if (matches == null && rreq == null) { 110 | recognize(); 111 | } 112 | } 113 | 114 | // Copy the image of the face and start a recognition request 115 | void recognize() { 116 | PImage cropped = cropFace(cam); 117 | saveFace(cropped); 118 | rreq = new RecognizeRequest(path); 119 | rreq.start(); 120 | } 121 | 122 | 123 | // make a training request 124 | void train() { 125 | treq = new TrainRequest(path, name); 126 | treq.start(); 127 | } 128 | 129 | // Display method 130 | void display() { 131 | 132 | // Fade color out over time 133 | fill(0, 0, 255, timer); 134 | if (rollover) { 135 | fill(255, 0, 255, timer); 136 | } 137 | else if (selected) { 138 | fill(255, 0, 0, timer); 139 | } 140 | // Draw the face 141 | stroke(0, 0, 255); 142 | rect(x*scl, y*scl, w*scl, h*scl); 143 | fill(255); 144 | 145 | // Draw the ID and guess 146 | text("id: "+id, x*scl+10, y*scl+30); 147 | text("Guess: "+guess, x*scl+10, y*scl+45); 148 | 149 | 150 | if (treq != null) { 151 | String dots = ""; 152 | for (int i = 0; i < frameCount/15 % 4; i++) { 153 | dots += "."; 154 | } 155 | text("Training"+dots, x*scl+10, y*scl+h*scl-15); 156 | // Display info based on selection status 157 | } 158 | else if (selected) { 159 | text("Enter actual name: " + name, x*scl+10, y*scl+h*scl-15); 160 | } 161 | else if (rollover) { 162 | text("Click to enter name.", x*scl+10, y*scl+h*scl-15); 163 | } 164 | 165 | 166 | if (rreq != null) { 167 | String dots = ""; 168 | for (int i = 0; i < frameCount/15 % 4; i++) { 169 | dots += "."; 170 | } 171 | text("Loading"+dots, x*scl+10, y*scl+75); 172 | // Display matches and guess info 173 | } 174 | else if (matches != null) { 175 | String display = ""; 176 | for (String key : matches.keys()) { 177 | float likely = matches.get(key); 178 | display += key + ": " + int(likely*100) + "%\n"; 179 | // We could also get Age, Gender, Smiling, Glasses, and Eyes Closed data like in the FaceDetect example 180 | text(display, x*scl+10, y*scl+75); 181 | } 182 | } 183 | } 184 | 185 | // Methods below are for keeping track of rectangles over time 186 | 187 | // Give me a new location / size 188 | // Oooh, it would be nice to lerp here! 189 | void update(Rectangle newR) { 190 | //r = (Rectangle) newR.clone(); 191 | x = lerp(x, newR.x, 0.1); 192 | y = lerp(y, newR.y, 0.1); 193 | w = lerp(w, newR.width, 0.1); 194 | h = lerp(h, newR.height, 0.1); 195 | 196 | // If it lives you should get a new timer 197 | timer = 127; 198 | } 199 | 200 | // Count me down, I am gone 201 | void countDown() { 202 | timer--; 203 | } 204 | 205 | // I am dead, delete me 206 | boolean dead() { 207 | if (timer < 0) return true; 208 | return false; 209 | } 210 | 211 | // Check it mouse is inside 212 | boolean inside(float px, float py) { 213 | px = px/scl; 214 | py = py/scl; 215 | return (px > x && px < x + w && py > y && py < y + h); 216 | } 217 | 218 | // Set rollover to true or false 219 | void rollover(boolean b) { 220 | rollover = b; 221 | } 222 | 223 | 224 | // Set selection 225 | void selected(boolean b) { 226 | selected = b; 227 | if (selected) { 228 | name = ""; 229 | } 230 | } 231 | 232 | // Set name 233 | void setName(String s) { 234 | name = s; 235 | } 236 | } 237 | 238 | -------------------------------------------------------------------------------- /FaceRekognition/Greeter/FaceDetector.pde: -------------------------------------------------------------------------------- 1 | // Face Recognizer App 2 | // OpenCV + Rekognition API 3 | 4 | // This class keeps track of the list of faces on screen 5 | // It also knows which faces are new this frame for recognition 6 | 7 | class FaceDetector { 8 | // A list of my Face objects 9 | ArrayList faceList; 10 | ArrayList newFaces; 11 | 12 | // How many have I found over all time 13 | int faceCount = 0; 14 | 15 | // Is a face selected? 16 | boolean selected = false; 17 | 18 | FaceDetector() { 19 | faceList = new ArrayList(); 20 | newFaces = new ArrayList(); 21 | } 22 | 23 | // Update the list of faces based on current Rectangles from OpenCV 24 | void detect(Rectangle[] faces) { 25 | 26 | // Assume no new faces 27 | newFaces.clear(); 28 | 29 | // SCENARIO 1: faceList is empty 30 | if (faceList.isEmpty()) { 31 | // Just make a Face object for every face Rectangle 32 | for (int i = 0; i < faces.length; i++) { 33 | Face f = new Face(faces[i], faceCount); 34 | newFace(f); 35 | } 36 | // SCENARIO 2: We have fewer Face objects than face Rectangles found from OPENCV 37 | } 38 | else if (faceList.size() <= faces.length) { 39 | boolean[] used = new boolean[faces.length]; 40 | // Match existing Face objects with a Rectangle 41 | for (Face f : faceList) { 42 | // Find faces[index] that is closest to face f 43 | // set used[index] to true so that it can't be used twice 44 | float record = 50000; 45 | int index = -1; 46 | for (int i = 0; i < faces.length; i++) { 47 | float d = dist(faces[i].x, faces[i].y, f.x, f.y); 48 | if (d < record && !used[i]) { 49 | record = d; 50 | index = i; 51 | } 52 | } 53 | // Update Face object location 54 | used[index] = true; 55 | f.update(faces[index]); 56 | } 57 | // Add any unused faces 58 | for (int i = 0; i < faces.length; i++) { 59 | if (!used[i]) { 60 | Face f = new Face(faces[i], faceCount); 61 | newFace(f); 62 | } 63 | } 64 | // SCENARIO 3: We have more Face objects than face Rectangles found 65 | } 66 | else { 67 | // All Face objects start out as available 68 | for (Face f : faceList) { 69 | f.available = true; 70 | } 71 | // Match Rectangle with a Face object 72 | for (int i = 0; i < faces.length; i++) { 73 | // Find face object closest to faces[i] Rectangle 74 | // set available to false 75 | float record = 50000; 76 | int index = -1; 77 | for (int j = 0; j < faceList.size(); j++) { 78 | Face f = faceList.get(j); 79 | float d = dist(faces[i].x, faces[i].y, f.x, f.y); 80 | if (d < record && f.available) { 81 | record = d; 82 | index = j; 83 | } 84 | } 85 | // Update Face object location 86 | Face f = faceList.get(index); 87 | f.available = false; 88 | f.update(faces[i]); 89 | } 90 | // Start to kill any left over Face objects 91 | for (Face f : faceList) { 92 | if (f.available) { 93 | f.countDown(); 94 | if (f.dead()) { 95 | f.delete = true; 96 | } 97 | } 98 | } 99 | } 100 | 101 | // Delete any that should be deleted 102 | for (int i = faceList.size()-1; i >= 0; i--) { 103 | Face f = faceList.get(i); 104 | if (f.delete) { 105 | faceList.remove(i); 106 | } 107 | } 108 | } 109 | 110 | // See if we've clicked on a Face 111 | void click(float x, float y) { 112 | for (Face f : faceList) { 113 | if (f.inside(x, y)) { 114 | f.selected(true); 115 | selected = true; 116 | } 117 | } 118 | } 119 | 120 | // See if we are rolling over a Face 121 | void rollover(float x, float y) { 122 | for (Face f : faceList) { 123 | if (f.inside(x, y)) { 124 | f.rollover(true); 125 | } 126 | else { 127 | f.rollover(false); 128 | } 129 | } 130 | } 131 | 132 | 133 | // Set the name of the face that is selected 134 | void enter(String s, boolean finished) { 135 | for (Face f : faceList) { 136 | if (f.selected) { 137 | f.setName(s); 138 | if (finished) { 139 | selected = false; 140 | f.selected(false); 141 | f.train(); 142 | } 143 | } 144 | } 145 | } 146 | 147 | // Add a new face to the world 148 | void newFace(Face f) { 149 | faceList.add(f); 150 | newFaces.add(f); 151 | faceCount++; 152 | } 153 | 154 | 155 | // Draw all the faces 156 | void showFaces() { 157 | for (Face f : faceList) { 158 | f.display(); 159 | } 160 | } 161 | 162 | // Check any requests for any faces 163 | void checkRequests() { 164 | for (Face f : faceList) { 165 | f.checkRequests(); 166 | } 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /FaceRekognition/Greeter/Greeter.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | // https://github.com/shiffman/Faces 5 | 6 | // Face Recognizer App 7 | // OpenCV + Rekognition API 8 | 9 | // This example also requires 3 libraries 10 | // https://github.com/shiffman/RekognitionProcessing 11 | // https://github.com/atduskgreg/opencv-processing/releases 12 | // https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip 13 | 14 | // Also, you need an API key. 15 | // Sign up here: http://rekognition.com/register/ 16 | // Make a text file in your data folder called key.txt 17 | // Put your API key on the first line and your API secret on the second line 18 | 19 | // Rekognition Library 20 | import rekognition.faces.*; 21 | 22 | // Video library 23 | import processing.video.*; 24 | 25 | // OpenCV Library 26 | import gab.opencv.*; 27 | 28 | // Also need HTTP Requests for Rekognition 29 | import httprocessing.*; 30 | 31 | // Java Rectangle class 32 | import java.awt.Rectangle; 33 | 34 | 35 | // OpenCV and Capture 36 | OpenCV opencv; 37 | Capture cam; 38 | 39 | // We will need a smaller image for fast real-time detection 40 | PImage smaller; 41 | 42 | int openCVScale = 4; // Scale Capture to OpenCV 43 | float windowScale; // Window to Capture 44 | float scl; // Overall scale for drawing faces 45 | 46 | 47 | // Rekognition API 48 | Rekognition rekog; 49 | 50 | // An object to do OpenCV detection 51 | FaceDetector detector; 52 | 53 | // For the user to type in their name 54 | // This is awkard and needs to be improved 55 | String typed = ""; 56 | 57 | int vw = 640; 58 | int vh = 480; 59 | 60 | void setup() { 61 | size(1024, 768); 62 | 63 | windowScale = width/float(vw); 64 | scl = windowScale * openCVScale; 65 | 66 | // OpenCV object 67 | opencv = new OpenCV(this, vw/openCVScale, vh/openCVScale); 68 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 69 | 70 | // Scaled down image 71 | smaller = createImage(opencv.width, opencv.height, RGB); 72 | // Larger capture object 73 | cam = new Capture(this, vw, vh); 74 | cam.start(); 75 | 76 | // Setting up Rekognition API 77 | String[] keys = loadStrings("key.txt"); 78 | String k = keys[0]; 79 | String secret = keys[1]; 80 | rekog = new Rekognition(this, k, secret); 81 | // You can have different databases of faces for different applications 82 | rekog.setNamespace("demo2"); 83 | rekog.setUserID("processing"); 84 | 85 | // A generic time-based face detector 86 | detector = new FaceDetector(); 87 | } 88 | 89 | // Get images from camera 90 | void captureEvent(Capture cam) { 91 | cam.read(); 92 | } 93 | 94 | void draw() { 95 | 96 | background(0); 97 | // Draw video 98 | image(cam, 0, 0, width, height); 99 | 100 | // Scale down video and pass to OpenCV 101 | smaller.copy(cam, 0, 0, cam.width, cam.height, 0, 0, smaller.width, smaller.height); 102 | smaller.updatePixels(); 103 | opencv.loadImage(smaller); 104 | 105 | // Get an array of rectangles and send to the detector 106 | Rectangle[] faces = opencv.detect(); 107 | detector.detect(faces); 108 | 109 | // Draw the faces 110 | detector.showFaces(); 111 | // Check for any requests to Rekognition API 112 | detector.checkRequests(); 113 | // Check to see if user is rolling over faces 114 | detector.rollover(mouseX, mouseY); 115 | } 116 | 117 | void mousePressed() { 118 | // Check to see if user clicked on a face 119 | detector.click(mouseX, mouseY); 120 | } 121 | 122 | void keyPressed() { 123 | 124 | // This should really be improved, super basic keyboard input for name 125 | if (detector.selected) { 126 | if (key == '\n') { 127 | detector.enter(typed, true); 128 | typed = ""; 129 | } 130 | else if (key == 8) { 131 | if (typed.length() > 0) { 132 | typed = typed.substring(0, typed.length()-1); 133 | } 134 | detector.enter(typed, false); 135 | } 136 | else if (key > 31 && key < 127) { 137 | typed = typed + key; 138 | detector.enter(typed, false); 139 | } 140 | } 141 | } 142 | 143 | -------------------------------------------------------------------------------- /FaceRekognition/Greeter/RecognizeRequest.pde: -------------------------------------------------------------------------------- 1 | // Face Recognizer App 2 | // OpenCV + Rekognition API 3 | 4 | // This class is a separate thread to recognize a face 5 | 6 | class RecognizeRequest extends Thread { 7 | 8 | // path to recognize 9 | String path; 10 | 11 | // Is the thread done? 12 | boolean done; 13 | 14 | // What matches are there? 15 | FloatDict matches; 16 | 17 | // Create the request 18 | RecognizeRequest(String s) { 19 | path = s; 20 | matches = new FloatDict(); 21 | done = false; 22 | } 23 | 24 | // Perform the request 25 | void run () { 26 | RFace[] faces = rekog.recognize(path); 27 | if (faces != null && faces.length > 0) { 28 | // We are assuming there is just one face in each image 29 | matches = faces[0].getMatches(); 30 | // Sort by most likely 31 | matches.sortValuesReverse(); 32 | } 33 | // Request is complete 34 | done = true; 35 | } 36 | 37 | // Return the matches 38 | FloatDict getMatches() { 39 | return matches; 40 | } 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /FaceRekognition/Greeter/TrainRequest.pde: -------------------------------------------------------------------------------- 1 | // Face Recognizer App 2 | // OpenCV + Rekognition API 3 | 4 | // This class is a separate thread to train a face 5 | 6 | class TrainRequest extends Thread { 7 | 8 | // Path to face image 9 | String path; 10 | // Name of face 11 | String name; 12 | // Is the thread complete? 13 | boolean done; 14 | 15 | // Create the request 16 | TrainRequest (String s, String n) { 17 | path = s; 18 | name = n; 19 | done = false; 20 | } 21 | 22 | // Perform the request 23 | void run () { 24 | rekog.addFace(path, name); 25 | 26 | // We need a second API call to train Rekognition of whatever faces have been added 27 | // Here it's one face, then train, but you could add a lot of faces before training 28 | rekog.train(); 29 | 30 | // The request is complete 31 | done = true; 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/RawJSONExample.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | // https://github.com/shiffman/Faces 5 | 6 | // See raw JSON from API 7 | // https://github.com/shiffman/RekognitionProcessing 8 | // http://rekognition.com/ 9 | 10 | // This example also requires HTTProcessing.zip 11 | // https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip 12 | 13 | // Also, you need an API key. 14 | // Sign up here: http://rekognition.com/register/ 15 | // Make a text file in your data folder called key.txt 16 | // Put your API key on the first line and your API secret on the second line 17 | 18 | import httprocessing.*; 19 | import rekognition.faces.*; 20 | 21 | Rekognition rekog; 22 | 23 | PImage img; 24 | RFace[] faces; 25 | 26 | String json = ""; 27 | 28 | void setup() { 29 | size(800, 600); 30 | 31 | // load image for drawing 32 | String filename = "obama.jpg"; 33 | img = loadImage(filename); 34 | 35 | // Load the API keys 36 | String[] keys = loadStrings("key.txt"); 37 | String api_key = keys[0]; 38 | String api_secret = keys[1]; 39 | 40 | // Create the face recognizer object 41 | rekog = new Rekognition(this, api_key, api_secret); 42 | 43 | // We can get a post request 44 | PostRequest post = rekog.createPostRequest(); 45 | // And manually configure it 46 | post.addData("job_list", "face_recognize_part_gender_emotion_age_glass"); 47 | // Adding a file 48 | File f = new File(dataPath(filename)); 49 | post.addFile("uploaded_file", f); 50 | // And send it 51 | post.send(); 52 | // Now we can look at the raw JSON 53 | json = post.getContent(); 54 | 55 | faces = rekog.facesFromJSON(json); 56 | 57 | // Print JSON to console 58 | println(json); 59 | } 60 | 61 | void draw() { 62 | background(0); 63 | 64 | // Draw the image 65 | image(img, 0, 0); 66 | 67 | // The face objects have lots of information stored 68 | for (int i = 0; i < faces.length; i++) { 69 | stroke(0, 0, 0); 70 | strokeWeight(1); 71 | noFill(); 72 | rectMode(CENTER); 73 | rect(faces[i].center.x, faces[i].center.y, faces[i].w, faces[i].h); // Face center, with, and height 74 | rect(faces[i].eye_right.x, faces[i].eye_right.y, 4, 4); // Right eye 75 | rect(faces[i].eye_left.x, faces[i].eye_left.y, 4, 4); // Left eye 76 | rect(faces[i].mouth_left.x, faces[i].mouth_left.y, 4, 4); // Mouth Left 77 | rect(faces[i].mouth_right.x, faces[i].mouth_right.y, 4, 4); // Mouth right 78 | rect(faces[i].nose.x, faces[i].nose.y, 4, 4); // Nose 79 | fill(0, 255, 0); 80 | String display = "Age: " + int(faces[i].age) + "\n\n"; // Age 81 | display += "Gender: " + faces[i].gender + "\n"; // Gender 82 | display += "Gender rating: " + nf(faces[i].gender_rating, 1, 2) + "\n\n"; // Gender from 0 to 1, 1 male, 0 female 83 | display += "Smiling: " + faces[i].smiling + "\n"; // Smiling 84 | display += "Smile rating: " + nf(faces[i].smile_rating, 1, 2) + "\n\n"; // Smiling from 0 to 1 85 | display += "Glasses: " + faces[i].glasses + "\n"; // Glasses 86 | display += "Glasses rating: " + nf(faces[i].glasses_rating, 1, 2) + "\n\n"; // Glasses from 0 to 1 87 | display += "Eyes closed: " + faces[i].eyes_closed + "\n"; // Eyes closed 88 | display += "Eyes closed rating: " + nf(faces[i].eyes_closed_rating, 1, 2) + "\n\n"; // Eyes closed from 0 to 1 89 | text(display, faces[i].left(), faces[i].bottom()+20); // Draw all text below face rectangle 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/data/key.txt: -------------------------------------------------------------------------------- 1 | 6CxLSODTbw4wmRjG 2 | jOxQ3t4AU8S45OAc -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/RawJSONExample/data/obama.jpg -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/data/obamas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/RawJSONExample/data/obamas.jpg -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/data/pitt-jolie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/RawJSONExample/data/pitt-jolie.jpg -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/data/pitt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/RawJSONExample/data/pitt.jpg -------------------------------------------------------------------------------- /FaceRekognition/RawJSONExample/data/superman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/FaceRekognition/RawJSONExample/data/superman.jpg -------------------------------------------------------------------------------- /FaceShift/OSCDemo/OSCDemo.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | 5 | // Demonstration of receiving OSC messages from FaceShift OSC 6 | 7 | import oscP5.*; 8 | import netP5.*; 9 | 10 | // OSC Object 11 | OscP5 oscP5; 12 | 13 | // Here are three "gestures" I want to track 14 | float jaw = 0; 15 | float smileL = 0; 16 | float smileR = 0; 17 | 18 | void setup() { 19 | size(400, 400); 20 | 21 | // We need to have a larger datagram size to get all the data from FaceShift 22 | OscProperties properties = new OscProperties(); 23 | properties.setDatagramSize(4096); 24 | 25 | /* the port number you are listening for incoming osc packets. */ 26 | properties.setListeningPort(8338); 27 | 28 | // Create OSC Object 29 | oscP5 = new OscP5(this, properties); 30 | 31 | // Plug methods in 32 | oscP5.plug(this, "jawOpen", "/gesture/jaw/open"); 33 | oscP5.plug(this, "smileL", "/gesture/mouth/smile/left"); 34 | oscP5.plug(this, "smileR", "/gesture/mouth/smile/right"); 35 | } 36 | 37 | 38 | void draw() { 39 | background(0); 40 | 41 | // Draw a circle based on puffing 42 | stroke(255); 43 | fill(255, 50); 44 | float d = map(jaw, 0, 1, 0, 200); 45 | ellipse(width/2, height/2, d, d); 46 | 47 | // Draw some circles based on smiling 48 | ellipse(100, 200+map(smileL, 0, 1, 0, -50), 20, 20); 49 | ellipse(300, 200+map(smileR, 0, 1, 0, -50), 20, 20); 50 | 51 | // Display data 52 | fill(255); 53 | text(nf(smileL, 1, 2), 100, 240); 54 | text(nf(smileR, 1, 2), 300, 240); 55 | text(nf(jaw, 1, 2), 200, 240); 56 | } 57 | 58 | // Event methods that will receive data 59 | void jawOpen(float f) { 60 | jaw = f; 61 | } 62 | void smileL(float f) { 63 | smileL = f; 64 | } 65 | void smileR(float f) { 66 | smileR = f; 67 | } 68 | 69 | /* incoming osc message are forwarded to the oscEvent method. */ 70 | void oscEvent(OscMessage theOscMessage) { 71 | if (theOscMessage.isPlugged()==false) { 72 | // For any unplugged messages 73 | //println("UNPLUGGED: " + theOscMessage); 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /FaceShift/OSCDemo/PossibleMessages.pde: -------------------------------------------------------------------------------- 1 | /* 2 | /found i 3 | /gesture/brows/down/left f 4 | /gesture/brows/down/right f 5 | /gesture/brows/up/center f 6 | /gesture/brows/up/left f 7 | /gesture/brows/up/right f 8 | /gesture/cheek/squint/left f 9 | /gesture/cheek/squint/right f 10 | /gesture/chin/lower/raise f 11 | /gesture/chin/upper/raise f 12 | /gesture/eye/blink/left f 13 | /gesture/eye/blink/right f 14 | /gesture/eye/down/left f 15 | /gesture/eye/down/right f 16 | /gesture/eye/gaze/left ff 17 | /gesture/eye/gaze/right ff 18 | /gesture/eye/in/left f 19 | /gesture/eye/in/right f 20 | /gesture/eye/open/left f 21 | /gesture/eye/open/right f 22 | /gesture/eye/out/left f 23 | /gesture/eye/out/right f 24 | /gesture/eye/squint/left f 25 | /gesture/eye/squint/right f 26 | /gesture/eye/up/left f 27 | /gesture/eye/up/right f 28 | /gesture/jaw/forward f 29 | /gesture/jaw/left f 30 | /gesture/jaw/right f 31 | /gesture/lips/funnel f 32 | /gesture/lips/lower/close f 33 | /gesture/lips/lower/down f 34 | /gesture/lips/lower/open f 35 | /gesture/lips/pucker f 36 | /gesture/lips/stretch/left f 37 | /gesture/lips/stretch/right f 38 | /gesture/lips/upper/close f 39 | /gesture/lips/upper/up f 40 | /gesture/mouth/dimple/left f 41 | /gesture/mouth/dimple/right f 42 | /gesture/mouth/frown/left f 43 | /gesture/mouth/frown/right f 44 | /gesture/mouth/left f 45 | /gesture/mouth/right f 46 | /gesture/mouth/smile/left f 47 | /gesture/mouth/smile/right f 48 | /gesture/puff f 49 | /gesture/sneer f 50 | /pose/orientation fff 51 | /pose/position fff 52 | /timestamp f 53 | */ 54 | 55 | -------------------------------------------------------------------------------- /OpenCV/FaceDetectMemory/Face.pde: -------------------------------------------------------------------------------- 1 | // Which Face Is Which 2 | // Daniel Shiffman 3 | // http://www.shiffman.net 4 | 5 | class Face { 6 | 7 | // A Rectangle 8 | Rectangle r; 9 | 10 | // Am I available to be matched? 11 | boolean available; 12 | 13 | // Should I be deleted? 14 | boolean delete; 15 | 16 | // How long should I live if I have disappeared? 17 | int totalTime = 127; 18 | int timer = totalTime; 19 | 20 | // Assign a number to each face 21 | int id; 22 | 23 | // Make me 24 | Face(int x, int y, int w, int h) { 25 | r = new Rectangle(x,y,w,h); 26 | available = true; 27 | delete = false; 28 | id = faceCount; 29 | faceCount++; 30 | } 31 | 32 | // Show me 33 | void display() { 34 | fill(0,0,255,map(timer,0,10,0,100)); 35 | stroke(0,0,255); 36 | rect(r.x*scl,r.y*scl,r.width*scl, r.height*scl); 37 | fill(255); 38 | text(""+id,r.x*scl+10,r.y*scl+30); 39 | } 40 | 41 | // Give me a new location / size 42 | // Oooh, it would be nice to lerp here! 43 | void update(Rectangle newR) { 44 | r = (Rectangle) newR.clone(); 45 | timer = totalTime; 46 | } 47 | 48 | // Count me down, I am gone 49 | void countDown() { 50 | timer--; 51 | } 52 | 53 | // I am deed, delete me 54 | boolean dead() { 55 | if (timer < 0) return true; 56 | return false; 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /OpenCV/FaceDetectMemory/FaceDetectMemory.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | // https://github.com/shiffman/Faces 5 | 6 | import processing.video.*; 7 | 8 | import gab.opencv.*; 9 | import java.awt.Rectangle; 10 | 11 | OpenCV opencv; 12 | 13 | Capture cam; 14 | PImage smaller; 15 | 16 | // A list of my Face objects 17 | ArrayList faceList; 18 | 19 | // how many have I found over all time 20 | int faceCount = 0; 21 | 22 | // Scaling down the video 23 | int scl = 4; 24 | 25 | void setup() { 26 | size(640, 480); 27 | opencv = new OpenCV(this, width/scl, height/scl); 28 | smaller = createImage(opencv.width,opencv.height,RGB); 29 | cam = new Capture(this, width, height); 30 | cam.start(); 31 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 32 | faceList = new ArrayList(); 33 | } 34 | 35 | void captureEvent(Capture cam) { 36 | cam.read(); 37 | } 38 | 39 | void draw() { 40 | background(0); 41 | image(cam,0,0); 42 | 43 | smaller.copy(cam,0,0,cam.width,cam.height,0,0,smaller.width,smaller.height); 44 | smaller.updatePixels(); 45 | opencv.loadImage(smaller); 46 | 47 | Rectangle[] faces = opencv.detect(); 48 | 49 | // SCENARIO 1: faceList is empty 50 | if (faceList.isEmpty()) { 51 | // Just make a Face object for every face Rectangle 52 | for (int i = 0; i < faces.length; i++) { 53 | faceList.add(new Face(faces[i].x, faces[i].y, faces[i].width, faces[i].height)); 54 | } 55 | // SCENARIO 2: We have fewer Face objects than face Rectangles found from OPENCV 56 | } 57 | else if (faceList.size() <= faces.length) { 58 | boolean[] used = new boolean[faces.length]; 59 | // Match existing Face objects with a Rectangle 60 | for (Face f : faceList) { 61 | // Find faces[index] that is closest to face f 62 | // set used[index] to true so that it can't be used twice 63 | float record = 50000; 64 | int index = -1; 65 | for (int i = 0; i < faces.length; i++) { 66 | float d = dist(faces[i].x, faces[i].y, f.r.x, f.r.y); 67 | if (d < record && !used[i]) { 68 | record = d; 69 | index = i; 70 | } 71 | } 72 | // Update Face object location 73 | used[index] = true; 74 | f.update(faces[index]); 75 | } 76 | // Add any unused faces 77 | for (int i = 0; i < faces.length; i++) { 78 | if (!used[i]) { 79 | faceList.add(new Face(faces[i].x, faces[i].y, faces[i].width, faces[i].height)); 80 | } 81 | } 82 | // SCENARIO 3: We have more Face objects than face Rectangles found 83 | } 84 | else { 85 | // All Face objects start out as available 86 | for (Face f : faceList) { 87 | f.available = true; 88 | } 89 | // Match Rectangle with a Face object 90 | for (int i = 0; i < faces.length; i++) { 91 | // Find face object closest to faces[i] Rectangle 92 | // set available to false 93 | float record = 50000; 94 | int index = -1; 95 | for (int j = 0; j < faceList.size(); j++) { 96 | Face f = faceList.get(j); 97 | float d = dist(faces[i].x, faces[i].y, f.r.x, f.r.y); 98 | if (d < record && f.available) { 99 | record = d; 100 | index = j; 101 | } 102 | } 103 | // Update Face object location 104 | Face f = faceList.get(index); 105 | f.available = false; 106 | f.update(faces[i]); 107 | } 108 | // Start to kill any left over Face objects 109 | for (Face f : faceList) { 110 | if (f.available) { 111 | f.countDown(); 112 | if (f.dead()) { 113 | f.delete = true; 114 | } 115 | } 116 | } 117 | } 118 | 119 | // Delete any that should be deleted 120 | for (int i = faceList.size()-1; i >= 0; i--) { 121 | Face f = faceList.get(i); 122 | if (f.delete) { 123 | faceList.remove(i); 124 | } 125 | } 126 | 127 | // Draw all the faces 128 | for (int i = 0; i < faces.length; i++) { 129 | noFill(); 130 | stroke(255, 0, 0); 131 | rect(faces[i].x*scl, faces[i].y*scl, faces[i].width*scl, faces[i].height*scl); 132 | } 133 | 134 | for (Face f : faceList) { 135 | f.display(); 136 | } 137 | } 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /OpenCV/LiveFaceDetect/LiveFaceDetect.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | 5 | // Now we need the video library 6 | import processing.video.*; 7 | 8 | // Import the library 9 | import gab.opencv.*; 10 | 11 | // We need Java rectangles 12 | import java.awt.Rectangle; 13 | 14 | // Library object 15 | OpenCV opencv; 16 | 17 | // Capture object 18 | Capture cam; 19 | 20 | // Array of faces found 21 | Rectangle[] faces; 22 | 23 | void setup() { 24 | size(320, 240,P2D); 25 | 26 | // Start capturing 27 | cam = new Capture(this, 320, 240); 28 | cam.start(); 29 | 30 | // Create the OpenCV object 31 | opencv = new OpenCV(this, cam.width, cam.height); 32 | 33 | // Which "cascade" are we going to use? 34 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 35 | //opencv.loadCascade(OpenCV.CASCADE_EYE); 36 | //opencv.loadCascade(OpenCV.CASCADE_NOSE); 37 | } 38 | 39 | // New images from camera 40 | void captureEvent(Capture cam) { 41 | cam.read(); 42 | } 43 | 44 | void draw() { 45 | 46 | background(0); 47 | 48 | // We have to always "load" the camera image into OpenCV 49 | opencv.loadImage(cam); 50 | 51 | // Detect the faces 52 | faces = opencv.detect(); 53 | 54 | // Draw the video 55 | image(cam, 0, 0); 56 | 57 | // If we find faces, draw them! 58 | if (faces != null) { 59 | for (int i = 0; i < faces.length; i++) { 60 | strokeWeight(2); 61 | stroke(255,0,0); 62 | noFill(); 63 | rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); 64 | } 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /OpenCV/LiveFaceDetect_saveimages/LiveFaceDetect_saveimages.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | 5 | // Now we need the video library 6 | import processing.video.*; 7 | 8 | // Import the library 9 | import gab.opencv.*; 10 | 11 | // We need Java rectangles 12 | import java.awt.Rectangle; 13 | 14 | // Library object 15 | OpenCV opencv; 16 | 17 | // Capture object 18 | Capture cam; 19 | 20 | // Scaled down image 21 | PImage smaller; 22 | 23 | // Array of faces found 24 | Rectangle[] faces; 25 | 26 | int scale = 4; 27 | 28 | void setup() { 29 | size(640, 480); 30 | 31 | // Start capturing 32 | cam = new Capture(this, 640, 480); 33 | cam.start(); 34 | 35 | // Create the OpenCV object 36 | opencv = new OpenCV(this, cam.width/scale, cam.height/scale); 37 | 38 | // Which "cascade" are we going to use? 39 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 40 | 41 | // Make scaled down image 42 | smaller = createImage(opencv.width, opencv.height, RGB); 43 | } 44 | 45 | // New images from camera 46 | void captureEvent(Capture cam) { 47 | cam.read(); 48 | 49 | // Make smaller image 50 | smaller.copy(cam, 0, 0, cam.width, cam.height, 0, 0, smaller.width, smaller.height); 51 | smaller.updatePixels(); 52 | } 53 | 54 | void draw() { 55 | 56 | background(0); 57 | 58 | // We have to always "load" the image into OpenCV 59 | // But we check against the smaller image here 60 | opencv.loadImage(smaller); 61 | 62 | // Detect the faces 63 | faces = opencv.detect(); 64 | 65 | // Draw the video 66 | image(cam, 0, 0); 67 | 68 | // If we find faces, draw them! 69 | if (faces != null) { 70 | for (int i = 0; i < faces.length; i++) { 71 | strokeWeight(2); 72 | stroke(255, 0, 0); 73 | noFill(); 74 | rect(faces[i].x*scale, faces[i].y*scale, faces[i].width*scale, faces[i].height*scale); 75 | } 76 | } 77 | 78 | 79 | fill(255); 80 | textSize(24); 81 | text("Click mouse to save faces to image files",10,height-30); 82 | } 83 | 84 | void mousePressed() { 85 | if (faces != null) { 86 | for (int i = 0; i < faces.length; i++) { 87 | PImage cropped = createImage(faces[i].width*scale, faces[i].height*scale, RGB); 88 | cropped.copy(cam, faces[i].x*scale, faces[i].y*scale, faces[i].width*scale, faces[i].height*scale, 0, 0, faces[i].width*scale, faces[i].height*scale); 89 | cropped.updatePixels(); 90 | cropped.save("faces/face-"+i+".jpg"); 91 | } 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /OpenCV/LiveFaceDetect_scaled/LiveFaceDetect_scaled.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | 5 | // Now we need the video library 6 | import processing.video.*; 7 | 8 | // Import the library 9 | import gab.opencv.*; 10 | 11 | // We need Java rectangles 12 | import java.awt.Rectangle; 13 | 14 | // Library object 15 | OpenCV opencv; 16 | 17 | // Capture object 18 | Capture cam; 19 | 20 | // Scaled down image 21 | PImage smaller; 22 | 23 | // Array of faces found 24 | Rectangle[] faces; 25 | 26 | int scale = 4; 27 | 28 | void setup() { 29 | size(640, 480); 30 | 31 | // Start capturing 32 | cam = new Capture(this, 640, 480); 33 | cam.start(); 34 | 35 | // Create the OpenCV object 36 | opencv = new OpenCV(this, cam.width/scale, cam.height/scale); 37 | 38 | // Which "cascade" are we going to use? 39 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 40 | 41 | // Make scaled down image 42 | smaller = createImage(opencv.width,opencv.height,RGB); 43 | 44 | 45 | } 46 | 47 | // New images from camera 48 | void captureEvent(Capture cam) { 49 | cam.read(); 50 | 51 | // Make smaller image 52 | smaller.copy(cam,0,0,cam.width,cam.height,0,0,smaller.width,smaller.height); 53 | smaller.updatePixels(); 54 | } 55 | 56 | void draw() { 57 | 58 | background(0); 59 | 60 | // We have to always "load" the image into OpenCV 61 | // But we check against the smaller image here 62 | opencv.loadImage(smaller); 63 | 64 | // Detect the faces 65 | faces = opencv.detect(); 66 | 67 | // Draw the video 68 | image(cam, 0, 0); 69 | 70 | // If we find faces, draw them! 71 | if (faces != null) { 72 | for (int i = 0; i < faces.length; i++) { 73 | strokeWeight(2); 74 | stroke(255,0,0); 75 | noFill(); 76 | rect(faces[i].x*scale, faces[i].y*scale, faces[i].width*scale, faces[i].height*scale); 77 | } 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /OpenCV/SaveFaces/Face.pde: -------------------------------------------------------------------------------- 1 | // Which Face Is Which 2 | // Daniel Shiffman 3 | // http://www.shiffman.net 4 | 5 | class Face { 6 | 7 | // A Rectangle 8 | Rectangle r; 9 | 10 | // Am I available to be matched? 11 | boolean available; 12 | 13 | // Should I be deleted? 14 | boolean delete; 15 | 16 | // How long should I live if I have disappeared? 17 | int timer = 127; 18 | 19 | // Assign a number to each face 20 | int id; 21 | 22 | // Make me 23 | Face(int x, int y, int w, int h, int faceCount) { 24 | r = new Rectangle(x,y,w,h); 25 | 26 | available = true; 27 | delete = false; 28 | id = faceCount; 29 | } 30 | 31 | // Show me 32 | void display() { 33 | fill(0,0,255,timer); 34 | stroke(0,0,255); 35 | rect(r.x*scl,r.y*scl,r.width*scl, r.height*scl); 36 | fill(255,timer*2); 37 | text(""+id,r.x*scl+10,r.y*scl+30); 38 | } 39 | 40 | // Give me a new location / size 41 | // Oooh, it would be nice to lerp here! 42 | void update(Rectangle newR) { 43 | r = (Rectangle) newR.clone(); 44 | } 45 | 46 | // Count me down, I am gone 47 | void countDown() { 48 | timer--; 49 | } 50 | 51 | // I am deed, delete me 52 | boolean dead() { 53 | if (timer < 0) return true; 54 | return false; 55 | } 56 | 57 | // Crop the face to a smaller PImage 58 | PImage cropFace(PImage source) { 59 | PImage img = createImage(r.width*scl,r.height*scl,RGB); 60 | img.copy(source,r.x*scl,r.y*scl,r.width*scl,r.height*scl,0,0,r.width*scl,r.height*scl); 61 | img.updatePixels(); 62 | return img; 63 | } 64 | 65 | 66 | } 67 | 68 | -------------------------------------------------------------------------------- /OpenCV/SaveFaces/FaceDetector.pde: -------------------------------------------------------------------------------- 1 | class FaceDetector { 2 | // A list of my Face objects 3 | ArrayList faceList; 4 | ArrayList newFaces; 5 | 6 | // how many have I found over all time 7 | int faceCount = 0; 8 | 9 | FaceDetector() { 10 | faceList = new ArrayList(); 11 | newFaces = new ArrayList(); 12 | } 13 | 14 | void detect(Rectangle[] faces) { 15 | 16 | // Assume no new faces 17 | newFaces.clear(); 18 | 19 | // SCENARIO 1: faceList is empty 20 | if (faceList.isEmpty()) { 21 | // Just make a Face object for every face Rectangle 22 | for (int i = 0; i < faces.length; i++) { 23 | Face f = new Face(faces[i].x, faces[i].y, faces[i].width, faces[i].height, faceCount); 24 | newFace(f); 25 | } 26 | // SCENARIO 2: We have fewer Face objects than face Rectangles found from OPENCV 27 | } 28 | else if (faceList.size() <= faces.length) { 29 | boolean[] used = new boolean[faces.length]; 30 | // Match existing Face objects with a Rectangle 31 | for (Face f : faceList) { 32 | // Find faces[index] that is closest to face f 33 | // set used[index] to true so that it can't be used twice 34 | float record = 50000; 35 | int index = -1; 36 | for (int i = 0; i < faces.length; i++) { 37 | float d = dist(faces[i].x, faces[i].y, f.r.x, f.r.y); 38 | if (d < record && !used[i]) { 39 | record = d; 40 | index = i; 41 | } 42 | } 43 | // Update Face object location 44 | used[index] = true; 45 | f.update(faces[index]); 46 | } 47 | // Add any unused faces 48 | for (int i = 0; i < faces.length; i++) { 49 | if (!used[i]) { 50 | Face f = new Face(faces[i].x, faces[i].y, faces[i].width, faces[i].height, faceCount); 51 | newFace(f); 52 | } 53 | } 54 | // SCENARIO 3: We have more Face objects than face Rectangles found 55 | } 56 | else { 57 | // All Face objects start out as available 58 | for (Face f : faceList) { 59 | f.available = true; 60 | } 61 | // Match Rectangle with a Face object 62 | for (int i = 0; i < faces.length; i++) { 63 | // Find face object closest to faces[i] Rectangle 64 | // set available to false 65 | float record = 50000; 66 | int index = -1; 67 | for (int j = 0; j < faceList.size(); j++) { 68 | Face f = faceList.get(j); 69 | float d = dist(faces[i].x, faces[i].y, f.r.x, f.r.y); 70 | if (d < record && f.available) { 71 | record = d; 72 | index = j; 73 | } 74 | } 75 | // Update Face object location 76 | Face f = faceList.get(index); 77 | f.available = false; 78 | f.update(faces[i]); 79 | } 80 | // Start to kill any left over Face objects 81 | for (Face f : faceList) { 82 | if (f.available) { 83 | f.countDown(); 84 | if (f.dead()) { 85 | f.delete = true; 86 | } 87 | } 88 | } 89 | } 90 | 91 | // Delete any that should be deleted 92 | for (int i = faceList.size()-1; i >= 0; i--) { 93 | Face f = faceList.get(i); 94 | if (f.delete) { 95 | faceList.remove(i); 96 | } 97 | } 98 | } 99 | 100 | 101 | // Add a new face to the world 102 | void newFace(Face f) { 103 | faceList.add(f); 104 | newFaces.add(f); 105 | faceCount++; 106 | } 107 | 108 | // Save the faces as images 109 | void saveNewFaces() { 110 | for (Face f : newFaces) { 111 | PImage cropped = f.cropFace(cam); 112 | cropped.save("faces/face-"+f.id+".jpg"); 113 | } 114 | } 115 | 116 | // Draw the faces 117 | void showFaces() { 118 | for (Face f : faceList) { 119 | f.display(); 120 | } 121 | } 122 | } 123 | 124 | -------------------------------------------------------------------------------- /OpenCV/SaveFaces/SaveFaces.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | // https://github.com/shiffman/Faces 5 | 6 | import processing.video.*; 7 | 8 | // Video library 9 | import processing.video.*; 10 | 11 | // OpenCV Library 12 | import gab.opencv.*; 13 | 14 | // Java Rectangle class 15 | import java.awt.Rectangle; 16 | 17 | 18 | // OpenCV and Capture 19 | OpenCV opencv; 20 | Capture cam; 21 | 22 | // We will need a smaller image for fast real-time detection 23 | PImage smaller; 24 | 25 | int scl = 4; // Overall scale for drawing faces 26 | 27 | FaceDetector detector; 28 | 29 | void setup() { 30 | size(640, 480); 31 | opencv = new OpenCV(this, width/scl, height/scl); 32 | // Scaled down image 33 | smaller = createImage(opencv.width, opencv.height, RGB); 34 | // Larger capture object 35 | cam = new Capture(this, width, height); 36 | cam.start(); 37 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 38 | 39 | // A generic time-based face detector 40 | detector = new FaceDetector();} 41 | 42 | void captureEvent(Capture cam) { 43 | cam.read(); 44 | } 45 | 46 | void draw() { 47 | background(0); 48 | image(cam,0,0); 49 | 50 | smaller.copy(cam,0,0,cam.width,cam.height,0,0,smaller.width,smaller.height); 51 | smaller.updatePixels(); 52 | opencv.loadImage(smaller); 53 | 54 | Rectangle[] faces = opencv.detect(); 55 | detector.detect(faces); 56 | 57 | detector.showFaces(); 58 | detector.saveNewFaces(); 59 | } 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /OpenCV/SimpleFaceDetect/SimpleFaceDetect.pde: -------------------------------------------------------------------------------- 1 | // Face It 2 | // ITP Fall 2013 3 | // Daniel Shiffman 4 | // https://github.com/shiffman/Faces 5 | 6 | // Import the library 7 | import gab.opencv.*; 8 | 9 | // We need Java rectangles 10 | import java.awt.Rectangle; 11 | 12 | // Library object 13 | OpenCV opencv; 14 | 15 | // An image 16 | PImage img; 17 | 18 | // Array of faces found 19 | Rectangle[] faces; 20 | 21 | void setup() { 22 | size(640, 480); 23 | // Load the image 24 | img = loadImage("obama.jpg"); 25 | // Create the OpenCV object 26 | opencv = new OpenCV(this, img.width, img.height); 27 | // Put image into OpenCV 28 | opencv.loadImage(img); 29 | 30 | // Which "cascade" are we going to use? 31 | opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 32 | //opencv.loadCascade(OpenCV.CASCADE_EYE); 33 | //opencv.loadCascade(OpenCV.CASCADE_NOSE); 34 | 35 | 36 | 37 | // Detect! 38 | faces = opencv.detect(); 39 | } 40 | 41 | void draw() { 42 | background(0); 43 | // Draw the image 44 | image(img, 0, 0); 45 | 46 | // If we found faces 47 | if (faces != null) { 48 | // Draw them all 49 | for (int i = 0; i < faces.length; i++) { 50 | strokeWeight(2); 51 | stroke(255, 0, 0); 52 | noFill(); 53 | rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); 54 | } 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /OpenCV/SimpleFaceDetect/data/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiffman/Face-It/b69544a668e3f3af63eb69fbe156f7fb02c5ca53/OpenCV/SimpleFaceDetect/data/obama.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Face It Syllabus 2 | ================ 3 | 4 | A "syllabus" and repository of Processing examples for ITP fall workshop about face detection, recognition, and miscellaneous tracking methods. 5 | 6 | # Day 1, Saturday, September 28, 10-5 7 | 8 | ## 10:00 AM - Overview of day 9 | * Detection vs. Recognition vs. Tracking 10 | 11 | ## 10:15 AM - Reference Projects 12 | 13 | * Face Detection 14 | * [Drawing faces as instructed by facial detection](http://plummerfernandez.tumblr.com/post/54596732227/drawing-faces-as-instructed-by-facial-recognition) 15 | * [Portrait – Discovering centric figure(s) of movies using facial recognition](http://ssbkyh.com/works/portrait/) 16 | * [Cloud Faces](http://ssbkyh.com/works/cloud_face/) 17 | * [Google Earth Faces](http://www.onformative.com/lab/googlefaces/) 18 | * [CVDazzle](http://cvdazzle.com/) 19 | * Face Recognition 20 | * [Spurious Memories](http://deweyhagborg.com/spurious/) 21 | * Face Tracking 22 | * [Dance with your face](http://www.youtube.com/watch?v=dplBh_rxoUc) 23 | * [Face Substitution](https://vimeo.com/29279198), [Source](https://github.com/arturoc/FaceSubstitution) 24 | * [Kamio IOS app](https://itunes.apple.com/us/app/kamio/id668849062?mt=8) 25 | * [All the Universe is Full of the Lives of Perfect Creatures](https://vimeo.com/35262930) 26 | * [Typface](http://www.rhymeandreasoncreative.com/portfolio/index.php?project=typeface) 27 | * Other 28 | * [Split Faces](http://www.mymodernmet.com/profiles/blogs/split-family-faces) by http://www.ulriccollette.com/ 29 | * [Blind self-portrait](https://vimeo.com/40279845) and [Self-Portrait Machine](http://we-make-money-not-art.com/archives/2009/07/selfportrait-machine.php#.UkQ27WTXhTs) 30 | * The Human Face Documentary: [Part 1](http://www.youtube.com/watch?v=8HlqbSDqmE4), [Part 2](http://www.youtube.com/watch?v=dEocYZmuxbs), [Part 3](http://www.youtube.com/watch?v=HJpqoAkWgXI), [Part 4](http://www.youtube.com/watch?v=IDAsQQE0Il4) 31 | 32 | ## 11:00 AM - OpenCV Face Detection 33 | * How it works 34 | * [Download Release](https://github.com/atduskgreg/opencv-processing/releases),[Processing OpenCV library](https://github.com/atduskgreg/OpenCVPro) 35 | * [Face Detection visualized by Adam Harvey](https://vimeo.com/12774628) 36 | * [Interview with Adam Harvey re: Face Detection](http://makematics.com/research/viola-jones/) 37 | * [Haarcascade Visualizer](https://github.com/adamhrv/HaarcascadeVisualizer) -- Note this requires Processing 1.5.1 38 | * Examples 39 | * [Detect face in image](https://github.com/shiffman/Faces/tree/master/OpenCV/SimpleFaceDetect) 40 | * [Detect face in live video](https://github.com/shiffman/Faces/tree/master/OpenCV/LiveFaceDetect) 41 | * [scale down resolution for performance](https://github.com/shiffman/Faces/tree/master/OpenCV/LiveFaceDetect_scaled) 42 | * [save face as JPG](https://github.com/shiffman/Faces/tree/master/OpenCV/LiveFaceDetect_saveimages) 43 | * [track faces over time](https://github.com/shiffman/Faces/tree/master/OpenCV/FaceDetectMemory) 44 | * [save faces as images](https://github.com/shiffman/Faces/tree/master/OpenCV/SaveFaces) 45 | * [Face Detection in JavaScript!](http://inspirit.github.io/jsfeat/sample_haar_face.html) 46 | 47 | ## 12:00 PM - Lunch 48 | 49 | ## 1:00 PM - Face Recognition 50 | * How it works 51 | * [Eigenfaces](http://jeremykun.wordpress.com/2011/07/27/eigenfaces/) 52 | * [Processing example](https://github.com/atduskgreg/Processing-Eigenfaces) from Greg Borenstein using [Processing-Eigenfaces](https://github.com/atduskgreg/Processing-Eigenfaces) 53 | * [More algorithms and stuff](http://www.face-rec.org/) 54 | * But let's just use an API! 55 | * [Rekognition](http://rekognition.com/), [Sign up for API key](http://rekognition.com/register/) 56 | * [Rekognition for Processing Library](https://github.com/shiffman/RekognitionProcessing/releases/tag/0.1) 57 | * also requires [HTTProcessing](https://www.dropbox.com/s/fqzddqqfhzt7580/HTTProcessing.zip) 58 | * Examples 59 | * [Detect a Face](https://github.com/shiffman/Faces/tree/master/FaceRekognition/FaceDetectExample) 60 | * [Train a Face](https://github.com/shiffman/Faces/tree/master/FaceRekognition/FaceTrainExample) 61 | * [Recognize a Face](https://github.com/shiffman/Faces/tree/master/FaceRekognition/FaceRecognizeExample) 62 | * [Look at raw JSON](https://github.com/shiffman/Faces/tree/master/FaceRekognition/RawJSONExample) 63 | * [Threaded request](https://github.com/shiffman/Faces/tree/master/FaceRekognition/FaceRecognizeExampleThread) 64 | * [Putting it all together with Live OpenCV](https://github.com/shiffman/Faces/tree/master/FaceRekognition/Greeter) 65 | * [Lambda Labs](http://www.lambdal.com/) 66 | * [Processing library in progress](https://github.com/shiffman/LambdaProcessing) -- talk to me if you want to use this. 67 | 68 | ## 2:30 PM - Face Tracking 69 | * [FaceTracker](https://github.com/kylemcdonald/FaceTracker) by [Jason Saragih](http://jsaragih.org/). 70 | * [Interview with Kyle McDonald about FaceTracker](http://makematics.com/research/facetracker/) 71 | * Original "[Deformable Model Fitting by Regularized Landmark Mean-Shift](http://link.springer.com/article/10.1007%2Fs11263-010-0380-4)" paper. 72 | * [ofxFaceTracker](https://github.com/kylemcdonald/ofxFaceTracker) for direct use in OF. 73 | * [FaceOSC Downloads](https://github.com/kylemcdonald/ofxFaceTracker/downloads) for use with Processing and other applications 74 | * [FaceOSC + Syphon to get image into Processing](https://github.com/downloads/kylemcdonald/ofxFaceTracker/FaceOSC-osx+Syphon.zip) 75 | * [Blink detection OSC](https://github.com/downloads/kylemcdonald/ofxFaceTracker/BlinkExample-osx.zip) 76 | * OSC 77 | * [oscp5](http://www.sojamo.de/libraries/oscP5/) (install through Processing library manager) 78 | * [Osculator](http://www.osculator.net/) for help with debugging OSC 79 | * Examples 80 | * [Simple Tracker Data Demo](https://github.com/shiffman/Faces/tree/master/FaceOSC/FaceOSCDemo) 81 | * [All Points](https://github.com/shiffman/Faces/tree/master/FaceOSC/FaceOSCAllPoints) 82 | * [Triangle Mesh](https://github.com/shiffman/Faces/tree/master/FaceOSC/FaceOSCTriangleMesh) 83 | * [Puppet Face](https://github.com/shiffman/Face-It/tree/master/FaceOSC/FaceOSCPuppet), Requires: [FaceOSC-Img](https://www.dropbox.com/s/fzjznyiksvd6z0v/FaceOSC-img.zip) 84 | * [Blink Particles](https://github.com/shiffman/Faces/tree/master/FaceOSC/BlinkParticles) - requies: [BlinkExample](https://github.com/kylemcdonald/ofxFaceTracker/downloads) 85 | * [More Processing Examples](https://github.com/kylemcdonald/FaceOSC-Templates/tree/master/processing) 86 | * [All OF Examples](https://github.com/kylemcdonald/ofxFaceTracker) 87 | * [FaceShift](http://faceshift.com/) 88 | * [download free trial](http://www.faceshift.com/get-trial/) - 30 days only, noncommercial license avaialble for $150 and there will be a faceshift laptop in ER for checkout with academic license. 89 | * [ofxFaceShift](https://github.com/kylemcdonald/ofxFaceShift) for direct use in OF 90 | * [FaceShiftOSC tutorial](https://vimeo.com/46916078) from Kyle (note the tutorial uses an older version of FaceShift but concepts still apply). 91 | * [FaceShiftOSC download](https://github.com/kylemcdonald/ofxFaceShift/downloads) 92 | * [Simple OSC Processing Example](https://github.com/shiffman/Faces/tree/master/FaceShift) 93 | * Face Morphing 94 | * [How it works](https://ccrma.stanford.edu/~jacobliu/368Report/) 95 | * [Michael Jackson Black or White video](http://www.youtube.com/watch?feature=player_detailpage&v=bBAiZcNWecw#t=330s) 96 | * Examples 97 | * [Triangle Interpolation with Textures](https://github.com/shiffman/Face-It/tree/master/FaceMorphing/TextureDemo) 98 | * [Face Morphing](https://github.com/shiffman/Face-It/tree/master/FaceMorphing/FaceMorph) 99 | 100 | ## 4:00 PM - Wrap-Up / Project Idea Discussion 101 | 102 | ## Homework 103 | * [Post a link to your work here](https://github.com/shiffman/Face-It/wiki/Face-It-Projects) 104 | 105 | # Day 2, Friday, October 4th, 3:30-6 106 | 107 | ## Project Presentations 108 | 109 | 110 | --------------------------------------------------------------------------------