John Brieger — Face OSC

by John Brieger @ 6:49 am 24 January 2012

[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);
      }
    }
  }
}

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2023 Interactive Art and Computational Design, Spring 2012 | powered by WordPress with Barecity