Wednesday, May 8, 2013

ISTA 401: Final Project- Faces



Faces is work that achieves no clear goal, does not infer a motive, nor does it follow conventional rules regarding art. It may be best to consider it close to a Dadaist or anti-art work because if anything it’s mocking art. The project started as several ideas and has slowly merged into one clearly identifiable work.

Concept number one was an idea that with a phone you could write on a virtual wall at any time. Drawn from a project that allowed users to virtually draw on buildings with laser pointers it was a natural urge to try and condense the huge space the original project worked in to a small show room. For this we would use a camera watching a crowd in front of a projected mirror or essentially an image on the crowd just projected in front of the crowd. The crowd would watch the mirror and see themselves with but with a slight twist. If someone pulled out their phone and opened an app that turned the screen a green screen green you could then write on the mirror with your phone by holding it up to the camera. The technical details are simple enough. A camera watching the crowd would be looking for a certain color AKA green screen green. If it were to see the color it changes the pixels where the green is and output to a solid color. The projector showing the mirror then displays this altered image with a drawing on it. The total effect makes the user fell like he/she is drawing on the mirror with a phone. The idea was great for several reasons. First it was user interactive which in my opinion is always very important. Second the user controls the outcome of the work. Once the program is set, it is left to the masses for them to decide its fate. The implementation of this was more complex than we could attempt in a 4 week assignment so we moved on to our next idea.

This idea was drawn from two different sources and merged together. One of my partner’s mothers had the idea of a picture where the eyes in the picture would follow you wherever you went. Not a bad idea in our opinion, although slightly creepy. So we ran with it and combined our former idea of using a device as a drawing tool to a pointing tool. Not that far of a jump in our opinion. Thus we came up with a system where the camera looks for a laser pointers bright dot on a surface. Where that dot was located would be where the creepy eyes of our picture would be. It worked . . . for the most part. Initially we used a library called Mayron for the image analysis but we ran into limitations. The library could only see certain colors and would see every one of the pixels currently that color. A problem when a laser pointers dot generally looks like white. The program would find all pixels with white and essentially crash. This wasn’t going to work.
Our last and final iteration was only a natural step to take from iteration #2. We wanted the eye of the portraits to follow people so we need some software that could recognize people. Turns out there is a library called openCV that has a facial recognition feature embedded in it. This was perfect! We implemented it in so that the eye would follow a face walking by the image and we had our final product.

Well it wasn’t quiet that easy. openCV is a great piece of software that has been adapted and used on many different projects, programs and operating systems. It is very popular in image processing and helped us tremendously but not without some headaches. First we found that importing the openCV library into processing on a PC it’s close to impossible. Further its not possible on a 64-bit machine which is what mine is. Fortunately it is very easy to use with a Mac and so we used all Mac’s to complete the project. We also wanted a nice variation of portraits to be shown show we made a slide show feature with a fade in and out. This works perfectly creating the virtual art galllery feel that we were looking for with a special, creepy modification. Now we have the full effect. 

Together as a team we completed this very complex and ever changing projcet. I have to give full credit to my teammates for all their hard work. I personally did all of the eye placement and work to get them to match up with the pictures that my partner edited for eye holes. It was a fun project and a creepy outcome. Just picture this in an art gallery. You would initially think its just a projection of a famous painting but the notice that it is watching you everywhere you go!

Code below:

import hypermedia.video.*;
import java.awt.Rectangle;

OpenCV opencv;
// contrast/brightness values
int contrast_value    = 0;
int brightness_value  = 0;
int X1;
int Y1;
int X2;
int Y2;
int opac=255;
int order = 0;
int m=0;
int last=0;
boolean active = false;
boolean X = false;
boolean next = false;


int xcenterlefteye;
int ycenterlefteye;
int xcenterrighteye;
int ycenterrighteye;

int eyewidth;
int eyeheight;

int leftedgelefteye;
int rightedgelefteye;

int leftedgerighteye;
int rightedgerighteye;

int topedgelefteye;
int bottomedgelefteye;

int topedgerighteye;
int bottomedgerighteye;

int X12;
int Y12;
int X22;
int Y22;

int xcenterlefteye2;
int ycenterlefteye2;
int xcenterrighteye2;
int ycenterrighteye2;

int eyewidth2;
int eyeheight2;

int leftedgelefteye2;
int rightedgelefteye2;

int leftedgerighteye2;
int rightedgerighteye2;

int topedgelefteye2;
int bottomedgelefteye2;

