John Brieger — Face OSC
[vimeo=35562537 w=605&h=400]
Uses Face_OSC to do facial recognition, smiling and mouth movement to control an array of LED’s that respond in real time to facial features. Raising your eyebrows flashes the lights on the back of the collar in rapid succession, letting everyone around know if you are surprised or angry.
The dress itself is part of a fashion collaboration between myself and Alanna Fusaro. You can see our full line here.
Sorry for the rendering issues in the video.
Processing Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | // John Brieger // IACD 2012 // // // // Facetracking through: // Kyle McDonald's FaceOSC https://github.com/kylemcdonald/ofxFaceTracker // // this example includes a class to abstract the Face data // // 2012 Dan Wilcox danomatika.com // for the IACD Spring 2012 class at the CMU School of Art // // adapted from from Greg Borenstein's 2011 example // http://www.gregborenstein.com/ // https://gist.github.com/1603230 import oscP5.*; import processing.serial.*; Serial port = null; OscP5 oscP5; // our FaceOSC tracked face dat Face face = new Face(); void setup() { size(600, 720); frameRate(30); //setup serial connection to Arduino println("Available serial ports:"); String[] serialList =Serial.list(); println(serialList); if(serialList.length != 0) { port = new Serial(this, serialList[0], 9600); } else println("No Available Serial Ports!"); oscP5 = new OscP5(this, 8338); } void draw() { background(255); stroke(0); if (port == null) { //check for available serial ports String[] serialList =Serial.list(); if(serialList.length != 0) { println("Found Serial Port!"); println(serialList); println("\n"); port = new Serial(this, serialList[0], 9600); } } if (face.found > 0) { // write data out to port if(port != null) { port.write('Y'); float browHeightAvg = (face.eyebrowLeft + face.eyebrowRight) /2.0; if(browHeightAvg >= 8.0) { print("Brow Raised!"); port.write('^'); } else { port.write('_'); } port.write('B'); //mouth is a formula based off sqrt of area float mouthArea= face.mouthWidth * face.mouthHeight; float sqr = sqrt(mouthArea); byte mouthSend = (byte)((int)sqr); port.write(mouthSend); println("Mouth Sent: "+mouthSend); port.write('M'); } print(face.toString()); } else { //no face if(port != null) { port.write('N'); } } } // OSC CALLBACK FUNCTIONS void oscEvent(OscMessage m) { face.parseOSC(m); } |
Arduino Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | int currentPattern; const int DEFAULTPATTERN = 0; const int FACEPATTERN = 1; int ledArray[14]; int currentLED; // the number of the LED pin int index; int updown= 1; long previousMillis = 0; // will store last time LED was updated long interval = 125; // interval at which to blink (milliseconds) int noFaceCount = 0; int noRaiseCount = 0; char buff[]= "0000000000"; //charbuff for serial boolean browRaise = false; int mouthPin = 3; int browPin = 10; boolean brow = false; int mouth = 12; void setup() { // set the digital pins as output: pinMode(0, OUTPUT); pinMode(1, OUTPUT); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT); pinMode(12, OUTPUT); pinMode(13, OUTPUT); Serial.begin(9600); updown = 1; index = 0; currentLED =0; currentPattern = DEFAULTPATTERN; } void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { // save the last time you blinked the LED previousMillis = currentMillis; while( Serial.available() > 0) { for (int i=0; i= 10) { browRaise = false; } } break; case 'M': mouthPin = (int)(buff[9]); if (mouthPin>9){ mouthPin = 9; } break; case 'Y': if(currentPattern == DEFAULTPATTERN) { for(int i = 0; i = 40){ //turn all off; if(currentPattern == FACEPATTERN) { for(int i = 0; i <=13; i++) { digitalWrite(i, LOW); } updown = 1; currentLED = 0; index = 0; } currentPattern = DEFAULTPATTERN; } break; } } //HERE BE PATTERNS! //PATTERNTASTIC! if(currentPattern == DEFAULTPATTERN) { if(updown == 1) { if(currentLED != 0) { digitalWrite(currentLED-1, LOW); } index++; if(index == 13) { updown = -1; } } else { if(currentLED != 13) { digitalWrite(currentLED+1, LOW); } index--; if(index == 0) { updown = 1; } } //currentLED= ledArray[index]; currentLED=index; // set the LED with the ledArraytate of the variable: digitalWrite(currentLED, HIGH); delay(125); } //YAY FACES else if(currentPattern == FACEPATTERN){ for(int i = 0; i<= mouthPin; i++){ digitalWrite(i, HIGH); } for( int i =mouthPin+1; i<10;i++) { digitalWrite(i,LOW); } if(browRaise) { digitalWrite(currentLED, LOW); if(updown == 1) { index++; if(index == 13) { updown = -1; } } else { index--; if(index == 10) { updown = 1; } } currentLED = index; digitalWrite(currentLED, HIGH); } else{ digitalWrite(11, LOW); digitalWrite(12, LOW); digitalWrite(13, LOW); digitalWrite(10, HIGH); } } } } |