EliRosen – FaceOSC
[youtube https://www.youtube.com/watch?v=LCVDSafRvH8&w=600&h=437]
I used the FaceOSC data to animate a simple puppet of an old man. I put the puppet together in photoshop from an image I found on google images. The old man’s glasses move up and down in response to the user moving his eyebrows. The user also controls the old mans mouth. When the puppet opens its mouth it spews colorful balls towards the screen.
// A puppet by Eli Rosen based on // a template for receiving face tracking osc messages from // Kyle McDonald's FaceOSC https://github.com/kylemcdonald/ofxFaceTracker // // 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.*; OscP5 oscP5; // num faces found int 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; //variables for puppet images PImage face; PImage glasses; PImage chin; //variable to store last eyebrow value (for reducing jitter) float eyebrowLast = eyebrowRight; //array of particle positions PVector[] pArray = new PVector[1]; //array of particle sizes float[] pSize = new float[1]; //particle color array color[] pColor = new color[1]; void setup() { size(640, 480); frameRate(30); 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"); //load the puppet images face = loadImage("face.png"); glasses = loadImage("glasses.png"); chin = loadImage("chin.png"); //set color mode to HSB colorMode(HSB, 255); smooth(); } void draw() { background(255); if(found > 0) { //center and scale the elements translate(posePosition.x, posePosition.y); scale(poseScale*.8); //draw the face image(face, -45, -65,face.width*.25, face.height*.25); //save the new eyebrow position float eyebrowNew = eyebrowRight; //get the difference between the old eyebrow position and the new one float eyebrowDif = eyebrowNew - eyebrowLast; // check if the eyebrow moved beyond a certain threshold if(Math.abs(eyebrowDif) > .35) { //if it did then draw it with the new position image(glasses, -29, /*-10*/(eyebrowNew*-4)+22,glasses.width*.25, glasses.height*.25); //update the last eyebrow variable eyebrowLast = eyebrowNew; } // if eyebrows did not move enough redraw the glasses in the same position as last time else { image(glasses, -29, /*-10*/(eyebrowLast*-4)+22,glasses.width*.25, glasses.height*.25); } // draw the chin based on jaw position image(chin, -14, jaw*1.6,chin.width*.25, chin.height*.25); // check if the jaw is open if(jaw > 22) { //generate a random hue number int randomHue = int(random(0,256)); // get a random x and y that fall within the mouth area float xPos = random(-2,14); float yPos = random(36,40); // use the random hue to create a color color fillColor = color(randomHue,200,40); // create a new pVector and store the random x and y PVector p = new PVector(xPos, yPos); // create temporary arrays for copying the current arrays PVector[] tempArray = new PVector[pArray.length+1]; float[] tempArray2 = new float[pSize.length+1]; color[] tempArray3 = new color[pColor.length+1]; // copy the current particle attribute arrays for (int i = 0; i < pArray.length; i++) { tempArray[i] = pArray[i]; tempArray2[i] = pSize[i]; tempArray3[i] = pColor[i]; } // set the global arrays to be the new updated arrays pArray = tempArray; pSize = tempArray2; pColor = tempArray3; // add the new Pvector to the pvector array pArray[pArray.length-1] = p; // add the new color to the color array pColor[pColor.length-1] = fillColor; // set the drawing style for the new particle noStroke(); fill(fillColor); // set the size of the new particle float newSize = 2; // add the new particle size to the particle size array pSize[pSize.length-1]=newSize; // draw the new particle ellipse(p.x,p.y,newSize,newSize); } // loop through all particles for(int i=1; i < pArray.length; i++) { // move the particles y positions down pArray[i].y = pArray[i].y + random(1,3); // get the particles distance from the center of the face float xDif = Math.abs(pArray[i].x - 6); // if the particle is to the left of center move it further left if(pArray[i].x <=6) { // base magnitude of move on distance from center pArray[i].x = pArray[i].x - random(1,3)*.05*xDif; } // if particle is to the right of center move it further right else { // base magnitude of move on distance from center pArray[i].x = pArray[i].x + random(1,3)*.05*xDif; } // increase the size of the particle pSize[i]= pSize[i]+random(0,1); // brighten the particle float tempH = hue(pColor[i]); float tempS = saturation(pColor[i]); float tempB = brightness(pColor[i])+13; pColor[i] = color(tempH, tempS, tempB); // set fill color to new brighter color fill(pColor[i]); // draw the particle with all updated attributes ellipse(pArray[i].x, pArray[i].y, pSize[i], pSize[i]); } } } // 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); } } |
Comments Off on EliRosen – FaceOSC