Python OpenCV轮廓树层次结构

时间:2012-08-02 16:48:18

标签: python opencv

我正在尝试使用OpenCV在python中实现找到here的算法。

我正在尝试实现算法的一部分,根据它们的内部边界数量去除不相关的边界。

  • 如果当前边缘边界恰好有一个或两个内边缘边界,则可以忽略内部边界
  • 如果当前边缘边界有两个以上的内边界,则可以忽略

我无法确定从图像中提取的轮廓的树形结构。

我目前的来源:

import cv2

# Load the image
img = cv2.imread('test.png')
cv2.copyMakeBorder(img, 50,50,50,50,cv2.BORDER_CONSTANT, img, (255,255,255))

# Split out each channel
blue = cv2.split(img)[0]
green = cv2.split(img)[1]
red = cv2.split(img)[2]

# Run canny edge detection on each channel
blue_edges = cv2.Canny(blue, 1, 255)
green_edges = cv2.Canny(green, 1, 255)
red_edges = cv2.Canny(red, 1, 255)

# Join edges back into image
edges = blue_edges | green_edges | red_edges

# Find the contours
contours,hierarchy = cv2.findContours(edges.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

# For each contour, find the bounding rectangle and draw it
for cnt in contours:
    x,y,w,h = cv2.boundingRect(cnt)
    cv2.rectangle(edges,(x,y),(x+w,y+h),(200,200,200),2)

# Finally show the image
cv2.imshow('img',edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

我假设使用RETR_TREE会给我一个漂亮的嵌套轮廓数组,但似乎并非如此。如何检索轮廓的树结构?

1 个答案:

答案 0 :(得分:11)

这里的主要困惑可能是返回的层次结构是一个numpy数组,其维数多于必要的维度。最重要的是,它看起来像Python FindContours函数返回一个元组列表的元组,以及层次结构的NDARRAY ......

通过采用层次结构[0],您可以获得更合理的层次结构信息,这些信息更符合C文档。然后,它将是一个合适的形状,例如,用轮廓拉链。

下面是一个示例,将在此图像上绘制绿色的最外面的矩形和红色的最里面的矩形:

enter image description here

输出:

enter image description here

请注意,顺便说一下,OpenCV文档中的措辞有点含糊不清,但是hierarchyDataOfAContour[2]描述了该轮廓的子项(如果它是负数,那么这是一个内部轮廓),{{1描述该轮廓的父项(如果它是负数,则表示外部轮廓)。

另请注意:我考虑实施您在OCR文件中提到的算法,我看到FindContours给了我很多重复几乎相同的轮廓。如本文所述,这将使“边缘盒”的发现变得复杂。这可能是因为Canny阈值太低(请注意我正如本文所描述的那样玩弄它们),但可能有某种方法可以减少这种影响,或者只看一下所有角落的平均偏差盒子并消除重复...

hierarchyDataOfAContour[3]