About contours of the blob,area of blob's hole and contours hierarchy

asked 2013-06-17 05:05:16 -0600

wuling gravatar image

updated 2013-06-17 05:15:06 -0600

Hi all, this is test image.

image description

I have some qestion here:

1.in opencv doucument:"hierarchy – Optional output vector, containing information about the image topology. It has as many elements as the number of contours. For each i-th contour contours[i] , the elements hierarchy[i][0] , hiearchy[i][1] , hiearchy[i][2] , and hiearchy[i][3] are set to 0-based indices in contours of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative." The hiearchy which i define in code is right or not? If it's wrong, how to correct??

2.I check of orginal the area of the blob's hole should be equal the area of invert the orginal image in some place. But in fact, in this code , i can not find they are the same.

I hope someone could tell me in detail. Appreciate you!

And Code List here:

#define BLOB_NO_HOLE(hierarchy) ( (((hierarchy[2]==-1) && (hierarchy[3]==-1))?1:0) )
#define IS_TOPLEVEL(hierarchy) ( (((hierarchy[2]!=-1) && (hierarchy[3]==-1))?1:0) )
#define IS_CC(hierarchy) ( (hierarchy[3]==-1?0:1) )
#define ONLY_HOLE(hierarchy) ( (((hierarchy[0]==-1)  &&(hierarchy[1]==-1) && (hierarchy[2]==-1))?1:0) )

Mat HolesAreaTest( Mat _src)
    {
        CV_Assert(_src.type()==CV_8UC1);
        Mat dst;
        vector<vector<cv::Point>> contours;
        vector<Vec4i> hierarchy;
        Mat r[10];

        findContours(_src.clone(), contours,hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

        CvScalar color=cvScalar(255);
        dst=Mat::zeros(_src.size(),CV_8UC1);

        char* slen;
        char c[10];
        int idx = 0;

        cout <<" ===================A0======================= "<<endl;
        for( size_t i = 0; i< contours.size(); i++ )
        {   
            r[i]=Mat::zeros(_src.size(),CV_8UC1);

            drawContours(r[i], contours, (int)i, color, 0, 8, hierarchy, 0);

            cout << " Contour " << i << ":" << endl;
            cout << " next contour: " << hierarchy[i][0] << endl;
            cout << " previous contour: " << hierarchy[i][1] << endl;
            cout << " child contour: " << hierarchy[i][2] << endl;
            cout << " parent contour: " << hierarchy[i][3] << endl;
            cout << " size: " << contours[i].size() << endl;
            cout << " BLOB NO HOLE: " << BLOB_NO_HOLE(hierarchy[i]) << endl;
            cout << " HOLE:" << ONLY_HOLE(hierarchy[i])<<endl;
            cout << " Top-level: " << IS_TOPLEVEL(hierarchy[i]) << endl;
            cout << " CC: " << IS_CC(hierarchy[i]) << endl;
            sprintf(c,"%d",i);

            char* slen= strcat(c,"A1");
            imshow(slen,r[(int)i]);
            r[i]=Mat::zeros(_src.size(),CV_8UC1);
        }

        cout <<" ===================A1======================= "<<endl;
        for( int idx = 0; idx < contours.size(); idx++ )
        {
            if ONLY_HOLE(hierarchy[idx]) 
            {
                drawContours(r[idx], contours, (int)idx, color, CV_FILLED, 8, hierarchy, 0);
                double a=cv::contourArea(contours[idx]);
                cout<<" index:"<<idx<<endl;
                cout << " Hole size:" <<a<< endl;
                sprintf(c,"%d",idx);
                char* slen= strcat(c,"A2");
                imshow(slen,r[(int)idx]);
            }
        }

        cout <<" ==================A2======================== "<<endl;
        for(int idx = 0; idx < contours.size(); idx++)
        {
            r[idx]=Mat::zeros(_src.size(),CV_8UC1);
            c[idx]=NULL;
            if BLOB_NO_HOLE(hierarchy[idx]) 
            {
                cout << "Drawing BLOB NO HOLE index:" << idx <<endl;
                drawContours(r[idx], contours, (int)idx, color, CV_FILLED, 8, hierarchy, 0);
                double a=cv::contourArea(contours[idx]);
                cout << "Hole size: " <<a<< endl;
                sprintf(c,"%d",idx);
                char* slen= strcat(c,"A3 ...
(more)
edit retag flag offensive close merge delete

Comments

1

IS_TOPLEVEL(hierarchy) ( (((hierarchy[2]!=-1) && (hierarchy[3]==-1))?1:0) )

This is confusing, shouldn't it be IS_TOPLEVEL(hierarchy) ( ( (hierarchy[3]==-1)?1:0) )

No need to check v_next, since a top-level contour can have holes, right?

jonathan gravatar imagejonathan ( 2020-02-11 13:40:56 -0600 )edit