the problem is, that this only works for a very limited number of frames, since the n last frames must be stored.
but you can also accumulate frames, by "mixing" them ( see example).
this technique is often used for renderers, that need to accumulate/average thousand of render-passes, e.g. pathtracing.
the result is the same as if you would sum up the frames, and divide the sum by the number of frames.
float[][] av_frames; // for computing the average
PGraphics av_result; // for displaying the average
float rx = 0, rx_vel = 0; // rotation, rotation speed
int rect_col = color(255,0,0); // drawing color
public void setup() {
size(800, 600, JAVA2D);
av_frames = new float[width*height][3];
av_result = createGraphics(width, height, JAVA2D);
}
public void draw(){
// change color on mousePressed
if( mousePressed ){
rect_col = color(random(155,255), random(155,255), random(155,255));
}
// draw to main graphics buffer
background(0);
pushMatrix();
{
rx_vel += dist(mouseX, mouseY, pmouseX, pmouseY)/5000f;
rx_vel /= 1.01f;
rx += rx_vel;
translate(mouseX, mouseY);
rotate(rx);
fill(rect_col);
stroke(255);
strokeWeight(4);
rectMode(CENTER);
rect(0, 0, width/2, 100);
}
popMatrix();
// COMPUTE AVERAGE
PGraphics pg = this.g; // pg could also be the webcam frame
updateAverage(pg, frameCount);
// press any key, to display the averaged frames
if( keyPressed ){
updateImage();
image(av_result,0,0);
}
frame.setTitle("averaged frames: "+frameCount);
}
void updateAverage(PGraphics pg, int counter){
pg.loadPixels();
float weight = counter/(counter+1f);
float[] rgb = new float[3];
for(int i = 0; i < pg.pixels.length; i++){
// normalize rgb [0,1]
rgb[0] = ((pg.pixels[i]>>16)&0xFF)/255f;
rgb[1] = ((pg.pixels[i]>> 8)&0xFF)/255f;
rgb[2] = ((pg.pixels[i] )&0xFF)/255f;
// mix rgb
mixRGB(av_frames[i], rgb, weight);
}
}
void updateImage(){
av_result.loadPixels();
{
for(int i = 0; i < av_result.pixels.length; i++){
// rgb [0,1] -> [0,255]
int r = (int)(av_frames[i][0]*255);
int g = (int)(av_frames[i][1]*255);
int b = (int)(av_frames[i][2]*255);
// compose color
av_result.pixels[i] = 0xFF000000 | r << 16 | g << 8 | b;
}
}
av_result.updatePixels();
}
void mixRGB(float[] a, float[] b, float weight){
a[0] = mix(a[0], b[0], weight);
a[1] = mix(a[1], b[1], weight);
a[2] = mix(a[2], b[2], weight);
}
float mix(float a, float b, float weight){
return a*weight + b*(1-weight);
}