Home > Software design >  I want to find all children of a contour in OpenCV C
I want to find all children of a contour in OpenCV C

Time:12-31

I want to extract all children of a contour, but I only got one.Here's the final result(the right pic):enter image description here

As you can see, I only got one (innerRect), but I expected to get all three of them. Here's the code:

 findContours(midImage2, contours2, hierarchy2, RETR_TREE, CHAIN_APPROX_SIMPLE);

        for (int i = 0; i < contours2.size(); i  ) {

            double areaSize = contourArea(contours2[i]);
            int rect_count;

            Point2f innerRectcornerPoints[4], largeRectCornerPoints[4];
            RotatedRect innerRect, largeRect;

            if (areaSize > 3000) {

                largeRect = minAreaRect(contours2[i]);
                largeRect.points(largeRectCornerPoints);

                for (int j = 0; j < 4; j  ) {
                    line(frame, largeRectCornerPoints[j], largeRectCornerPoints[(j   1) % 4], Scalar(255, 255, 0), 3, 8);
                }
                putText(frame, "largeRect", largeRectCornerPoints[1], 2, 1,  Scalar(255, 255, 0));

                for (int j = 0; j <= i; j  ) {
                    if (hierarchy2[j][2] != -1) {
                        innerRect = minAreaRect(contours2[hierarchy2[i][2]]);
                        innerRect.points(innerRectcornerPoints);
                        rect_count  ;
                    }
                }

                //if (rect_count < 4) {
                    for (int j = 0; j < 4; j  ) {
                        line(frame, innerRectcornerPoints[j], innerRectcornerPoints[(j   1) % 4], Scalar(0, 255, 255), 3, 8);
                    }
                    putText(frame, "innerRect", innerRectcornerPoints[2], 2, 1, Scalar(0, 255, 255));
                //}
            }

        }

I've been stuck there for almost a day, hope you can help me out.

CodePudding user response:

From the openCV documentation:

hierarchy : Optional output vector (e.g. std::vector<cv::Vec4i>), 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] , hierarchy[i][1] , hierarchy[i][2] , and hierarchy[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.

https://docs.opencv.org/3.4/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a

Nesting for-loops are not the best way to resolve this, use the linking provided by the hierachy instead (pseudocode):

node_toplevel = hierarchy[0]
while (node_toplevel != null)
{
  // draw node_toplevel 
  ...

  if(node[2]) > 0) // there is a child, loop over those
    {
      node_child = hierarchy[node_toplevel[2]]
      while (node_toplevel != null)
      {
        // draw node_child 
        ...

        if(node_child[0] > 0)
          node_child = hierarchy[node_child[0]]
        else
          node_child  = null
      }
    }
  else // no children, next node_toplevel
  {
    if(node_toplevel[0] > 0)
      node_toplevel = hierarchy[node_toplevel[0]]
    else
      node_toplevel = null
  }
}

Note: There are certainly less verbose and probably more performant ways to do this. It's just walking over a linked list, this could be done using recursion for example. I chose this form to make the idea as clear as possible.

  • Related