/* Motion Visualization
Erland Sanborn
4/25/04

www.uweb.ucsb.edu/~erland/camera_motion_0
www.uweb.ucsb.edu/~erland/camera_motion_1
www.uweb.ucsb.edu/~erland/camera_motion_2
www.uweb.ucsb.edu/~erland/camera_motion_3

You must have a video device connected to your machine for this to work. Program may crash!
*/

boolean newFrame = false;
BImage pre_frame;
int count = 0;
int threshold = 50; // motion sensitivity -- use arrows to 'tune'
int _scale = 5; // scales the size of each pixel
int _alpha = 25; // percentage


void setup()
{
size(640, 480);
background(255);
imageMode(CENTER_DIAMETER);
noStroke();

// begin reading at a 4:3 ratio (relative to window height)
beginVideo(height*4/(3*_scale), height/_scale, 10);

// create an empty image buffer to store old frames
pre_frame = new BImage(height*4/(3*_scale), height/_scale);
}

// called when video updates
void videoEvent()
{ newFrame = true; }

// "Tune" variables and output setup
void keyPressed() {
if ( key == UP ) threshold++;
else if ( key == DOWN ) threshold--;
else if ( key == LEFT ) _alpha--;
else if ( key == RIGHT) _alpha++;
else if ( key == '=' ) shift++;
else if ( key == '-' ) shift--;

if ( threshold < 0 )
threshold += 255;
else if ( threshold > 255 )
threshold -= 255;

println("Threshold: " + threshold + "\tAlpha: " + _alpha + "\tHue Shift: " +
shift);
}


void loop()
{
if(newFrame) {

// store current frame
BImage cur_frame = video.get(0,0,video.width, video.height);
for ( int y = 0; y < cur_frame.height; y++ ) {
for ( int x = 0; x < cur_frame.width; x++ ) {
if ( pre_frame != null ) {

int cur_bright = (int) brightness(cur_frame.get(x,y)),
pre_bright = (int) brightness(pre_frame.get(x,y)),
dif_bright = abs( cur_bright - pre_bright);

// get brightness difference between each pixel in cur_frame and pre_frame
// if below the threshold, fill white - the actual difference (light grey)
// otherwise, fill black/dark grey (also based on actual difference)
if ( dif_bright <= threshold )
dif_bright = 255 - (abs(dif_bright-threshold));
else
dif_bright = (abs(dif_bright-threshold));

// pseudo-random color scheme based on bright values
fill(dif_bright,cur_bright,pre_bright);
/* could also use something like:
fill(dif_bright, _alpha);
for transparency and slight video delay.
*/


rect(x*width/cur_frame.width,y*height/cur_frame.height,width/cur_frame.width,height/cur_frame.height);
}
}
}
pre_frame = cur_frame; // store cur_frame for next iteration
}
}
}