We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › multiblob detector
Page Index Toggle Pages: 1
multiblob detector (Read 644 times)
multiblob detector
Jun 21st, 2008, 3:27am
 
hello
implementing a multiblob detector, but not working very well. this code works well in c, but perhaps something is buggy in this java version. someone can assist? many thanks, a

code:/**
multiblob detector, andré sier, xpanded from
processing example video capture

To initialize the background, press a key.
*/

import processing.opengl.*;
import processing.video.*;

int numPixels;
int[] backgroundPixels;
Capture video;

int videores = 256;
int videothresh = 10; // thresh for binary image

PImage videotexbin = new PImage(videores,videores);
PImage videotexgray = new PImage(videores,videores);
ImageBlobs blobs = new ImageBlobs();

void setup() {
 size(1024, 480, OPENGL);//OPENGL);
 frameRate(25);
 video = new Capture(this, videores, videores, 15);
 numPixels = video.width * video.height;
 backgroundPixels = new int[numPixels];
}


Re: multiblob detector
Reply #1 - Jun 21st, 2008, 3:29am
 
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];

     int currG = (currColor >> 8) & 0xFF;
           
     int bkgdG = (bkgdColor >> 8) & 0xFF;
 
     int diffG = abs(currG - bkgdG);

     presenceSum +=  diffG ;

     int binarize = (diffG > videothresh) ? 255 : 0;
     videotexbin.pixels[i] = 0xFF000000 | (binarize << 16) | (binarize << 8) | binarize;
     videotexgray.pixels[i] = 0xFF000000 | (diffG << 16) | (diffG << 8) | diffG;
     
   }
   println("presence "+presenceSum); // Print out the total amount of movement

   videotexbin.updatePixels(); ///notify videotex pixels changed
   videotexgray.updatePixels(); ///notify videotex pixels changed


     ///////CALC BLOBS
     
     blobs.calc(videotexbin);
     blobs.query();


   // render textures
   float dimx = 160;//320;
   float dimy = 120;//240;


  // render textures gray
   
  pushMatrix();
  translate(170, 300, 0);

    beginShape();
   texture(videotexgray);
   vertex(-dimx,-dimy,0.,   0, 0);
// vertex(180,20, feed1size,0);
   vertex(dimx,-dimy,0.,   videores,0);
   vertex(dimx,dimy,0.,    videores,videores);
   vertex(-dimx,dimy,0.,   0,videores);
   endShape();
 
   popMatrix();

 // render textures bin
   
  pushMatrix();
  translate(500, 300, 0);

    beginShape();
   texture(videotexbin);
   vertex(-dimx,-dimy,0.,   0, 0);
// vertex(180,20, feed1size,0);
   vertex(dimx,-dimy,0.,   videores,0);
   vertex(dimx,dimy,0.,    videores,videores);
   vertex(-dimx,dimy,0.,   0,videores);
   endShape();
 
   popMatrix();



 }
}

Re: multiblob detector
Reply #2 - Jun 21st, 2008, 3:31am
 
void keyPressed() {
 video.loadPixels();
 arraycopy(video.pixels, backgroundPixels);
}

class ImageBlobs{
  int numblobs;
  int ninpix; //min num pix for a blob
  ArrayList theblobs=null;
  ArrayList thecoords=null;
 
  ImageBlobs() { ///constructor
    theblobs = new ArrayList();
    thecoords = new ArrayList();
    numblobs=0;
    ninpix=100;
  }

  void setninpix(int nin){
   ninpix=nin;
  }

