We have multiple contours. Some are positive and some are negative (holes). Here is the code i'm using
def get_corners(grid: np.ndarray, show=False):
corners = set()
hole_corners = set()
# Filter using contour hierarchy
cnts, hierarchy = cv.findContours(grid, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)[-2:]
hierarchy = hierarchy[0]
for component in zip(cnts, hierarchy):
currentContour = component[0]
currentHierarchy = component[1]
# x,y,w,h = cv.boundingRect(currentContour)
# Has hole which means it is IN
if currentHierarchy[2] < 0:
for corner in currentContour[:, 0, :]:
corner_coords = tuple(corner.tolist())
hole_corners.add(corner_coords)
# cv.putText(image, 'IN', (x,y-10), cv.FONT_HERSHEY_SIMPLEX, 0.7, (36,255,12), 2)
# No child which means it is OUT
elif currentHierarchy[3] < 0:
for corner in currentContour[:, 0, :]:
corner_coords = tuple(corner.tolist())
corners.add(corner_coords)
the problem with it is that, when there is more than one positive contour, it doesn't work as expected. every positive contour > 1 gets counted as a hole. here is it displayed.
As you can see its not working as expected.
all counted as holes
one counted correctly, rest mostly incorrectly
image with contours labelled correctly (ignore corner color here)
Another failure case with islands with no child being counted as holes
hierarchy for this: [[ 1 -1 -1 -1]
[ 3 0 2 -1]
[-1 -1 -1 1]
[-1 1 -1 -1]]
Figured it out. using RETR_CCOMP and checking for currentHierarchy[3] worked for me. Corners is a set with all corners of the outer contours, hole_corners is a set with all corners of the inner, or hole contours.
(cnts, hierarchy) = cv.findContours(grid,mode=cv.RETR_CCOMP, method=cv.CHAIN_APPROX_TC89_KCOS)
corners = set()
hole_corners = set()
# Filter using contour hierarchy
hierarchy = hierarchy[0]
for component in zip(cnts, hierarchy):
currentContour = component[0]
currentHierarchy = component[1]
# Has inner contours which means it is IN
if currentHierarchy[3] < 0:
for corner in currentContour[:, 0, :]:
corner_coords = tuple(corner.tolist())
corners.add(corner_coords)
# No child which means it is OUT
elif currentHierarchy[3] >= 0:
for corner in currentContour[:, 0, :]:
corner_coords = tuple(corner.tolist())
hole_corners.add(corner_coords)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.