我将向您展示如何找到嵌套的最内部轮廓。
我认为有比您的样本更复杂的结构,您必须对其进行分类。
-
我建议不要使用cv2.Canny,因为它会创建更多的层次结构。
看看使用cv2.imshow("edges", edges) 和cv2.waitKey()。
您可能只是反转极性以获得黑色背景上的白色三角形。
img = 255 - img
-
有一个小错误(循环内):
您正在使用:currentHierarchy = hierarchy[1]
而不是:currentHierarchy = component[1]
寻找嵌套轮廓:
-
从最内侧的轮廓开始。
最内部的轮廓是没有“第一个孩子”的轮廓。
检查是否currentHierarchy[2] < 0。
-
所有内部轮廓都将有一个父轮廓。
原因是每个三角形都应用了两个(嵌套的)轮廓:
我们需要得到父轮廓,并检查父轮廓是否有父轮廓。
具有祖父母的内部三角形是嵌套三角形。
这是完整的代码示例:
import numpy as np
import cv2
img = cv2.imread('triangles.png', cv2.IMREAD_GRAYSCALE) # Read input image as grayscale,
# edges = cv2.Canny(img, 50, 200)
# Invert polarity of img, instead of using Canny - we need the contours to be white.
img = 255 - img
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
hierarchy = hierarchy[0] # get the actual inner list of hierarchy descriptions
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) # Convert image to BGR, for using colored text.
for component in zip(contours, hierarchy):
currentContour = component[0]
#currentHierarchy = hierarchy[1] # Why ?
currentHierarchy = component[1]
approx = cv2.approxPolyDP(currentContour, 0.01 * cv2.arcLength(currentContour, True), True)
x = approx.ravel()[0]
y = approx.ravel()[1] - 5
# https://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html
# Hierarchy Representation in OpenCV
# Each contour has its own information regarding what hierarchy it is, who is its child, who is its parent etc.
# OpenCV represents it as an array of four values : [Next, Previous, First_Child, Parent]
#if (currentHierarchy[1] < 0) and len(approx) == 3:
if (currentHierarchy[2] < 0) and len(approx) == 3:
# These are the innermost child components
parent_idx = currentHierarchy[3] # Get the index of the parent contour
parent_hier = hierarchy[parent_idx] # Get the hierarchy of the parent.
if parent_hier[3] >= 0:
# Contour is nested only if the parent has a parent.
cv2.putText(img, "Nested", (x, y), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 0, 0), 2)
cv2.drawContours(img, [currentContour], -1, (0, 255, 0), 1)
cv2.waitKey(1000)
cv2.imshow("image", img)
cv2.waitKey()
cv2.destroyAllWindows()
结果: