I want to extract all children of a contour, but I only got one.Here's the final result(the right pic):
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.