Processing Video Example -- Background Subtraction

Hi all – I’ve been playing around with the BackgroundSubtraction example by Golan Levin in the Processing Video examples and have gotten comfortable with manipulating most aspects of the code in relationship to the image displayed, but there is a more technical part that I’m hoping someone can provide insight on. Currently, when a key is pressed, the image at time of pressing is stored and displayed; however, when you press a key again, that previous image is erased and then the new current image is stored and displayed. I’m wondering if it’s possible to keep storing and displaying every time the key is pressed, eg. if I press a key ten times, then there should be ten images stored and displayed… is this possible? And, then is it possible to press a key to erase all stored images?

G. Levin’s code:

/**
 * Background Subtraction 
 * by Golan Levin. 
 *
 * Detect the presence of people and objects in the frame using a simple
 * background-subtraction technique. To initialize the background, press a key.
 */


import processing.video.*;

int numPixels;
int[] backgroundPixels;
Capture video;

void setup() {
  fullScreen(); 
  
  // This the default video input, see the GettingStartedCapture 
  // example if it creates an error
  //video = new Capture(this, 160, 120);
  video = new Capture(this, width, height);
  
  // Start capturing the images from the camera
  video.start();  
  
  numPixels = video.width * video.height;
  // Create array to store the background image
  backgroundPixels = new int[numPixels];
  // Make the pixels[] array available for direct manipulation
  loadPixels();
}

void draw() {
  if (video.available()) {
    video.read(); // Read a new video frame
    video.loadPixels(); // Make the pixels of video available
    // Difference between the current frame and the stored background
    int presenceSum = 0;
    for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
      // Fetch the current color in that location, and also the color
      // of the background in that spot
      color currColor = video.pixels[i];
      color bkgdColor = backgroundPixels[i];
      // Extract the red, green, and blue components of the current pixel's color
      int currR = (currColor >> 16) & 0xFF;
      int currG = (currColor >> 8) & 0xFF;
      int currB = currColor & 0xFF;
      // Extract the red, green, and blue components of the background pixel's color
      int bkgdR = (bkgdColor >> 16) & 0xFF;
      int bkgdG = (bkgdColor >> 8) & 0xFF;
      int bkgdB = bkgdColor & 0xFF;
      // Compute the difference of the red, green, and blue values
      int diffR = abs(currR - bkgdR);
      int diffG = abs(currG - bkgdG);
      int diffB = abs(currB - bkgdB);
      // Add these differences to the running tally
      presenceSum += diffR + diffG + diffB;
      // Render the difference image to the screen
      //pixels[i] = color(diffR, diffG, diffB);
      // The following line does the same thing much faster, but is more technical
      pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
    }
    updatePixels(); // Notify that the pixels[] array has changed
    println(presenceSum); // Print out the total amount of movement
  }
}

// When a key is pressed, capture the background image into the backgroundPixels
// buffer, by copying each of the current frame's pixels into it.
void keyPressed() {
  video.loadPixels();
  arrayCopy(video.pixels, backgroundPixels);
}

Hi,

Yes, currently in the code pixels are stored as a 1 dimensional array of pixels but if you want to store multiple images you can use a 2 dimensional array for that :

// For example an array of 10 images
int[][] backgroundImages = new int[10][numPixels];

If you want to store an arbitrary number of images, you can take a look at ArrayList for a dynamic array (in the last example we had to specify 10 at first) and PImage to store pixels in an object oriented way.

How do you want to display ten images at a time?

Thank you @josephh - that worked for me!

1 Like