Using OpenCV face tracking to blend faces together

edited July 2014 in Library Questions

I'm writing a sketch that will take in a folder of photographs, all of which are "selfies" and blend from one face to another. Using the new OpenCV for Processing library I've got it to work in terms of lining of the X and Y for the faces, but not the scaling. Another issue is that they all stay in the same spot (by design of course) but ideally it'd look like this: http://selfiecity.net/#intro

import gab.opencv.*;
import java.awt.Rectangle;

OpenCV opencv;
Rectangle[] faces;

int i = 0;  // keep track of what image we are lookin at
int factor = 8;  // scale factor

float faceScale;

PImage faceImage;  // store full-res image of face
PImage scaleDown;  // store smaller image for faster processing

PVector lastScale;

void setup() {

  lastScale = new PVector(1,1);

  size(800, 800);

  background(0);

  newFace();
}

void draw() {
}

void newFace() {

  // load in image, scale it down
  faceImage = loadImage(i + ".jpg");
  // first init scaleDown
  scaleDown = loadImage(i + ".jpg");  // must be loaded in separately
  // reduce size by a factor of...
  scaleDown.resize(faceImage.width/factor, faceImage.height/factor);
  // grayscale might reduce lag...
  scaleDown.filter(GRAY);
  // get that face info!
  opencv = new OpenCV(this, scaleDown);
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);  
  faces = opencv.detect();

  if (faces.length > 0) {
    // the goal is to get the face into the center of the screen
    float xOff = faces[0].x*factor + faces[0].width * factor / 2;
    float x = width / 2 - xOff;
    float yOff = faces[0].y*factor + faces[0].height * factor / 2;
    float y = height / 2 - yOff;

    tint(255, 200);

    //faceImage.width = int(faceImage.width * lastScale.x);
    //faceImage.height = int(faceImage.height * lastScale.y);

    image(faceImage, x, y);

    // 
    float temp = faces[0].width*factor;
    float scaleX = temp / faceImage.width;
    temp = faces[0].height*factor;
    float scaleY = temp / faceImage.height;

    lastScale = new PVector(scaleX, scaleY);

  } else {
    i++;
    newFace();
  }

  // next face for next time
  i++;
}

void keyReleased() {
  newFace();
}

I'm not worried about rotation at this point. I'd just like to get that face in the center look, with the images landing to the sides to keep the actual tracked faces centered, like in the above project. Keeping them scaled so the faces are roughly the same size as one another is paramount in that. Ideas?

Tagged:
Sign In or Register to comment.