Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recognize open and closed shapes opencv

Tags:

how to detect open and closed shapes in opencv.

enter image description here

These are simple sample shapes I want to detect. I have detected rectangle using findContours and approxPolyDP and than checking for angle between vectors.

Now I want to detect the open shape, approxPolyDP function has bool for closed shape set to true, and also there is a check for isCounterConvex on the points returned, plus contourArea limitation.

Any ideas how should I go on detecting images of these kind.

like image 314
Fahad Malik Avatar asked Mar 07 '14 03:03

Fahad Malik


People also ask

How do you know if contour is closed on OpenCV?

Just use findContours() in your image, then decide whether the contour is closed or not by examining the hierarchy passed to the findContours() function.

How do you identify an OpenCV triangle?

We can find shapes present in an image using the findContours() and approxPolyDP() function of OpenCV. We can detect shapes depending on the number of corners it has. For example, a triangle has 3 corners, a square has 4 corners, and a pentagon has 5 corners.

What function is used to detect polygons OpenCV?

Contours – convex contours and the Douglas-Peucker algorithm The first facility OpenCV offers to calculate the approximate bounding polygon of a shape is cv2. approxPolyDP. This function takes three parameters: A contour.

How do you know if a rectangle is OpenCV?

Use the findContours() and contourArea() Function of OpenCV to Detect Rectangles in Images in Python. We can detect a rectangle present in an image using the findContours() function of OpenCV, and we can use the contourArea() function to sort different rectangles according to their area.


2 Answers

Just use findContours() in your image, then decide whether the contour is closed or not by examining the hierarchy passed to the findContours() function. From the second figure it is clearer that no contour has child contour as compared to the first image, you will get this data from hierarchy parameter which is optional output vector, containing information about the image topology. It has as many elements as the number of contours.

Here we will use hierarchy as

vector< Vec4i > hierarchy 

where for an i-th contour

hierarchy[i][0] = next contour at the same hierarchical level hierarchy[i][1] = previous contour at the same hierarchical level hierarchy[i][2] = denotes its first child contour hierarchy[i][3] = denotes index of its parent contour 

If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative. See findContours() function for more details.

So by checking the value hierarchy[i][2] you can decide the contour belongs to closed or not, that is for a contour if the hierarchy[i][2] = -1 then no child and it belongs to opened.

And one more thing is that in findContours() function you should use CV_RETR_CCOMP which retrieves all of the contours and organizes them into a two-level hierarchy.

Here is the C++ code how to implement this.

    Mat tmp,thr;     Mat src=imread("1.png",1);     cvtColor(src,tmp,CV_BGR2GRAY);     threshold(tmp,thr,200,255,THRESH_BINARY_INV);      vector< vector <Point> > contours; // Vector for storing contour     vector< Vec4i > hierarchy;     findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );      for( int i = 0; i< contours.size(); i=hierarchy[i][0] ) // iterate through each contour.     {         Rect r= boundingRect(contours[i]);         if(hierarchy[i][2]<0) //Check if there is a child contour           rectangle(src,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10), Scalar(0,0,255),2,8,0); //Opened contour         else           rectangle(src,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10), Scalar(0,255,0),2,8,0); //closed contour     } 

Result:

enter image description here

like image 68
Haris Avatar answered Nov 02 '22 10:11

Haris


While correct for the problem posed, @Haris helpful answer should not be taken as a general solution for identifying closed contours using findContours().

One reason is that a filled object will have no internal contour and so would return hierarchy[i][2] = -1, meaning this test on its own would wrongly label such contours as 'open'.

The contour of a filled object should have no child or parent in the contour hierarchy, i.e. be at top level. So to detect for closed contours of filled objects would at least require an additional test: if(hierarchy[i][2] < 0 && hierarchy[i][3] < 0).

I think @Haris answer may have made this point obliquely but I thought it worth clarifying for people, like myself, who are learning how to use opencv.

like image 35
fink-nottle Avatar answered Nov 02 '22 09:11

fink-nottle