Motion Animation - Greg Parsons


Midterm Project

Motivation
I was interested in the demonstrations of computer vision presented during the first week of lecture. Using the in class sampling of the technologies I was impressed by how I was able to manipulate a project using frame differencing. I would like to create a project that is manipulated by movements from the viewer of the project.
Interaction
The interaction of the project will be enacted with a webcam, recording movement in a scene and manipulating a graphical image based on the data collected from the difference in frames. In total the project would react to the viewers movements in some way.
Function
My programming experience is limited to the past two quarters of instruction. But I would like to be able to achieve smooth movement in the image using some form of algorithmic processing.
Visualization
I have a semi-working project that I created this weekend using a visual example from OpenProcessing.org that I will show in class if needed.



Code for Demo:

Copy this into a new processing project to test.

 * Greg Parsons VIS145B Midterm Test
 *  
 * Project Uses Frame Differencing to detect motion, sees it and draws a picture
 * 
 */


//videocapture
import processing.video.*;
float x, y;
int numPixels;
int[] previousFrame;
int[] diffFrame;
Capture video;

//treecursion
float curlx = 0; 
float curly = 0; 
float f = sqrt(2)/2.; 
float deley = 20; 
float growth = 0; 
float growthTarget = 0; 


int movementDiff = constrain(10, 5, 15);
int movementDiffNegative = constrain(10, -5, -10);

void setup() {
  //video capture
  size(640, 480, P2D); //P2D from treecursion
  video = new Capture(this, width, height, 24);
  numPixels = video.width * video.height;
  previousFrame = new int[numPixels];
  diffFrame = new int[numPixels];
  loadPixels();
  smooth();
  //treecursion
  addMouseWheelListener(new java.awt.event.MouseWheelListener() {  
    public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) {  
      mouseWheel(evt.getWheelRotation()); 
    }
  }
  );
}

void draw() {



  //video capture
  if (video.available()) {


    // When using video to manipulate the screen, use video.available() and
    // video.read() inside the draw() method so that it's safe to draw to the screen
    video.read(); // Read the new frame from the camera
    video.loadPixels(); // Make its pixels[] array available

    int movementSum = 0; // Amount of movement in the frame
    for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
      color currColor = video.pixels[i];
      color prevColor = previousFrame[i];
      // Extract the red, green, and blue components from current pixel
      int currR = (currColor >> 16) & 0xFF; // Like red(), but faster
      int currG = (currColor >> 8) & 0xFF;
      int currB = currColor & 0xFF;
      // Extract red, green, and blue components from previous pixel
      int prevR = (prevColor >> 16) & 0xFF;
      int prevG = (prevColor >> 8) & 0xFF;
      int prevB = prevColor & 0xFF;
      // Compute the difference of the red, green, and blue values
      int diffR = abs(currR - prevR);
      int diffG = abs(currG - prevG);
      int diffB = abs(currB - prevB);
      // Add these differences to the running tally
      movementSum += diffR + diffG + diffB;
      // Render the difference image to the screen
      //diffFrame = color(diffR, diffG, diffB);
      diffFrame[i] = round(sqrt(diffR*diffR + diffG*diffG + diffB*diffB));
      //     pixels[i] = currColor;
      // pixels[i] = color(diffFrame[i]);
      // The following line is much faster, but more confusing to read
      //pixels[i] = 0xff000000 | (diffR << 16) | (diffG << 8) | diffB;
      // Save the current color into the 'previous' buffer
      previousFrame[i] = currColor;
    }
    // To prevent flicker from frames that are all black (no movement),
    // only update the screen if the image has changed.
    if (movementSum > 0) {
      updatePixels();
      //   println(movementSum); // Print the total amount of movement to the console
    }
  }

  int v = round(x+y*width);
  if (diffFrame[v] > 5)
  {
    

    if ((diffFrame[v] > 5) && (diffFrame[v] < 15))
    {
      movementDiff = movementDiff + 3;
    }
    else if ((diffFrame[v] > 15) && (diffFrame[v] < 50))
    {
      movementDiff = movementDiff - 3;
    }    

    movementDiffNegative = (movementDiff * -1);
    
    System.out.println("the movement diff is" + movementDiff + "the movementDiffNegative is" + movementDiffNegative);
    //treecursion
    background(250); 
    stroke(0); 
    curlx += (radians(360./height*movementDiff)-curlx)/deley; 
    curly += (radians(360./height*movementDiffNegative)-curly)/deley; 
    translate(width/2,height/3*2); 
    line(0,0,0,height/2); 
    branch(height/4.,17); 
    growth += (growthTarget/10-growth+1.)/deley; 
    println(diffFrame[v]);
  } 

}

void mouseWheel(int delta) 
{ 
  growthTarget += delta; 
} 

//treecursion 
void branch(float len,int num) 
{ 
  len *= f; 
  num -= 1; 
  if((len > 1) && (num > 0)) 
  { 
    pushMatrix(); 
    rotate(curlx); 
    line(0,0,0,-len); 
    translate(0,-len); 
    branch(len,num); 
    popMatrix(); 

    //    pushMatrix(); 
    //    line(0,0,0,-len); 
    //    translate(0,-len); 
    //    branch(len); 
    //    popMatrix(); 
    len *= growth; 
    pushMatrix(); 
    rotate(curlx-curly); 
    line(0,0,0,-len); 
    translate(0,-len); 
    branch(len,num); 
    popMatrix(); 
    //len /= growth; 
  } 
}