opencv / opencv

Open Source Computer Vision Library
https://opencv.org
Apache License 2.0
78.94k stars 55.8k forks source link

findContours documentation does not state how to find the first contour #6635

Open kaba2 opened 8 years ago

kaba2 commented 8 years ago

When using the CV_RETR_TREE mode to retrieve the whole hierarchy of the contours in findContours(), the documentation is missing information on how to find the first contour from which the links are to be followed. The first contour could be 0, but without documentation I cannot be sure. Because of this, I have to do a linear scan to make sure I will find all of the 0-level contours.

Alexendar commented 8 years ago

There is no explanation how this function works excepts the link to 404 book containing the explanation. Do you have anything else besides OpenCV documentation to understand how findContours work?

kaba2 commented 8 years ago

Here is the documentation I was referring to.

Alexendar commented 8 years ago

The function retrieves contours from the binary image using the algorithm [Suzuki85].

We would have to see how this Suzuki85 works to know the fix to your issue. Unfortunately, from what I searched, the book explaining the algorithm is nowhere to be found online.

kaba2 commented 8 years ago

I tried through my university, but unfortunately we do not have access to that paper. I did some googling, and found it elsewhere.

Download the source code (400MB:() from here. I believe the paper is in tpf-robotica/trunk/Vision/papers/SA-CVGIP.PDF. I've been having trouble downloading this package though.

kaba2 commented 8 years ago

I believe that the detailed workings of the algorithm is irrelevant. Somewhere in that function there is the place where the "linked-lists" of contours are created, and maybe there the first contour of the first level can be tracked without overhead. Let's see if I can study the code myself...

kaba2 commented 8 years ago

The code is here. Starting from line 1635, there is the internal cvFindContours() function. This function outputs firstContour, which is the contour that I am interested in.

This function is called by the user-function cv::findContours() on line 1719:

cvFindContours(&_cimage, storage, &_ccontours, sizeof(CvContour), mode, method, offset);

The first contour is stored in _ccontours. Unfortunately, cv::findContours() does not return this information. I believe the fix is as follows:

// Line 1716
int firstIndex;
// Line 1732
if (c == _ccontours)
{
     firstIndex = i;
}

After that, firstIndex needs to be returned, so perhaps a new output-variable needs to be introduced.

Would this work?

There is also the possibility that firstIndex is always zero, but that would need to be checked from the code. As a preliminary test, I computed contours for about 13000 different images. For all of these images, it holds that the 0-index contour is the "root" of the contour-tree.

LorenaGdL commented 8 years ago

Take a look at the Python tutorial about contour hierarchy: http://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html#gsc.tab=0