Skip to content

Instantly share code, notes, and snippets.

@ronniej2014
Created November 10, 2014 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ronniej2014/da218fc57bb9b3d8c470 to your computer and use it in GitHub Desktop.
Save ronniej2014/da218fc57bb9b3d8c470 to your computer and use it in GitHub Desktop.
//Based on openCV resourse code "gesture_baseFile2a_motionPixels", by: Daniel Shiffman
//Based on Processing resourse code "Water Simulation", by: Rodrigo Amaya
import processing.video.*;
Capture video; //variable for capture device
PImage prevFrame; //previous Frame of captured camera video
PImage refImg; //import a static image
int imgAlpha = 0; //define the initial alpha value of image
float threshold = 80; //set the value of motion threshold
float avgMotion; //average motion according to screen
float bigWave = 12; // set the value of average motion
int frameDelay = 1; //set delay for detecting frame
int savedTime1; //reocrd millis for frameDelay
int refImgDelay = 7000; //a delay for img appearance
int savedTime2; //record millis for refImgDelay
boolean inRecovery = false; //judge the condition of img statment
boolean overMaxMotion = false; //img appear if it's true
//=======define variable for creating ripples=======
int size;
int hwidth, hheight;
int riprad;
int ripplemap[];
int ripple[];
int texture[];
int oldind, newind, mapind;
int i, a, b;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void setup()
{
size(960, 560); //screen size
savedTime1 = millis(); //set timer
savedTime2 = millis(); //set timer
//==========setting for video capture===================
video = new Capture(this, 960, 560);
video.start();
prevFrame = createImage(video.width, video.height, RGB);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
refImg = loadImage("reflect.png"); //link to img
//==========setting for ripple effect===================
riprad=3; //test with 3
size = width * (height+2) * 2;
ripplemap = new int[size];
ripple = new int[width*height];
texture = new int[width*height];
oldind = width;
newind = width * (height+3);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
//=========New frame available from camera============
void captureEvent(Capture video)
{
// Save previous frame for motion detection!!
prevFrame.copy(video, 0, 0, video.width, video.height, 0, 0, video.width, video.height);
prevFrame.updatePixels();
video.read();
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void draw()
{
background(255); //background color
tint(255, 255); //video tint
image(video, 0, 0); //load video to screen
tint(255, imgAlpha); //img tint
image(refImg, 0, 0, width, height); //load img to screen
//============setting for ripple effect==============
loadPixels();
texture = pixels;
newframe();
for (int i = 0; i < pixels.length; i++)
{
pixels[i] = ripple[i];
}
updatePixels();
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============detect pixels of camera video============
video.loadPixels();
prevFrame.loadPixels();
// Begin loop to walk through every pixel
// Start with a total of 0
float totalMotion = 0;
// Sum the brightness of each pixel
for (int x = 0; x < video.width; x++ )
{
for (int y = 0; y < video.height; y++)
{
int loc = x + y * video.width;
// Step 2, what is the current color
color current = video.pixels[loc];
// Step 3, what is the previous color
color previous = prevFrame.pixels[loc];
// Step 4, compare colors (previous vs. current)
float r1 = red(current);
float g1 = green(current);
float b1 = blue(current);
float r2 = red(previous);
float g2 = green(previous);
float b2 = blue(previous);
// Motion for an individual pixel is the difference between the previous color and current color.
float diff = dist(r1, g1, b1, r2, g2, b2);
// totalMotion is the sum of all color differences.
if (diff >= threshold)
{
totalMotion += diff;
// 1 frame delay to display ripples
int passedTime1 = millis() - savedTime1;
if (passedTime1 > frameDelay)
{
disturb(x, y);
savedTime1 = millis();
}
}
}
}
// averageMotion is total motion divided by the number of pixels analyzed
avgMotion = totalMotion / video.pixels.length;
//println(avgMotion);
//img appears if avgMotion higher than setting
if (avgMotion > bigWave && inRecovery != true)
{
overMaxMotion = true;
}
if (overMaxMotion == true && inRecovery != true)
{
imgAlpha += 75; //img appear
if (imgAlpha > 255)
{
inRecovery = true;
overMaxMotion = false;
savedTime2 = millis(); //timer for the delay of img disappear
}
}
if (inRecovery == true)
{
int passedTime2 = millis() - savedTime2;
if (passedTime2 > refImgDelay)
{
imgAlpha -= 75; //img disappear
if (imgAlpha < 0)
{
inRecovery = false;
}
}
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
//==============setting for ripple effect================
public void disturb(int dx, int dy)
{
for (int j=dy-riprad; j<dy+riprad; j++)
{
for (int k=dx-riprad; k<dx+riprad; k++)
{
if (j>=0 && j<height && k>=0 && k<width)
{
ripplemap[oldind+(j*width)+k] += 128; //test with 512
}
}
}
}
void newframe()
{
//Toggle maps each frame
i=oldind;
oldind=newind;
newind=i;
i=0;
mapind=oldind;
for (int y=0; y<height; y++)
{
for (int x=0; x<width; x++)
{
short data = (short)((ripplemap[mapind-width]+ripplemap[mapind+width]+ripplemap[mapind-1]+ripplemap[mapind+1])>>1);
data -= ripplemap[newind+i];
data -= data >> 5;
ripplemap[newind+i]=data;
//where data=0 then still, where data>0 then wave
data = (short)(1024-data);
//offsets
a=((x-hwidth)*data/1024)+hwidth;
b=((y-hheight)*data/1024)+hheight;
//bounds check
if (a>=width) a=width-1;
if (a<0) a=0;
if (b>=height) b=height-1;
if (b<0) b=0;
ripple[i]=texture[a+(b*width)];
mapind++;
i++;
}
}
}
void mouseMoved()
{
disturb(mouseX, mouseY);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment