gpt4 book ai didi

Python OpenCV 轮廓树层次结构

转载 作者:太空狗 更新时间:2023-10-29 18:25:52 55 4
gpt4 key购买 nike

我正在尝试实现找到的算法 here在带有 OpenCV 的 Python 中。

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

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

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

我当前的来源:

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()

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

最佳答案

这里的主要混淆可能是返回的层次结构是一个 numpy 数组,其维度比必要的多。最重要的是,看起来 Python FindContours 函数返回一个元组,它是轮廓的 LIST 和层次结构的 NDARRAY ...

您只需采用 hierarchy[0] 即可获得更符合 C 文档的合理的层次结构信息数组。这将是一个合适的形状来压缩,例如,使用轮廓。

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

enter image description here

输出:

enter image description here

请注意,顺便说一下,OpenCV 文档中的措辞有点模棱两可,但是 hierarchyDataOfAContour[2] 描述了该轮廓的子级(如果它是负数,那么这是一个内部轮廓), 和 hierarchyDataOfAContour[3] 描述了该轮廓的父级(如果它是负数,那么这是一个外部轮廓)。

另请注意:我研究了您在 OCR 论文中提到的算法的实现,我发现 FindContours 为我提供了很多几乎相同的轮廓的重复。如论文所述,这会使“边缘框”的发现变得复杂。这可能是因为 Canny 阈值太低(请注意,我正在按照论文中的描述使用它们),但可能有一些方法可以减少这种影响,或者只看所有的四个角的平均偏差框并消除重复...

import cv2
import numpy

# Load the image
img = cv2.imread("/ContourTest.PNG")

# Split out each channel
blue, green, red = cv2.split(img)

def medianCanny(img, thresh1, thresh2):
median = numpy.median(img)
img = cv2.Canny(img, int(thresh1 * median), int(thresh2 * median))
return img

# Run canny edge detection on each channel
blue_edges = medianCanny(blue, 0.2, 0.3)
green_edges = medianCanny(green, 0.2, 0.3)
red_edges = medianCanny(red, 0.2, 0.3)

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

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

hierarchy = hierarchy[0] # get the actual inner list of hierarchy descriptions

# For each contour, find the bounding rectangle and draw it
for component in zip(contours, hierarchy):
currentContour = component[0]
currentHierarchy = component[1]
x,y,w,h = cv2.boundingRect(currentContour)
if currentHierarchy[2] < 0:
# these are the innermost child components
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),3)
elif currentHierarchy[3] < 0:
# these are the outermost parent components
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3)

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

关于Python OpenCV 轮廓树层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11782147/

55 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com