We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Smoothing output of Frame Differencing (Read 1606 times)
Smoothing output of Frame Differencing
Apr 23rd, 2010, 12:11am
 
I am using the basic frame differencing example to work on manipulating a moving drawing. Basically I want the project to react when there is movement on the screen.

Currently everything works but the values that the differencing algorithm is spitting out vary too much to provide smooth movement of the image.

I am using an example from open processing while I try to get the project to work, it is called Advanced Tree Generator by James Noeckel.

If you run the code the output in the console is the data I am using to manipulate the tree movement, in the example (which can be seen on open processing) the mouse was providing a smooth moving int value to adjust the tree's position. The webcam version is providing jumpy movement.

I am not a java expert, but I would think there is something to buffer the output based on a min and max value, and the outputs place in that range, like for instance if the min and max is 1 and 340 if the value is first 22, then 340 it would move in the direction of 340, 22, 23, 24 etc until the value changes.

Is this impossible? Does it require a complex algorithm?

here is the code of the project:

Code:

/**
*
*
* 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;



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)
{


//treecursion
background(250);
stroke(0);
curlx += (radians(360./height*diffFrame[v])-curlx)/deley;
curly -= (radians(360./height*diffFrame[v])-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;
}
}



Thanks in advance.

-Greg
Re: Smoothing output of Frame Differencing
Reply #1 - Apr 23rd, 2010, 11:16am
 
Maybe instead someone knows of a better way to do this?

I just want the presence of a person to manipulate the image.

-G
Re: Smoothing output of Frame Differencing
Reply #2 - Apr 23rd, 2010, 1:33pm
 
Worked on it some more, here is the new code, it is smoother, but it is not constraining the values that determine the curl on the tree.

What gives?

Code:

/**
*
*
* 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;
}
}



Page Index Toggle Pages: 1