  void calc(PImage frame){////excpects binary image

    // calc takes a frame as PImage and estimates the blobs
    int min0 = 0x7FFFFFFF;
    int min1 = 0x7FFFFFFF;
    int max0 = 0; int max1 = 0;
    boolean inrange0,inrange1;
    pt2  p=new pt2();
    pt2  p2=new pt2();  
    int pixelcount=0;  
    ABlob  b=new ABlob();

    ///always reset arraylists
    theblobs = new ArrayList();
    thecoords = new ArrayList();

    numblobs=0; //reset count per frame at begin
    int numpix = frame.width * frame.height; //num pix
    int[] imagemap = new int[numpix]; //and array
   
//     for(int i=0;i<numpix;i++)  imagemap[i] = 0;    
    /// java pass
    frame.loadPixels();//make pix avail
   

Re: multiblob detector
Reply #3 - Jun 21st, 2008, 3:31am
 
    for (int j=0; j<frame.height; j++){
      inrange1=false;
      for (int i=0; i<frame.width; i++){
        inrange0=true;
        int pixval = ( frame.pixels[j*frame.width+i] ) & 0xFF;
        if( pixval <= 0 || pixval >= 256){
          inrange0=false;// print(".");
        }
        if( inrange0 == true ) { //if lit pixel
          inrange1=true;
          if(i<min0)
            min0=i;
          else if(i>max0)
            max0=i;
          //if is not painted
  if(imagemap[j*frame.width+i]==0) { //this is a new pixel in a blob, iterate thru it(blob)
             //add this first pixel
             p.x = i;
             p.y = j;
             thecoords.add(p);
             //zero pix count
             pixelcount=1;
             // put blobminmax params
             b.boxminx=i;b.boxmaxx=i;
             b.boxminy=j;b.boxmaxy=j;
             
             while  ( thecoords.size() > 0) {
               p2 = (pt2) thecoords.get(0); ///pop!
               thecoords.remove(0);
               ///first check inside imageframe
               if(p2.x > 0 && p2.x < frame.width && p2.y > 0 && p2.y < frame.height) {
               /// check imagemap
                 if( imagemap[p2.y*frame.width+p2.x]==0  ) {
                   ///post("map not seen, checking val");
                   
                   pixval = ( frame.pixels[p2.y*frame.width+p2.x] )  & 0xFF ;
                   if (pixval > 0) {
                     imagemap[p2.y*frame.width+p2.x]=1; //mark posit
                     pixelcount++;
                   //   print(".");
                     ////add cornerns to linkedlist ; floodfill points
                     p.x = p2.x;
                     p.y = p2.y+1;
                     thecoords.add(p);
                     p.x = p2.x;
                     p.y = p2.y-1;
                     thecoords.add(p);
                     p.x = p2.x+1;
                     p.y = p2.y;
                     thecoords.add(p);
                     p.x = p2.x-1;
                     p.y = p2.y;
                     thecoords.add(p);
                     //boxcalc for blob
                     if(p2.x < b.boxminx)
                       b.boxminx = p2.x;
                     if(p2.x > b.boxmaxx)
                       b.boxmaxx = p2.x;
                     if(p2.y < b.boxminy)
                       b.boxminy = p2.y;
                     if(p2.y > b.boxmaxy)
                       b.boxmaxy = p2.y;
                   
                   }
                   
                   
                 }
                 
               }
               
               
             } //end whilecoords
             
             
             ///check valid blob
             
             if (pixelcount > 5){//ninpix) {
               ////this one is valid, store blob info
               b.id = numblobs;
               b.pixelcount = pixelcount;
               //boxcalcs already set, just center
               b.boxcenterx = (int)((b.boxminx + b.boxmaxx) * 0.5);
               b.boxcentery = (int)((b.boxminy + b.boxmaxy) * 0.5);
               
               theblobs.add(b);// = new ArrayList();
               
               numblobs++;
               println("found blob "+numblobs);
             }
             
             
           
           }
         
        }

       
      }
    }
   

  } //end calc

Re: multiblob detector
Reply #4 - Jun 21st, 2008, 3:32am
 
  void query(){
    println("query blobdata");
    println("numblobs "+numblobs);
    for(int i=0; i < theblobs.size(); i++) {
      ABlob b = (ABlob) theblobs.get(i);
      println("blob"+b.id+" pix"+b.pixelcount+
      " coords "+b.boxminx+" "+b.boxminy+" "+b.boxmaxx+" "+b.boxmaxy+"  center "+b.boxcenterx+" "+b.boxcentery);
    }    
  }
 
 
 
 
 
} //end class



class pt2{
int x; int y;
}

class ABlob {
 int id;
 int pixelcount;
 int boxminx,boxminy,boxmaxx,boxmaxy;
 int boxcenterx,boxcentery;
 ABlob(){  /// constructor    
 }
 
}


sorry for the lenghy post, this was very hard to post all this code here..
many thanks for any hints
Re: multiblob detector
Reply #5 - Jun 24th, 2008, 1:42am
 
i tracked this down to unexpected behaviour of ArrayList...
adding different points results in the same last point all over the list.

here is some simple example code. does anyone know if this is normal behaviour? i think i never had this sort of problems on arraylists, must be some obvious misuse??

code:

///test arraylist add

ArrayList test = new ArrayList();

class pt2{
int x;  int y;
}

pt2  pt = new pt2();
pt2  p2 = new pt2();


println("test size "+test.size());

   p2.x = (int) random(100);
   p2.y = (int) random(100);

println(" p2 "+p2.x+" "+p2.y);

   test.add(p2);

   pt.x = p2.x;
   pt.y = p2.y + 1;
     println(" pt1 "+pt.x+" "+pt.y);
  test.add(pt);
 
  pt.x = p2.x;
  pt.y = p2.y - 1;
    println(" pt2 "+pt.x+" "+pt.y);
  test.add(pt);

  pt.x = p2.x + 1;
  pt.y = p2.y;
     println(" pt3 "+pt.x+" "+pt.y);
  test.add(pt);

  pt.x = p2.x - 1;
  pt.y = p2.y;
    println(" pt4 "+pt.x+" "+pt.y);
  test.add(pt);
                     
  println("test size "+test.size());

  //list contents
  println("\nlistcontents");
  for(int i=0;i<test.size();i++) {
     pt = (pt2) test.get(i);
     println("arraylist"+i+" "+pt.x+" "+pt.y);
  }
                     
                     
Re: multiblob detector
Reply #6 - Jun 24th, 2008, 7:08am
 
I haven't tested your code, so I don't know what is the "unexpected behavior".
But I can guess you want different points in the ArrayList and get identical points instead...
You keep adding the same object, but what you add isn't really the objects, but reference to them. So as soon as you update the object, all the items in the list are updated!
What you want is to call "pt2 pt = new pt2()" (better with a constructor setting x and y) before each add(). Thus you create a fresh new point to add to the list, with new coordinates.
Re: multiblob detector
Reply #7 - Jun 24th, 2008, 11:33am
 
thanks. that's it.
Re: multiblob detector
Reply #8 - Jun 25th, 2008, 1:21am
 
hehe, got this working so faaaasssst, the collision still sucks, but it's nice to keep a tally balance going. check out a simple game made with a simple multiblob detector here: http://www.s373.net/x/all_applet. if any sugestions welcome, thanks & enjoy

a
Page Index Toggle Pages: 1