5

I am trying to use findcontours() function in OpenCV on the image below.

findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cvPoint(0,0) );

When I do this query: contours.size() it returns 18, so that seems 2 contour for each circle. The circles are as you can see 1-pixel thick, how is it 2 contours? Is it one for outer and one for inner, if so, how can I force this function to detect just one contour for each circle? I thought a contour was defined as a connected sequence of pixels, 1 pixel thick.

Says there are 18 contours!!

dr_rk
  • 4,395
  • 13
  • 48
  • 74

2 Answers2

4

I can't confirm this, but i think the algorithm used by this function does something equivalent to computing the gradient for each function. Which means that there will be a contour found on the outer edge and one on the inner edge, just like you suggested. To confirm this, You can try to use an input image where the circles have been filled with white (elimininating the inner contour)

you can also test with different parameters on the findContours function

For example, try using CV_RETR_EXTERNAL instead of CV_RETR_TREE I assume the inner circle is nested within the outer one, so this should force it to return only the outer ones

Naps62
  • 960
  • 6
  • 17
  • But when I look at this example [here](http://jmpelletier.com/a-simple-opencv-tutorial/) it seems it is not counting the inner and outer separately. But the example there is the C version of the findcontours. Is there a difference between the old and the new implementations? – dr_rk Jul 03 '12 at 00:06
  • no, there shouldn't be any differences between the C and the C++ version that would influence the final result. In fact from what i remember, one is just a wrapper for the other. However, looking at the images from that link, i see the exact opposite of what you said. it seems to be detecting both the inner and outer contour for each circle, which makes even more sense on the image shown there – Naps62 Jul 03 '12 at 01:04
  • 1
    Indeed, using the CV_RETR_EXTERNAL flag should fix it for you. See here for a complete list of flags: http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset) – Steve Heim Jul 03 '12 at 07:25
  • But the problem with CV_RETR_EXTERNAL is that it doesn't create the hierarchical tree for you, which is what I really need for this application. I need to know which contours are enclosed inside which ones. In this example shown above all are contours without any holes. – dr_rk Jul 03 '12 at 13:00
0

You might've already figured this out but...

findContours only concerns about white objects and so recognizes each of hollowed circle as a band, thus produces two contours.

Best way is to create another image with filled circles and to apply findContoours for that image. It will give you what you want.

Tae-Sung Shin
  • 20,215
  • 33
  • 138
  • 240