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 & HelpSyntax Questions › store x number in an array
Page Index Toggle Pages: 1
store x number in an array (Read 906 times)
store x number in an array
Apr 21st, 2009, 3:32am
 
Hi, I want to store the x number in the lineBlob 2d-array.

Every line in the image has his own lineBlob array, they y is used for that one. Now I want to store the x number when the color is white,
they array should look like this:

lineBlob[0][0] = 6;
               [1] = 7;
lineBlob[1][0] = 7;
               [1] = 8;        
               [2] = 14;  

I was thinking maybe it's better to use
int[][] lineBlob = new int[36][50];

instand of \/ and expand everytime
int[][] lineBlob = new int[36][];

anyway, how do I store the x number?

...

Code:
PImage img;

int count = 0; //counts pixels to get pixels[#]
int blobCounter = 0;
int[][] lineBlob = new int[36][];//36, één voor elke lijn

void setup() {
size(640, 480);
img = loadImage("test.png");
noLoop();
}


void draw() {

img.filter(THRESHOLD, 0.82);//overbodig als het goed is
image(img, 0, 0, 500, 360);
for (int y = 0; y < img.height; y ++){//
for (int x = 0; x < img.width; x ++){ //
if (red(img.pixels[count]) == 255.0){
lineBlob[y] = x;

//println("blob");

}
count ++;
}
}
println("count "+count);
}
Re: store x number in an array
Reply #1 - Apr 21st, 2009, 3:45am
 
I got it to work but is it a good way?

Code:
PImage img;

int count = 0; //counts pixels to get pixels[#]
int blobCounter = 0;
int[][] lineBlob = new int[36][50];//36, één voor elke lijn //50 voor breedte vreet mischien wel ram zo?

void setup() {
size(640, 480);
img = loadImage("test.png");
noLoop();
}


void draw() {

img.filter(THRESHOLD, 0.82);//overbodig als het goed is
image(img, 0, 0, 500, 360);
for (int y = 0; y < img.height; y ++){//
int c = 0;
for (int x = 0; x < img.width; x ++){ //
if (red(img.pixels[count]) == 255.0){

lineBlob[y][c] = x;
println("lineBlob["+y+"]["+c+"] "+lineBlob[y][c]);
c ++;

//println("blob");

}

count ++;

}
}
println("count "+count);
}
Re: store x number in an array
Reply #2 - Apr 21st, 2009, 6:53am
 
In Java a 2D array is an array of arrays so
int[][] lineBlob = new int[36][];
will cause a NullPointerException because it is an array of null pointers.

Although the code works fine I do have a couple of suggestions, first is that if we use a different size image we can get an ArrayIndexOutOfBoundsException, so the array should be  created after we have loaded the image.

This would give an array where the number of elements = number of pixels.

Consider a situation where in image row 15 the first pixel only is white  the rest being something else and in row 16 none of the pixels is white. There is no difference between lineBlob[15] and lineBlob[16] all the values would be 0

Two solutions either have an array of arraylists or keep track of the number of'x' valies are in each lineBlob.

The following code takes the second approach.
Code:


PImage img;
int count = 0; //counts pixels to get pixels[#]
int blobCounter = 0;
int[][] lineBlob;
int [] lineBlobCount;

void setup() {  
 size(640, 480);  
 img = loadImage("test.png");
 lineBlob = new int[img.height][img.width];
 lineBlobCount = new int[img.height];
 noLoop();
}

void draw() {  
 img.filter(THRESHOLD, 0.82);//overbodig als het goed is  
 image(img, 0, 0, img.width, img.height);
 count = 0; // need to reset once you get rid of noloop()
 int colToFind = color(255,255,255); // rgb
 for (int y = 0; y < img.height; y ++){//    
   int c = 0;    
   for (int x = 0; x < img.width; x ++){ //
     if (img.pixels[count] == colToFind){
       lineBlob[y][c] = x;
       println("lineBlob["+y+"]["+c+"] "+lineBlob[y][c] + "  " + count);
       c ++;  
     }
     count ++;    
   } // end of for x
   lineBlobCount[y] = c;  
   if(lineBlobCount[y] > 0)
     println("Matched " + lineBlobCount[y] + " on row " + y);
 } // end of for y
 println("count "+count);
}

Re: store x number in an array
Reply #3 - Apr 23rd, 2009, 12:20pm
 
quark, thx for your help, I've tried to go on with it but I started again from scratch goes I came into certain problems.
Now I'm stuck here:

