Ripple effect with web cam.
in
Core Library Questions
•
6 months ago
Hi everyone, I'm trying to use this code to apply a ripple effect to the video from a webcam. The code creates a ripple when you drag your mouse across the processing window. I want to make it so a single ripple appears in a random location (as if a single drop of water fell) when a motion sensor detects motion. Does anyone know how to do this? Or can you at least tell me how to change it so a ripple appears just when you click your mouse instead of drag it?
Thank you in advance for your help!
/**
Thank you in advance for your help!
/**
* Frame Differencing
* by Golan Levin.
*
* Quantify the amount of movement in the video frame using frame-differencing.
*/
Ripple ripple;
import processing.video.*;
int numPixels;
int[] previousFrame;
Capture video;
void setup() {
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
// Uses the default video input, see the reference if this causes an error
video = new Capture(this, width, height, 24);
numPixels = video.width * video.height;
// Create an array to store the previously captured frame
previousFrame = new int[numPixels];
ripple = new Ripple();
frameRate(60);
//loadPixels();
}
void draw() {
int x = int(random(video.width));
int y = int(random(video.height));
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
loadPixels();
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...
for (int i = 0; i < width * height; i++) {
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
pixels[i] = ripple.col[i] ;
// pixels[i] = ripple.col[i] + (RGB);
// 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();
ripple.newframe();
println(movementSum); // Print the total amount of movement to the console
}
}
}
class Ripple {
int i, a, b;
int oldind, newind, mapind;
short ripplemap[]; // the height map
int col[]; // the actual pixels
int riprad;
int rwidth, rheight;
int ttexture[];
int ssize;
Ripple() {
// constructor
riprad = 3;
rwidth = width >> 1;
rheight = height >> 1;
ssize = width * (height + 2) * 2;
ripplemap = new short[ssize];
col = new int[width * height];
ttexture = new int[width * height];
oldind = width;
newind = width * (height + 3);
}
void newframe() {
// update the height map and the image
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;
if (x == 0 || y == 0) // avoid the wraparound effect
ripplemap[newind + i] = 0;
else
ripplemap[newind + i] = data;
// where data = 0 then still, where data > 0 then wave
data = (short)(1024 - data);
// offsets
a = ((x - rwidth) * data / 1024) + rwidth;
b = ((y - rheight) * data / 1024) + rheight;
//bounds check
if (a >= width)
a = width - 1;
if (a < 0)
a = 0;
if (b >= height)
b = height-1;
if (b < 0)
b=0;
col[i] = video.pixels[a + (b * width)];
// col[i] = color(diffR,diffG,diffB);
mapind++;
i++;
}
}
}
}
void mouseDragged() {
for (int j = mouseY - ripple.riprad; j < mouseY + ripple.riprad; j++) {
for (int k = mouseX - ripple.riprad; k < mouseX + ripple.riprad; k++) {
if (j >= 0 && j < height && k>= 0 && k < width) {
ripple.ripplemap[ripple.oldind + (j * width) + k] += 512;
}
}
}
}
1