我正在尝试使用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会给我一个漂亮的嵌套轮廓数组,但似乎并非如此。如何检索轮廓的树结构?
答案 0 :(得分:11)
这里的主要困惑可能是返回的层次结构是一个numpy数组,其维数多于必要的维度。最重要的是,它看起来像Python FindContours函数返回一个元组列表的元组,以及层次结构的NDARRAY ......
通过采用层次结构[0],您可以获得更合理的层次结构信息,这些信息更符合C文档。然后,它将是一个合适的形状,例如,用轮廓拉链。
下面是一个示例,将在此图像上绘制绿色的最外面的矩形和红色的最里面的矩形:
输出:
请注意,顺便说一下,OpenCV文档中的措辞有点含糊不清,但是hierarchyDataOfAContour[2]
描述了该轮廓的子项(如果它是负数,那么这是一个内部轮廓),{{1描述该轮廓的父项(如果它是负数,则表示外部轮廓)。
另请注意:我考虑实施您在OCR文件中提到的算法,我看到FindContours给了我很多重复几乎相同的轮廓。如本文所述,这将使“边缘盒”的发现变得复杂。这可能是因为Canny阈值太低(请注意我正如本文所描述的那样玩弄它们),但可能有某种方法可以减少这种影响,或者只看一下所有角落的平均偏差盒子并消除重复...
hierarchyDataOfAContour[3]