13

I'm using OpenCV to filter an image for certain colours, so I've got a binary image of the detected regions.

Now I want to erode those areas and then get rid of the smaller ones, and find the x,y coordinates of the largest 'blob'

I was looking for recommendations as to what the best library would be to use? I've seen cvBlob and cvBlobsLib but I'm not too sure how to set them up. Do I want to compile them along with the project or do I want to compile and install them to the system (like I did with OpenCV)?

I'm currently using the Code::Blocks IDE on Ubuntu (although that shouldn't restrict things)

amr
  • 1,255
  • 3
  • 15
  • 23

4 Answers4

11

I'm late to the party, but I'd just like to chime in that there is a way to do connected components in opencv, it's just not mainlined yet.

Update: It is mainlined, it's just been stuck waiting for 3.0 to release for multiple years. Linky to documentation

See http://code.opencv.org/issues/1236 and http://code.opencv.org/attachments/467/opencv-connectedcomponents.patch

Disclaimer - I'm the author.

Jason Newton
  • 1,201
  • 9
  • 13
  • 2
    Nice work Jason. I've integrated your patch and it seems to work well. Speed is good too. Maybe adding some properties function would be great too (like area, centroïd etc). Anyway, thanks for the great work. I hope the OpenCV team integrate your patch soon. This is a serious lack of OpenCV IMHO, especially since the other library are outdated and only use IplImage*... – Jean-Philippe Jodoin Jun 14 '12 at 13:53
  • Is this in the api now? if yes a link to the docs would help future readers. – dashesy Mar 02 '15 at 00:33
11

You can use findContours to do that, see the opencv manual and a Tutorial to find connected components.


Edit: Code from the tutorial (via Archive.org)

#include <stdio.h>
#include <cv.h>
#include <highgui.h>

int main(int argc, char *argv[])
{
    IplImage *img, *cc_color; /*IplImage is an image in OpenCV*/
    CvMemStorage *mem;
    CvSeq *contours, *ptr;
    img = cvLoadImage(argv[1], 0); /* loads the image from the command line */
    cc_color = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);

    cvThreshold(img, img, 150, 255, CV_THRESH_BINARY);
    mem = cvCreateMemStorage(0);
    cvFindContours(img, mem, &contours, sizeof(CvContour), CV_RETR_CCOMP,
        CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));


    for (ptr = contours; ptr != NULL; ptr = ptr->h_next) {
        CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
        cvDrawContours(cc_color, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
    }

    cvSaveImage("result.png", cc_color);
    cvReleaseImage(&img);
    cvReleaseImage(&cc_color);
    return 0;
}
etarion
  • 16,935
  • 4
  • 43
  • 66
  • This looks promising too, just looking on how to find the largest contour/blob - thanks :) – amr Jan 09 '11 at 23:07
  • I think you can calculate the area of a contour. There's some function for that. – Utkarsh Sinha Jan 10 '11 at 08:46
  • Yep, I just calculated the area of the contour's bounding box and it did the job – amr Jan 10 '11 at 14:50
  • 1
    the second link is dead and the first one also seems not responding, can you please update – dashesy Mar 02 '15 at 00:35
  • Second link is alive on Archive.org - answer could be updated https://web.archive.org/web/20110505194913/http://www.associatedcontent.com/article/2695649/connected_components_using_opencv.html – Fuhrmanator Apr 09 '16 at 18:55
10

Unfortunately OpenCV doesn't have any connected component labelling functionality, which seems like a serious omission for a computer vision library. Anyway I had a similar requirement recently so I implemented my own CCL routine - there are a couple of different algorithms described on the CCL Wikipedia page and they are both pretty simple to implement.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    This seems to be the best option, thanks :) It does seem a massive oversight on OpenCV's part, you're right. – amr Jan 09 '11 at 21:47
  • There is a third party blobs library on the OpenCV site (cvBlobsLib or similar) but I looked at it and the code quality was not great. Better to roll your own in this instance, I think. – Paul R Jan 09 '11 at 21:50
  • As mentioned in another answer, doesn't findContours give the equivalent of connected components labeling? – carnieri Jan 10 '11 at 17:49
  • @carnieri: it depends on what kind of information you are trying to collect - cvFindContours fits polygons to blobs and you can get *some* kinds of information from these polygons, but in my case I needed to know the number of connected pixels in each blob and this doesn't seem to be possible with cvFindContours. With a regular CCL algorithm though it's pretty straightforward (just histogram the label values). – Paul R Jan 10 '11 at 22:27
  • Good to know - if @amr is still around then ideally he should now mark your answer as accepted instead of my out-of-date answer. – Paul R May 08 '15 at 14:22
0

I think the best and easy option to work with blobs with OpenCV is to use cvBlob library. Its a complemntary library with OpenCV a its so easy to use.

Jorge Vega Sánchez
  • 7,430
  • 14
  • 55
  • 77