Particles on webcam pixels (and phone cam)

Hi there. Based on the frame differencing Processing example, how can I include particle systems to represent the pixels on the webcam? I mean, how can I represent the webcam’s movement through particles?

Thanks.

1 Like

Hi. Nice video. I’m going to work on this also.
Here is the code.
http://www.dayofthenewdan.com/ParticleVideo.zip

1 Like

Hello. Thanks for sharing! I would also appreciate your help

@joana
Since I do not have a PC, I adapted the code to be able to work with the android Ketai library. I still not have the quality of the original video. In the video below I am waving a golden brush in front of my phone camara, but it is barely noticeable. I will tweak a bit to see what happens. Please post your result also.

``````/**
ParticleVideo by Dan Bridges 2011
Check out Daniel Shiffman's tutorials on
particle systems here:
http://www.shiffman.net/teaching/nature/particles/
As you can see some of this code is built upon
those tutorials.
*/

import ketai.camera.*;
KetaiCamera cam;

PImage prevFrame;
float threshold = 50;
int videoWidth;
int videoHeight;
int reduction;
ParticleSystem system;

void setup() {
size(320, 240);
system = new ParticleSystem(30000);
frameRate(30);
reduction = 1;
videoWidth = width/reduction;
videoHeight = height/reduction;
cam = new KetaiCamera(this, 320, 240, 20);
cam.start();
prevFrame = createImage(cam.width, cam.height, RGB);
}

void onCameraPreviewEvent() {
prevFrame.copy(cam, 0, 0, cam.width, cam.height, 0, 0, cam.width, cam.height);
prevFrame.updatePixels();
}

void draw() {
// image(cam, 0, 0);
background(255,200);
for (int x=0; x< videoWidth; x+=3) {
for (int y = 0; y < videoHeight; y+=4) {
if (abs((cam.pixels[y* videoWidth +x] >> 16 & 0xFF)-(prevFrame.pixels[y* videoWidth +x] >> 16 & 0xFF)) < 75
&& abs((cam.pixels[y* videoWidth +x] >> 8 & 0xFF)-(prevFrame.pixels[y* videoWidth +x] >> 8 & 0xFF)) < 75
&& abs((cam.pixels[y* videoWidth +x] & 0xFF)-(prevFrame.pixels[y* videoWidth +x] & 0xFF)) < 75) {
} else {
for (int i=0; i<2; i++) {
system.addParticle(( videoWidth - x - 1)*reduction, y*reduction, random(-100, 100), random(-320, 0), 1);
}
}
}
}
system.update(1/frameRate, cam);
fill(0);
}

public class ParticleSystem {
private ArrayList <Particle> particles;
private int iterations;
private int maxSize;

ParticleSystem(int maxSize) {
this.particles = new ArrayList<Particle>(maxSize);
this.iterations = 1;
this.maxSize = maxSize;
}

void update(float dt, KetaiCamera cam ) {
for (int j = particles.size()-1; j >= 0; j--) {
Particle particle = particles.get(j);
particle.update(dt);
if (particle.position.x > 0 && particle.position.x < width &&
particle.position.y > 0 && particle.position.y < height) {
particle.render(cam.pixels[floor(particle.position.y/reduction)*videoWidth+(videoWidth-floor(particle.position.x/reduction)-1)]);
}
if (particle.shouldDestroy()) {
particles.remove(j);
}
}
}

void addParticle(float x, float y, float mass) {
}

void addParticle(float x, float y, float dx, float dy, float mass) {
if (size() < maxSize) {
particles.add(new Particle(x, y, dx, dy, mass));
}
}

int size() {
return particles.size();
}
}

public class Particle {
private PVector position;
private PVector velocity;
private PVector force;
private float mass;
private boolean fixed;
private float diameter;
private float time;
private float maxTime;

Particle(float x, float y, float mass) {
this(x, y, 0.0, 0.0, mass);
}

Particle(float x, float y, float dx, float dy, float mass) {
this.position = new PVector(x, y);
this.velocity = new PVector(dx, dy);
this.force = new PVector(0, 0);
this.mass = mass;
this.fixed = false;
this.diameter = random(1, 10);
this.time = 0;
this.maxTime = random(3, 7);
}

void update(float dt) {
time += dt;
if (!fixed){
//Gravity
//force.div(mass); take this out for simplicity, don't need it for free fall
}
//Zero forces
force.mult(0);
}

void render(color c) {
int transparency = floor((time/maxTime)*255);
ellipseMode(CENTER);
fill(blendColor(c, color(255, 255, 255, transparency), BLEND));
noStroke();
ellipse(position.x, position.y, diameter, diameter);
}

boolean shouldDestroy() {
//destroy if off screen
if (position.x > width ||
position.x < 0 ||
position.y > height) {
return true;
}

//destroy if time is up
if (time > maxTime) {
return true;
}

return false;
}
}
``````
1 Like