Quick and easy connected component (blob) using OpenCV

OpenCV is up to version 2.3.1 and it still lacks a basic connected component function for binary blob analysis. A quick Google will bring up cvBlobsLib (http://opencv.willowgarage.com/wiki/cvBlobsLib), an external lib that uses OpenCV calls. At the time when I needed such functionality I wasn’t too keen on linking to more libraries for something so basic. So instead I quickly wrote my own version using existing OpenCV calls. It uses cv:floodFill with 4 connected neighbours. Here is the code and example input image

UPDATE: 22th July 2013

I got rid of the hacks to work with OpenCV 2.3.1. It should now work with OpenCV 2.4.x.

On Linux, you can compile it using:

g++ blob.cpp -o blob -lopencv_core -lopencv_highgui -lopencv_imgproc

The results …

20 thoughts on “Quick and easy connected component (blob) using OpenCV

  1. goodevening
    i am tryig to use ur code in my projects and facing problems in the building stage …wish u can help me …that some kinds of the erros i recieve :

    error C2783: ‘_Tp &cv::Mat::at(int,int)’ : could not deduce template argument for ‘_Tp’
    1> c:\opencv-2.1.0\include\opencv\cxcore.hpp(895) : see declaration of ‘cv::Mat::at’

    error C2783: ‘const _Tp &cv::Mat::at(int,int) const’ : could not deduce template argument for ‘_Tp’
    1> c:\opencv-2.1.0\include\opencv\cxcore.hpp(897) : see declaration of ‘cv::Mat::at’

    error C2228: left of ‘.y’ must have class/struct/union
    error C3203: ‘vector’ : unspecialized class template can’t be used as a template ar
    std::vector’ : use of class template requires template argument list

  2. hi nghiaho12
    i tried to do so even before ,but with no diference…..
    may i have your e-mail or skype or any other faster way to contact you…its verry important to me to use
    your code in my project.
    thanks anyway for trying to help me

    • To solve the problem some of you are getting, you need to do do a couple of change:

      std::vector blob; —–> std::vector blob;

      if((int)label_image.at(y,x) != 1) { —-> if((int)label_image.at(y,x) != 1) {

      if((int)label_image.at(i,j) != label_count) { —-> if((int)label_image.at(i,j) != label_count) {

      This should fix your issue with the compiler unable to deduce the template argument.

  3. Hi,

    I copied latest version of cvblob from http://code.google.com/p/cvblob/

    I used cmake to build it. when I compile the code I am getting the following error

    LINK : fatal error LNK1104: cannot open file ‘..\lib\Debug\cvblob.lib’

    There is no library file in the path. Please let me know how to resolve the error.

    Thanks

    Mahesh

  4. Is there a way to compile this under Linux?
    It looks like I can only compile pure C code… I am getting this errors when trying to compile:

    test01.c:26: error: type/value mismatch at argument 1 in template parameter list for ‘template class std::vector’
    test01.c:26: error: expected a type, got ‘vector’
    test01.c:26: error: template argument 2 is invalid
    test01.c:26: error: invalid type in declaration before ‘;’ token
    test01.c:30: error: ‘FindBlobs’ was not declared in this scope

    am I doing something wrong or it only works on Windows?

    • Due to some annoying HTML issues messing up with the displaying of the code, I’ve posted it up for download. Should have done that from the beginning!

  5. Hi,

    I have one image showing different smaller objects of irregular sizes. By using blob detection codes provided by you, I can able to get the labelled image clearly but I couldn’t obtain total counting of those smaller labelled objects in numbers.

    Can you guide me in this matter?

    Thank You

    • The function returns std::vector < std::vector > &blobs. To find the size of a blob do

      blobs[i].size(), for the i-th blob.

      • I beg your pardon but my doubt is to “Count Total Number of Labelled Blobs” of the image in numbers like I should get total numbers of blobs as 30 or 40 or more.

        Is determining size of blobs suggested by you solve this problem?

        Please guide me again as this task is very important for me to understand and implement it completely.

        Thank You

        • I’m a bit unclear what you’re asking. The function returns std::vector < std::vector > &blobs, which allows you to do:

          cout << “Total blobs found: ” << blobs.size() << endl;

          for(size_t i=0; i < blob.size(); i++)
          cout << “Blob ” << i << ” size is: ” << blob[i].size() << endl;

          Is this what you are looking for?

  6. Pingback: opencv blob or connected components | Lost Ferry

  7. It works pretty well. I”m trying to extract largest blob and output it in a new window. Do you have any idea how to do it?
    blob.size() vs. blobs[i].size() ?? I’m confused because I just couldn’t understand or picture vectors…vector conceived in another vector.

    • in terms of vectors… where is the start of blob point and where is the end of it? blobs[i][j] or is it a blob vector inside blobs[i][j] cell?

    • Think of it as a 2D array. The first index loops through the blob, the second index loops through the blob’s co-ordinates.

      For your task do

      size_t max_pixels = 0;
      size_t max_at = 0;

      for(size_t i=0; i < blobs.size(); i++) {
      if(blobs[i].size() > max_pixels) {
      max_pixels = blobs[i].size();
      max_at = i;
      }
      }

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>