Understanding Hierarchy, from findContours opencv
Asked Answered
M

1

8

I am trying to understand Hierarchy and findContours, from opencv c++, but am finding it difficult.

I did go through this question here, but I still am not able to get it clearly. I tried using it in different examples, using below sample images

enter image description here

for the above image, running the following code,

    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>

    using namespace cv;
    using namespace std;

    Mat src; Mat src_gray;
    int thresh = 100;
    int max_thresh = 255;
    RNG rng(12345);

    void thresh_callback(int, void* );

    /** @function main */
    int main( int argc, char** argv )
    {
            src = imread( argv[1], 1 );
            cvtColor( src, src_gray, CV_BGR2GRAY );
            blur( src_gray, src_gray, Size(3,3) );

            String source_window = "Source";
            namedWindow( source_window, CV_WINDOW_AUTOSIZE );
            imshow( source_window, src );

            createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
            thresh_callback( 0, 0 );

            waitKey(0);
            return(0);
    }

    /** @function thresh_callback */
    void thresh_callback(int, void* )
    {
            Mat canny_output;
            vector<vector<Point> > contours;
            vector<Vec4i> hierarchy;
            int rows = 0,cols = 0;

            Canny( src_gray, canny_output, thresh, thresh*3, 3 );
            findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

            for(int i=0;i<hierarchy.size();i++)
            {
                    cout<<hierarchy[i]<<endl;

            }
    /*      for(int i =0;i<contours.size();i++)
            {
                    for(int j = 0;j<contours[i].size();j++)
                    {
                            cout<<"printing contours"<<endl;
                            cout<<contours[i][j]<<endl;
                    }
            }*/

            Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
            for( int i = 0; i< contours.size(); i++ )
            {
                    Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
                    drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
            }

            /// Show in a window
            namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
            imshow( "Contours", drawing );
    }

The output I got for the above image for Hierarchy is as follows

    [6, -1, 1, -1]
    [-1, -1, 2, 0]
    [-1, -1, 3, 1]
    [-1, -1, 4, 2]
    [-1, -1, 5, 3]
    [-1, -1, -1, 4]
    [-1, 0, -1, -1]

According to the description from here, there are 7 contours. I do not understand how this is possible, when I see only 2 in the image. An outer contour and another one inside enclosed by the other.

Secondly, What do the numbers, 6, 5, 3 denote? From reading the description, am not able to understand the underlying logic. It would be really helpful if someone can explain this.

To remove doubts, I tried with various image types. Below is another one

enter image description here

and the answer for this is

      [2, -1, 1, -1]
      [-1, -1, -1, 0]
      [-1, 0, -1, -1]

Now we have 3 contours, while actually there's only one, as visible to naked eye.

and finally, tried the worst case,

enter image description here

And the output,

    [-1, -1, 1, -1]
    [-1, -1, -1, 0]

I know I am obviously missing some logic. If someone can explain, it would be of great help.

I am trying to split the contours, based on their area, as large, medium and small, based on some threshold. I am stuck here , as I am trying to compute the area of a contour, but not able to understand it completely.

Few things I can deduce is there's possibly two contour regions drawn for every possible single contour. One the boundary and the other the hole or space inside. Is it something like that?

Still, the numbers of the hierarchy still confuse me.

Any help would be really appreciated. Thanks in advance :).

Malanie answered 15/4, 2015 at 5:46 Comment(1)
@rayryeng danke. Will check itMalanie
F
0

According to the description from here, there are 7 contours. I do not understand how this is possible, when I see only 2 in the image.

Your image has two blobs, and each of them has two contours: inner and outer. See all 4 contours below:

enter image description here

When you apply Canny edge detector, you should get 8 contours: 4 blobs with 2 contours each. Except, in your case, there is a discontinuity artifact, which reduces this number to 7. See enlarged area of this artifact here, with fragments of all 7 contours visible:

enter image description here

Fractional answered 26/3, 2022 at 6:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.