Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get separate contours (and fill them) in OpenCV?

Tags:

c

opencv

I'm trying to separate the contours of an image (in order to find uniform regions) so I applied cvCanny and then cvFindContours, then I use the following code to draw 1 contour each time I press a key:

for( ; contours2 != 0; contours2 = contours2->h_next ){
        cvSet(img6, cvScalar(0,0,0));
        CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
        cvDrawContours(img6, contours2, color, cvScalarAll(255), 100);
        //cvFillConvexPoly(img6,(CvPoint *)contours2,sizeof (contours2),color);
        area=cvContourArea(contours2);
        cvShowImage("3",img6);
        printf(" %d", area);
        cvWaitKey();
    }

But in the first iteration it draws ALL the contours, in the second it draws ALL but one, the third draws all but two, and so on.

And if I use the cvFillConvexPoly function it fills most of the screen (although as I wrote this I realized a convex polygon won't work for me, I need to fill just the insideof the contour)

So, how can I take just 1 contour on each iteration of the for, instead of all the remaining contours?

Thanks.

like image 212
Gerardo Galarza Avatar asked Apr 14 '13 02:04

Gerardo Galarza


1 Answers

You need to change the last parameter you are passing to the function, which is currently 100, to either 0 or a negative value, depending on whether you want to draw the children.

According to the documentation (http://opencv.willowgarage.com/documentation/drawing_functions.html#drawcontours), the function has the following signature:

void cvDrawContours(CvArr *img, CvSeq* contour, CvScalar external_color,
CvScalar hole_color, int max_level, int thickness=1, int lineType=8)

From the same docs, max_level has the following purpose (most applicable part is in bold):

max_level – Maximal level for drawn contours. If 0, only contour is drawn. If 1, the contour and all contours following it on the same level are drawn. If 2, all contours following and all contours one level below the contours are drawn, and so forth. If the value is negative, the function does not draw the contours following after contour but draws the child contours of contour up to the $|\texttt{max_ level}|-1$ level.

Edit:

To fill the contour, use a negative value for the thickness parameter:

thickness – Thickness of lines the contours are drawn with. If it is negative (For example, =CV_FILLED), the contour interiors are drawn.

like image 173
maditya Avatar answered Sep 19 '22 14:09

maditya