I got the code to work but I changed the image where the white is reaching the right edge and now I got an arrayIndexOutOfBounds exeption on this line:

     if (img.pixels[count] == colToFind){ //pixel is white

here is the image I use now:
...

someone now how to fix?

Code:
PImage img;

int[][] lineBlob;

int lbCount = 0;//lineblob count
int ID = 0;

void setup() {  
 size(640, 480);  
 img = loadImage("test.png");

 lineBlob = new int[img.height][4];//meer dan nodig...

 noLoop();
}

void draw() {  

 img.filter(THRESHOLD, 0.82);  
 image(img, 0, 0, 500, 360);

 int count = 0; // created here for once the noLoop will get out

 int colToFind = color(255,255,255); // rgb

 //Pass 1
 for (int y = 0; y < img.height; y ++){//    
   //int c = 0;    
   for (int x = 0; x < img.width; x ++){ //
   
if (img.pixels[count] == colToFind){ //pixel is white
 //binnen hier doorlopen tot einde van lineblob!

 lineBlob[lbCount][1] = y; //stores y row
 lineBlob[lbCount][2] = x; //stores startPoint
 //println("startPoint is "+x);
 
 int maxX = img.width;
 //println("for(int countX = ("+x+"+1); countX < "+maxX+"; countX ++){");
 
 for(int countX = (x+1); countX < maxX; countX ++){
   count ++;
   
   if (img.pixels[count] == colToFind){
//it belongs to the current lineBlob and next pixels should be checked

   }
   else { //end lineBlob
   
lineBlob[lbCount][3] = (countX-1); //stores endPoint
println("endPoint is "+(countX-1));
//check here for ID with min and max??

x = countX; //updates original x from second for loop in Pass 1
break;
   }
 }

 //ID
 //y-co
 //startPoint
 //endPoint  
}
count ++;    
   } // end of for x
 } // end of for y
 println("count "+count); //should be 1800
}

Re: store x number in an array
Reply #4 - Apr 24th, 2009, 12:46pm
 
Your code for finding the end of the lineBlob is very complicated and I found it difficult to follow. Also it is not recommended in a for loop to change the value of the control variable (in this case'x'). To avoid this I have changed the inner loop (x) to a while statement.

I also had to alter the size of the lineBlob array to make sure it was large enough for the worst case scenario. This meant that it was big enough to hold 900 lineBlobs. I also changed the [4] to [3] to save memory. Now -
lineBlob[?][0] = y
lineBlob[?][1] = x first pixel in the blob
lineBlob[?][2] = x last pixel in the blob

I have tested the code with your image and it worked fine.

The maximum number of lineBlobs that can be in an image is half the number of pixels. Your image had 1800 pixels so I had to create an array of size 900. The image only had 41 lineBlobs! To avoid this wastage and to simplify future developments e.g. rectBlobs I suggest a LineBlob class to hold the three values (y,xs,xe) and an ArrayList to hold the LineBlob.

I don't know what programming experience you have but if you are interested I can easily modify the code to include these features.

Code:

PImage img;

int[][] lineBlob;
int lbCount = 0;//lineblob count

int ID = 0;

void setup() {  
 size(640, 480);  
 img = loadImage("test.png");

 println(img.width + " X " + img.height);
 println(img.pixels.length);

 // If we have a chessboard of allternate black/white pixels then there
 // can be upto height * width / 2 lineBobs
 lineBlob = new int[img.height * img.width / 2][3];

 noLoop();
}

void makeLineBlobs(PImage img, int col){
 int x = 0, y = 0, xs;
 int count = 0;
 lbCount = 0;

 for(y = 0; y < img.height; y++){
   x = 0;
   while(x < img.width){
     if(img.pixels[count] == col){
       lineBlob[lbCount][0] = y; //stores y row
       lineBlob[lbCount][1] = x; //stores startPoint
       xs = x + 1;
       x++;
       count++;
       while(xs < img.width && img.pixels[count] == col){
         xs++;
         x++;
         count++;
       }
       lineBlob[lbCount][2] = x-1; //stores last pixel in lineBlob
       lbCount++;
     }
     else {
       x++;
       count++;
     }
   }// end x while
 }//end y for
 println("Found " + lbCount + " lineBlobs");
}

void showLineBlobs(int col){
 stroke(col);
 for(int i = 0; i < lbCount ; i++){
   line(lineBlob[i][1], lineBlob[i][0],lineBlob[i][2],lineBlob[i][0]);
 }
}

void draw() {  
 img.filter(THRESHOLD, 0.82);  
 image(img, 0, 0); // show image 1:1 scale
 makeLineBlobs(img, color(255,255,255));
 showLineBlobs(color(255,0,0));
}

Re: store x number in an array
Reply #5 - Apr 25th, 2009, 10:55am
 
your the man!

I gtg in a few minutes so I will take a deeper look tommorow.

Quote:
I don't know what programming experience you have but if you are interested I can easily modify the code to include these features.


My experience are litle with actionscript (I'm better at processing..) and my processing experience is a few weeks so let's say almost no experience.
I would like to try first myself for the purpose of learning but I will keep the offer in mind.
Re: store x number in an array
Reply #6 - Apr 26th, 2009, 10:13am
 
As requested I include the code to detect and store irregular shaped areas of pixels of a particular colour. The image below shows the results of my testing.
...

The image on the left is the starting image and the one on the right shows the 7 blobs detected each in a different colour.

To detect irregular shaped blobs the code had to be more complex than that for simple rectangles, there is nothing I can do about that.

I suggest that you spend sometime studying and experimenting with the code.

The main class is Blob which has some useful methods that you could use in your own program for instance
nbrPixels returns how many pixels make up the Blob
contains(x,y) detects whether the position x,y is actually part of the Blob.

The methods showBlobs and listBlobs show how you can iterate through the ArrayList of Blobs.

Hope you find this useful.

Code:

PImage img;

// This will hold all the blobs
ArrayList blobs = new ArrayList();

public void setup() {  
 size(640, 480);  
 img = loadImage("test.png");

 noLoop();
}

public void draw() {  
 img.filter(THRESHOLD, 0.82f);  
 image(img, 0, 0); // show image 1:1 scale
 detectBlobs(img, color(255,255,255));
 showBlobs();
 listBlobs();
}

// This is the main method for detecting blob shapes
void detectBlobs(PImage img, int col){
 int x = 0, y = 0;
 int count = 0;
 LineBlob lb;

 for(y = 0; y < img.height; y++){
   x = 0;
   while(x < img.width){
     if(img.pixels[count] == col){
       lb = new LineBlob();
       lb.y = y; //stores y row
       lb.sx = x; //stores startPoint
       x++;
       count++;
       while(x < img.width && img.pixels[count] == col){
         x++;
         count++;
       }
       lb.ex = x-1; //stores startPoint
       addToAndMergeBlobs(lb);
     }
     else {
       x++;
       count++;
     }
   }// end x while
 }//end y for
}

// Do not call this method directly
void addToAndMergeBlobs(LineBlob lb){
 ArrayList blobsToMergeWith = new ArrayList();
 for(int i = 0; i < blobs.size(); i++){
   Blob b = ((Blob)blobs.get(i));
   if(b.canMergeLineBlob(lb))
     blobsToMergeWith.add(b);
 }
 if(blobsToMergeWith.size() == 0){
   blobs.add(new Blob(lb));
 }
 else {
   Blob b0 = ((Blob)blobsToMergeWith.get(0));
   b0.mergeLineBlob(lb);
   for(int i = 1; i < blobsToMergeWith.size(); i++){
     Blob bmerge = ((Blob)blobsToMergeWith.get(i));
     b0.mergeBlob(bmerge);
     blobs.remove(bmerge);
   }
 }
}

public void showBlobs() {
 int showCol = color(255,0,0);
 for(int i = 0; i < blobs.size(); i++){
   showCol = color(128 + random(128), 128 + random(128), 128 + random(128));
   ((Blob)blobs.get(i)).showBlob(showCol);
 }
}

public void listBlobs() {
 Blob b;
 println("Detected "+ blobs.size() + " blobs");
 for(int i = 0; i < blobs.size(); i++){
   b = ((Blob)blobs.get(i));
   println("  Blob "+ i + "\t has " + b.nbrPixels() + " pixels");
 }

}

// This class represents a continuous area of a particular colour
class Blob {
 ArrayList lineBlobs = new ArrayList();

 public Blob(LineBlob lb){
   lineBlobs.add(lb);
 }

 // Sees whether the position x,y is part of the blob
 // by seeing if it
 public boolean contains(int x, int y){
   boolean result = false;
   for(int i = 0; i < lineBlobs.size(); i++){
     if(((LineBlob)lineBlobs.get(i)).contains(x, y)){
       result = true;
     }
   }
   return result;
 }

 // Sees whether a lineblob is adjacent to this blob but does
 // NOT merge them
 public boolean canMergeLineBlob(LineBlob lb){
   boolean result = false;
   for(int i = 0; i < lineBlobs.size(); i++){
     if(((LineBlob)lineBlobs.get(i)).hasVertOverlap(lb)){
       result = true;
     }
   }
   return result;
 }

 // This merges a LineBlob to this Blob
 public void mergeLineBlob(LineBlob lb){
   lineBlobs.add(lb);
 }

 public void mergeBlob(Blob b){
   lineBlobs.addAll(b.lineBlobs);
 }

 public void showBlob(int showCol){
   stroke(showCol);
   for(int i = 0; i < lineBlobs.size() ; i++){
     ((LineBlob)lineBlobs.get(i)).showLineBlob(showCol);
   }
 }

 public int nbrPixels(){
   int n = 0;
   for(int i = 0; i < lineBlobs.size(); i++)
     n += ((LineBlob)lineBlobs.get(i)).nbrPixels();
   return n;
 }
}

// Supporting class to Blob
class LineBlob {
 public int y;
 public int sx;
 public int ex;

 public LineBlob() {
 }

 public LineBlob(int y, int sx, int ex) {
   super();
   this.y = y;
   this.sx = sx;
   this.ex = ex;
 }

 public boolean contains(int px, int py){
   if(py == y && px >= sx && px <= ex)
     return true;
   else
     return false;
 }

 public boolean hasVertOverlap(LineBlob b){
   if(Math.abs(b.y - y) == 1) {
     if( (b.sx >= sx && b.sx <= ex) || (sx >= b.sx && sx <= b.ex) ){
       return true;
     }
   }
   return false;
 }

 public void showLineBlob(int showCol){
   line(sx,y,ex,y);
 }

 public int nbrPixels(){
   return ex - sx + 1;
 }
}

Page Index Toggle Pages: 1