Zack J-W Face_OSC

by zack @ 1:01 am 24 January 2012

One of the first things I noticed about Face_OSC is that it’s awesome and my wife thought you had to yell at it for it work.  The next thing I noticed is that it doesn’t read facial hair well and, well, I have some.

So I thought it would be appropriate to use Face_OSC to deal with the one thing it hadn’t, err, faced at least in a metaphorical sense.  I came to find out that it was a known unknown.  Golan lamented that it dealt with beards in a maddening way and Dan Wilcox suggested with one frown that it was a computational nightmare.  So I hope programmers get a kick out of it.

One technical hurdle was, using a camera for both the background image and face tracking meant two cameras (at least in my limited capacity as a coder).  Processing would not share with Face_OSC and vice versa from the computers built in camera.  Having an external web-cam meant I was always going to have an offset between the two focal points which is exacerbated by scale and movement.  A better code may be able to compensate for this.

Credit where credit is due:  Thanks to Dan Wilcox for bringing the Titty Tracker into the world.  Clearly an inspiration.

Video becomes worthless after 1:30…

[youtube https://www.youtube.com/watch?v=VToNr8IQTp4]

 

import processing.video.*;
Capture video;
 
import oscP5.*;
OscP5 oscP5;
 
PImage[] images = new PImage[6];
 
int b, found;
 
// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();
 
// gesture
float mouthHeight;
float mouthWidth;
float eyeLeft;
float eyeRight;
float eyebrowLeft;
float eyebrowRight;
float jaw;
float nostrils;
 
void setup()
{
  size(640,480);
  frameRate(2);
  imageMode(CENTER);
  b = 0;
 
  video = new Capture(this, width, height);
 
  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "poseScale", "/pose/scale");
  oscP5.plug(this, "posePosition", "/pose/position");
  oscP5.plug(this, "poseOrientation", "/pose/orientation");
  oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width");
  oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
  oscP5.plug(this, "eyeLeftReceived", "/gesture/eye/left");
  oscP5.plug(this, "eyeRightReceived", "/gesture/eye/right");
  oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left");
  oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right");
  oscP5.plug(this, "jawReceived", "/gesture/jaw");
  oscP5.plug(this, "nostrilsReceived", "/gesture/nostrils");
 
  for ( int i = 0; i< images.length; i++ )   {     images[i] = loadImage( i + ".png" );   // make sure images "0.png" to "?.png" exist   } } void draw() {     if (video.available()) {     video.read();     image(video, width/2, height/2);       // background(0);      if(found > 0)
  {
    scale(poseScale*.12);
    image(images[b], posePosition.x*poseScale - width*.75 ,posePosition.y*poseScale + height*.1);
  }
}
}
 
void keyPressed()
{
  if (keyPressed && key == ' ' )
  {
    b = (b + 1) % 6;
  }
  redraw();
}
 
// OSC CALLBACK FUNCTIONS
 
public void found(int i) {
  println("found: " + i);
  found = i;
}
 
public void poseScale(float s) {
  println("scale: " + s);
  poseScale = s;
}
 
public void posePosition(float x, float y) {
  println("pose position\tX: " + x + " Y: " + y );
  posePosition.set(x, y, 0);
}
 
public void poseOrientation(float x, float y, float z) {
  println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
  poseOrientation.set(x, y, z);
}
 
public void mouthWidthReceived(float w) {
  println("mouth Width: " + w);
  mouthWidth = w;
}
 
public void mouthHeightReceived(float h) {
  println("mouth height: " + h);
  mouthHeight = h;
}
 
public void eyeLeftReceived(float f) {
  println("eye left: " + f);
  eyeLeft = f;
}
 
public void eyeRightReceived(float f) {
  println("eye right: " + f);
  eyeRight = f;
}
 
public void eyebrowLeftReceived(float f) {
  println("eyebrow left: " + f);
  eyebrowLeft = f;
}
 
public void eyebrowRightReceived(float f) {
  println("eyebrow right: " + f);
  eyebrowRight = f;
}
 
public void jawReceived(float f) {
  println("jaw: " + f);
  jaw = f;
}
 
public void nostrilsReceived(float f) {
  println("nostrils: " + f);
  nostrils = f;
}
 
// all other OSC messages end up here
void oscEvent(OscMessage m) {
  if(m.isPlugged() == false) {
    println("UNPLUGGED: " + m);
  }
}

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