Friday, 16 April 2010

background subtraction

This is an interesting approach. The "controlip5" library is used to as a slider to adjust the level of backgroud subtraction using RGB colours. The effect is pretty good and this highlights the fact, I think, that some sort of potentiometer could possibly be used to adjust the sensitivity of the cameras exposure to picking up light in different conditions. I guess this was shown earlier with the threshold click and drag function in my first blob tracking example.

http://processing.org/discourse/yabb2/YaBB.pl?num=1257273175
/* This is the example of background substraction by golan levin;
i just messed around a little bit. after having started the sketch
press SPACE(!) to get an background image. after this the blob is
green and in x[] and y[] the edges are stored. out of those i'd
like to do my shape.*/

import processing.video.*;
import controlP5.*;
/* if you don't got the control P5 thing than delete all the stuff out
sliderValue is the treshold*/
int sliderValue = 60;

int numPixels;
int[] backgroundPixels;
Capture video;

ControlP5 controlP5;
ControlWindow controlWindow;

int num = 0;
int[] x = new int[0];
int[] y = new int[0];
boolean once = false;

void setup() {
  size(320, 240, P2D);
 
  //threshold slider
  controlP5 = new ControlP5(this);
  controlWindow = controlP5.addControlWindow("settings", 500, 100, 490, 180);
  controlWindow.setBackground(color(0));
  Slider s = controlP5.addSlider("sliderValue",0,255,60,40,120,350,20);
  s.setWindow(controlWindow);
 
  video = new Capture(this, width, height, 24);
  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();
    video.loadPixels();
    int presenceSum = 0;
   
    //j does count the lines
    int j = 0;
   
    x = new int[0];
    y = new int[0];
   
    for (int i = 0; i < numPixels; i++) {
     
      // ----background substraction as in the example by Golan Levin-------
      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);
     
      pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
      // -------------------------------------------------------------------
     
     
      //------------------starting to mess around---------------------------
      if (diffR > sliderValue || diffG > sliderValue || diffB > sliderValue){  //make the silhouette green
        pixels[i] = color(0,255,0);   
       
        if(j > 0 && (pixels[i-1] != color(0,255,0))){  //quick and dirty edge detection from black to green
        x = append(x, i-((j-1)*width));  //getting x, when pixel changes from black to green
        y = append(y, j);            //same with y
        }
      }
     
      if(j > 0 && pixels[i-1] == color(0,255,0) && pixels[i] != color(0,255,0)){    //quick and dirty edge detection from green to black
        x = append(x, i-((j-1)*width));  //getting x, when pixel changes from green to black
        y = append(y, j);            //same with y
      }
     
      if(i > width && i > j*width) j++;  //count the lines we got
    }
    updatePixels(); // Notify that the pixels[] array has changed
   
    //here is where i somehow would like to do an silhouette out of all those x and y i got
    //but curently its only rectangles
    noStroke();
    fill(255,0,0);
    //beginShape();    
    for (int i = 0; i < x.length; i++){
    rect(x[i], y[i], 10,10);
    }
    //endShape();
    noFill();
  }
}


void keyPressed() {
  if (key == ' '){
    video.loadPixels();
    arraycopy(video.pixels, backgroundPixels);
  }
  if (key == 'e') exit();
}

No comments:

Post a Comment