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 …

71 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.



  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;

  8. Hello,
    I am wiling to use your code for a project concerning object detection and recognition.
    “Blob.cpp” does exactly what I need but unfortunately I can’t get it to work… I am stuck with this error:

    OpenCV Error: Unsupported format or combination of formats () in cvFloodFill, file /build/buildd/opencv-2.3.1/modules/imgproc/src/floodfill.cpp, line 1046
    terminate called after throwing an instance of ‘cv::Exception’
    what(): /build/buildd/opencv-2.3.1/modules/imgproc/src/floodfill.cpp:1046: error: (-210) in function cvFloodFill

    I know that this means that cv::FloodFill doesn’t get the parameters he wants (the right type) but I can’t find which parameters is wrong (I didn’t change anything to your code)…

    Can you give me a hint?
    Thank you in advance!

  9. Thank you. Your code works great. It is annoying that OpenCV does not have ConnectedComponent function, even though the OpenCv2.4.9 has the doccument for it.

  10. Hi, I just used your code, with a couple of changes to make it fit in my app, and it works very well. Now I’m trying to understand it, what is this line for: “int *row = (int*)label_image.ptr(y);” and this one: “int *row2 = (int*)label_image.ptr(i);”.


  11. Hi,

    Your routine is awesome! I can successfully get a set of blobs that are 4-way connected. To reduce noise in an binary image. I also need to run a second pass at an 8-way connection to do a solidity analysis. By modifying the flood-fill parameter (to 8) it doesn’t seem to produce correct results. Is there something else I’m missing…


    • There’s very little difference between the 4 and 8 in theory. The 8 is able to connect two blobs joined on the diagonal by a single pixel, where as the 4 can’t. That’s like the edge casse. Every other situation they both should produce more or less the same results.

      • Can you point in the right direction in modifying your function to be able to do a 8 way or a 4 way? I thought it would be as simple as changing the floodfill parameter from 4 to 8… I’ve read the wiki page on Connected-component_labeling … but it is a bit over my head.

          • The difference I’m seeing is in the Blob Size. I thought I’d see a reduction in the number of blobs because a couple would “merge” together based, instead it merges more blobs together than expected….

  12. i replace CV_32UC1 with CV_8U … because i have the same error –> (Kateline)

    the image result is black (i used your image blob.png)

    i have the opencv2.4.9

    Please help me :’(
    Thank you in advance!

  13. Thank you for your code. It works well. After component labeling, I would like to apply the Harris coner detector to the pixel blobs for EACH labeled component SEPERATELY. Could you should me how to do that? Thanks!

  14. Hey its a really nice code.

    may I ask how can I find only blobs bigger than X,Y size in this piece code ? because on my image I get a lot of labels.

    • You can find the bounding box by looping over the pixels inside the array

      vector> blobs

      blobs[0] <– loop over this vector and find the min/max (x,y)
      do the same for the blobs[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>