int topedgerighteye2;
int bottomedgerighteye2;

PImage imgMona;
PImage imgjohn;
PImage imgobama;
PImage imgfarm;
PImage imggw;

void setup() {

    size( 1280, 800 );

    opencv = new OpenCV( this );
    opencv.capture( width, height);                   // open video stream
    opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT );  // load detection description, here-> front face detection : "haarcascade_frontalface_alt.xml"
    
    imgMona = loadImage("Mona.png");
    imgjohn = loadImage("john.png");
    imgobama = loadImage("obama.png");
    imgfarm = loadImage("farm.png");
    imggw = loadImage("gw.png");

}


public void stop() {
    opencv.stop();
    super.stop();
}


void draw() {
    background(0);
    int h = height;
    int w= width;
    opencv.read();
    //opencv.absDiff();
    opencv.flip( OpenCV.FLIP_HORIZONTAL );
   
    print("time " +m/1000+"\n");
    print("order " +order+"\n");
    print("next " +next+"\n");
    print("active " +active+"\n\n\n\n");
    
    m = millis()-last;
    
    if(millis()>last+30000){
      last=millis();
      next=true;
    }
     if(next){
      opac = opac-25;
      print("-opac = " +opac+'\n');
     }
     if((opac<-25) && (active==false)){
       next=false;
       active = true;
       order = order + 1;
     }
     if(active){
       
       opac = opac + 25;
       print("+opac = " +opac+'\n');
     }
     if ((opac > 255) && (active)){
        active=false;
       
     }
     if(order==5){
       order=0;
     }
     
    // proceed detection
    Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );

   
    
    // draw face area(s)
    noFill();
    //stroke(255,0,0);
    noStroke();
    for( int i=0; i<faces.length; i++ ) {
        rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height ); 
        X1=(faces[i].x+(faces[i].width/2));
        Y1=(faces[i].y+(faces[i].height/2));
        X12=(faces[i].x+(faces[i].width/2));
        Y12=(faces[i].y+(faces[i].height/2));
        //print("X "+X1+ "    Y "+ Y1+"\n");
    }
    ellipseMode(CENTER);

 stroke(0);   
    
  if (order==0){
        //Mona
        xcenterlefteye = 605;
        ycenterlefteye = 275;
        xcenterrighteye = 685;
        ycenterrighteye = 275;
        
        eyewidth = 40;
        eyeheight = 20;
        
        leftedgelefteye = xcenterlefteye - eyewidth/2;
        rightedgelefteye = xcenterlefteye + eyewidth/2;
      
        leftedgerighteye = xcenterrighteye - eyewidth/2;
        rightedgerighteye = xcenterrighteye + eyewidth/2;
      
        topedgelefteye = ycenterlefteye - eyeheight/2;
        bottomedgelefteye = ycenterlefteye + eyeheight/2;
      
        topedgerighteye = ycenterrighteye - eyeheight/2;
        bottomedgerighteye = ycenterlefteye + eyeheight/2;
        
        
        //left eye
        float x1 = map(X1, 0, width, leftedgelefteye, rightedgelefteye);
        float y1 = map(Y1, 0, height, topedgelefteye, bottomedgelefteye);
        //right eye
        float x2 = map(X1, 0, width, leftedgerighteye, rightedgerighteye);
        float y2 = map(Y1, 0, height, topedgerighteye, bottomedgerighteye);
        
        ellipseMode(CENTER);
        
        //eyes
        fill(231,192,105,opac);
        ellipse(xcenterlefteye, ycenterlefteye, eyewidth, eyeheight);
        ellipse(xcenterrighteye, ycenterrighteye, eyewidth, eyeheight);
       
         
        //pupils
        fill(0,0,0,opac);
        ellipse(x1, y1, 10, 10);
        ellipse(x2, y2, 10, 10);
        
        tint(255,opac);
        image(imgMona,width/2-400,0);
  }
  
  if (order==1) { 
        //obama
        xcenterlefteye = 640;
        ycenterlefteye = 320;
        xcenterrighteye = 710;
        ycenterrighteye = 317;
        
        eyewidth = 35;
        eyeheight = 15;
        
        leftedgelefteye = xcenterlefteye - eyewidth/2;
        rightedgelefteye = xcenterlefteye + eyewidth/2;
      
        leftedgerighteye = xcenterrighteye - eyewidth/2;
        rightedgerighteye = xcenterrighteye + eyewidth/2;
      
        topedgelefteye = ycenterlefteye - eyeheight/2;
        bottomedgelefteye = ycenterlefteye + eyeheight/2;
      
        topedgerighteye = ycenterrighteye - eyeheight/2;
        bottomedgerighteye = ycenterlefteye + eyeheight/2;
        
        
        //left eye
        float x1 = map(X1, 0, width, leftedgelefteye, rightedgelefteye);
        float y1 = map(Y1, 0, height, topedgelefteye, bottomedgelefteye);
        //right eye
        float x2 = map(X1, 0, width, leftedgerighteye, rightedgerighteye);
        float y2 = map(Y1, 0, height, topedgerighteye, bottomedgerighteye);
        
        ellipseMode(CENTER);
        
        //eyes
        fill(255,255,255,opac);
        ellipse(xcenterlefteye, ycenterlefteye, eyewidth, eyeheight);
        ellipse(xcenterrighteye, ycenterrighteye, eyewidth, eyeheight);
       
         
        //pupils
        fill(0,0,0,opac);
        ellipse(x1, y1, 7, 7);
        ellipse(x2, y2, 7, 7);
        
        tint(255,opac);
        image(imgobama, (width/2)-180, (height/2)-250);  
      
  }
  if(order==2){
        //john
        xcenterlefteye = 520;
        ycenterlefteye = 373;
        xcenterrighteye = 670;
        ycenterrighteye = 373;
        
        eyewidth = 50;
        eyeheight = 30;
        
        leftedgelefteye = xcenterlefteye - eyewidth/2;
        rightedgelefteye = xcenterlefteye + eyewidth/2;
      
        leftedgerighteye = xcenterrighteye - eyewidth/2;
        rightedgerighteye = xcenterrighteye + eyewidth/2;
      
        topedgelefteye = ycenterlefteye - eyeheight/2;
        bottomedgelefteye = ycenterlefteye + eyeheight/2;
      
        topedgerighteye = ycenterrighteye - eyeheight/2;
        bottomedgerighteye = ycenterlefteye + eyeheight/2;
        
        
        //left eye
        float x1 = map(X1, 0, width, leftedgelefteye, rightedgelefteye);
        float y1 = map(Y1, 0, height, topedgelefteye, bottomedgelefteye);
        //right eye
        float x2 = map(X1, 0, width, leftedgerighteye, rightedgerighteye);
        float y2 = map(Y1, 0, height, topedgerighteye, bottomedgerighteye);
        
        ellipseMode(CENTER);
        
        //eyes
        fill(255,209,189,opac);
        ellipse(xcenterlefteye, ycenterlefteye, eyewidth, eyeheight);
        ellipse(xcenterrighteye, ycenterrighteye, eyewidth, eyeheight);
       
         
        //pupils
        fill(0,0,0,opac);
        ellipse(x1, y1, 13, 13);
        ellipse(x2, y2, 13, 13);
        
        tint(255,opac);
        image(imgjohn, (width/2)-221, (height/2)-300);
  }
  if(order==3){
        //farm
  
  //eyes # 1
  xcenterlefteye = 485;
  ycenterlefteye = 276;
  xcenterrighteye = 525;
  ycenterrighteye = 276;
  
  eyewidth = 20;
  eyeheight = 9;
  
  leftedgelefteye = xcenterlefteye - eyewidth/2;
  rightedgelefteye = xcenterlefteye + eyewidth/2;

  leftedgerighteye = xcenterrighteye - eyewidth/2;
  rightedgerighteye = xcenterrighteye + eyewidth/2;

  topedgelefteye = ycenterlefteye - eyeheight/2;
  bottomedgelefteye = ycenterlefteye + eyeheight/2;

  topedgerighteye = ycenterrighteye - eyeheight/2;
  bottomedgerighteye = ycenterlefteye + eyeheight/2;
  
  
  //left eye
  float x1 = map(X1, 0, width, leftedgelefteye, rightedgelefteye);
  float y1 = map(Y1, 0, height, topedgelefteye, bottomedgelefteye);
  //right eye
  float x2 = map(X1, 0, width, leftedgerighteye, rightedgerighteye);
  float y2 = map(Y1, 0, height, topedgerighteye, bottomedgerighteye);
  
  ellipseMode(CENTER);
  
  //eyes
  fill(205,205,205,opac);
  ellipse(xcenterlefteye, ycenterlefteye, eyewidth, eyeheight);
  ellipse(xcenterrighteye, ycenterrighteye, eyewidth, eyeheight);

   
  //pupils
  fill(0,0,0,opac);
  ellipse(x1, y1, 4, 4);
  ellipse(x2, y2, 4, 4);

  //////////////////////////////////
  
  
  //eyes # 2
  xcenterlefteye2 = 730;
  ycenterlefteye2 = 210;
  xcenterrighteye2 = 785;
  ycenterrighteye2 = 210;
  
  eyewidth2 = 20;
  eyeheight2 = 10;
  
  leftedgelefteye2 = xcenterlefteye2 - eyewidth2/2;
  rightedgelefteye2 = xcenterlefteye2 + eyewidth2/2;

  leftedgerighteye2 = xcenterrighteye2 - eyewidth2/2;
  rightedgerighteye2 = xcenterrighteye2 + eyewidth2/2;

  topedgelefteye2 = ycenterlefteye2 - eyeheight2/2;
  bottomedgelefteye2 = ycenterlefteye2 + eyeheight2/2;

  topedgerighteye2 = ycenterrighteye2 - eyeheight2/2;
  bottomedgerighteye2 = ycenterlefteye2 + eyeheight2/2;
  
  
  //left eye
  float x12 = map(X12, 0, width, leftedgelefteye2, rightedgelefteye2);
  float y12 = map(Y12, 0, height, topedgelefteye2, bottomedgelefteye2);
  //right eye
  float x22 = map(X12, 0, width, leftedgerighteye2, rightedgerighteye2);
  float y22 = map(Y12, 0, height, topedgerighteye2, bottomedgerighteye2);
  
  ellipseMode(CENTER);
  
  //eyes
  fill(205,205,205,opac);
  ellipse(xcenterlefteye2, ycenterlefteye2, eyewidth2, eyeheight2);
  ellipse(xcenterrighteye2, ycenterrighteye2, eyewidth2, eyeheight2);

    //pupils
  fill(0,0,0,opac);
  ellipse(x12, y12, 4, 4);
  ellipse(x22, y22, 4, 4);

  
  tint(255,opac);
  image(imgfarm, (width/2)-301, (height/2)-360);
  
  
  }
   if(order==4){
        //gw
  xcenterlefteye = 556;
  ycenterlefteye = 332;
  xcenterrighteye = 630;
  ycenterrighteye = 333;
  
  eyewidth = 30;
  eyeheight = 15;
  
  leftedgelefteye = xcenterlefteye - eyewidth/2;
  rightedgelefteye = xcenterlefteye + eyewidth/2;

  leftedgerighteye = xcenterrighteye - eyewidth/2;
  rightedgerighteye = xcenterrighteye + eyewidth/2;

  topedgelefteye = ycenterlefteye - eyeheight/2;
  bottomedgelefteye = ycenterlefteye + eyeheight/2;

  topedgerighteye = ycenterrighteye - eyeheight/2;
  bottomedgerighteye = ycenterlefteye + eyeheight/2;
  
  
  //left eye
  float x1 = map(X1, 0, width, leftedgelefteye, rightedgelefteye);
  float y1 = map(Y1, 0, height, topedgelefteye, bottomedgelefteye);
  //right eye
  float x2 = map(X1, 0, width, leftedgerighteye, rightedgerighteye);
  float y2 = map(Y1, 0, height, topedgerighteye, bottomedgerighteye);
  
  ellipseMode(CENTER);
  
  //eyes

  fill(205,205,205,opac);
  ellipse(xcenterlefteye, ycenterlefteye, eyewidth, eyeheight);
  ellipse(xcenterrighteye, ycenterrighteye, eyewidth, eyeheight);

   
  //pupils
  fill(0,0,0,opac);
  ellipse(x1, y1, 6, 6);
  ellipse(x2, y2, 6, 6);
  
   
   
   tint(255,opac);
  image(imggw, (width/2)-302, (height/2)-250);
   }
    
    
    
    if(key=='o'){
      tint(255,125);
        image( opencv.image(), 0,0, displayWidth, displayHeight);
    }

    if ((key=='z')){
      X = false;
    }
      if ((key=='x')){
      X = true;
    }
    if (X){
      fill(255);
      noStroke();
      quad(X1-10,Y1+10,X1-7,Y1+10,X1+10,Y1-10,X1+7,Y1-10);
      quad(X1+10,Y1+10,X1+7,Y1+10,X1-10,Y1-10,X1-7,Y1-10);
      
    }
}





or link to project:
https://www.dropbox.com/s/flxhx7wlji4ofxm/face_detectionE2.pde

1 comment: