Tutorials‎ > ‎

2 Counting the blobs

                                                                                   Abstract
In this tutorial I will show how to use Blobscanner and Processing to count the blobs in a monochrome image, what are the basic rules to use correctly the library methods for this task and also I will try to provide a very basic understanding on how Blobscanner detects blobs.


 
Assuming the code from this tutorial as starting point for this new one....

import blobscanner.*;

Detector bs;
PImage img;
int threshold = 255;

void setup() {


img = loadImage("blobs.jpg");

size(img.width, img.height);

bs = new Detector( this, threshold );

}
 
void draw() {

bs.imageFindBlobs(img);

}

Assuming we apply the code to this monochrome .jpg image 

 
changing the draw() methods to this :

void draw() {

image(img, 0, 0);//display the image

bs.imageFindBlobs(img);//computes the blobs
 
int blobnumber = bs.getBlobsNumber();//assign the number of blobs found to a variable

println(blobnumber);//print the number of blobs found

noLoop()//we don't need a loop but we will use this framework for clarity sake


}

If we run the program something strange happens: the number of blobs printed to the console it's far bigger than what we expected (90 on my  machine). The image on the screen, to our eyes obviously, has four well distinct white blobs on a black background.To understand what it's really going on, let zooming in the image a little:


as you can now see, the profile of the blobs is not made by pixels with the same intensity level. At this point, once we know how Blobscanner performs blob detection, it will be easy to understand why we get a number of blobs so high.

How Blobscanner performs blob detection


In this line of the program

bs = new Detector( this, threshold );

where  threshold = 255, we ask the library to find each blob with a pixel's brightness value equals to 255.

Blobscanner finds all the pixels in the image with a brightness value equals to 255, assigning to those connected between them( connected component ) an equal ID and counting for each group of pixels with the same ID a new blob.
To better understand why the code above returns so many blobs, we must see for a moment with the library eyes. That's very easy:
we only have to put on the screen the pixels with a brightness value of 255. To see this image, change the code to this :

import blobscanner.*;

Detector bs;
PImage img = loadImage("blobs.jpg");
int threshold = 255;

void setup() {


size(img.width, img.height);

bs = new Detector( this, threshold );

}
 
void draw() {

//Fills the screen buffer with the  same
//pixel data that the library will detect.
grab_white();

loadPixels();

//We don't have an image object to read data from
//but only the screen buffer. Thus this method is used
//instead of imageFindBlobs.
bs.findBlobs(pixels, width, height);

updatePixels();

int blobnumber = bs.getBlobsNumber();

println(blobnumber);
noLoop();
 

}

//This method measures the brightness of each pixel
//in the image, setting the corresponding screen's pixel to
//white (255) if the brightness of the pixel
measured is
//equals to 255 and to black if it's different.
That's also
//what happens behind the scene in the library
.

void grab_white(){
    //for each pixel in the image
  for(int x = 0; x < img.width; x++){
    for(int y = 0; y < img.height; y++){

    //if the brightness of a pixel is equal to 255, set the
    //the corresponding screen's pixels to white                  

    if(brightness(img.get( x, y))==255) set( x, y, color(255)) ;

       //else set it to black
    else set(x, y, color(0));
    }
  }
}


 


The image above on the left is the image that the threshold() method draws to the screen when the last code it's ran, and that is the image as it is perceived by the library. On the right in contrast, the image as we see it. The blob detection algorithm is applied to all the white pixels ( threshold = 255 ) in the image on the left.
The following image shows a zoom on the blob's profile in the left image:



we can clearly see a cluster of blobs and segments of white pixels. Until this point we know at least that the library is working correctly, and that it's detecting the right number of blobs with a brightness value of 255. But this is not enough for us because, if we wanted the library to simulate human vision, the result would be wrong. Also, even if we were using the library in a visual aesthetic context, for example to detect the human body movement for controlling some kind of fancy visual effect, the blobs number would be so high to crash our application.

How to solve the problem

There are few methods to reduce the number of blobs detected by the library;
in our case and in the majority of the cases concerning computer vision, it's impossible to achieve a result without first recurring to another field of image science, and that is image processing, which indeed it is as important as the computer vision technique itself. In our specific case,  all we have to do it is to apply a "threshold" filter to the original image before is processed by the blob detector. So doing, undesired blobs will be merged in to an unique blob, and the four shapes in it will be preserved for further analysis.

The Processing language provides us with some basic image processing and image transformation tools, like the filter(..)  method. Try rewriting the code this way:

import blobscanner.*;

Detector bs;
PImage img;
int threshold = 255;

void setup() {


img = loadImage("blobs.jpg")

size(img.width, img.height);

bs = new Detector( this, threshold );

}
 
void draw() {

image(img, 0, 0);

img.filter(THRESHOLD); //<-processing the image before sending it to the library


bs.imageFindBlobs(img);

int blobnumber = bs.getBlobsNumber();

println(blobnumber);

noLoop();

}

Now the output of the console will be 4. The following image is the profile of a blob in the image which is sent to the library with last version of the code, after the threshold filter is applied:



In this way, with a simple image processing filter, we have enhanced the main features of the input image, simplified the job of the library, reduced its workload and reached our desired( and a correct )final result. 
        
Conclusions

From Wikipedia :
" Before a computer vision method can be applied to image data in order to extract some specific piece of information, it is usually necessary to process the data in order to assure that it satisfies certain assumptions implied by the method."

Processing the image before to apply a blob detection algorithm to it, it's important as the algorithm itself. Choosing  the right operators( filters ) and the right sequence it's fundamental to reach a good result. Some times the image processing it's part of the CV algorithm itself, some times we can choose the operator to use and when  applying it to the image itself, nevertheless we can usually never decide to do without it.      
 
 


                                                    
The content of this website is available under GPL v3 license.
                                
                                              
                                                        
Antonio Molinaro © 2014 

Comments