【问题标题】:Detecting Nested Shape in opencv在opencv中检测嵌套形状
【发布时间】:2021-06-28 14:59:58
【问题描述】:

我需要在 opencv 中检测嵌套形状,但似乎即使使用层次结构我也可以做到


edges = cv2.Canny(img,50,200)
contours,hierarchy = cv2.findContours(edges, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

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


for comp in contours:

currentCont = comp[0]
currentHie = hierarchy[1]

x,y,w,h = cv2.boundingRect(currentContour)
  if ( currentHierarchy[1] < 0 ) 
    these are the innermost child components
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),3)
    cv2.putText(img, "nes", (x, y), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 0), 2)
    cv2.drawContours(img, [currentCont], -1, (0, 255, 0), 1)
    cv2.waitKey()
    cv2.imshow("image",img)

cv2.waitKey(0)
cv2.destroyAllWindows()

【问题讨论】:

  • 不太清楚你是如何进入“最里面的子组件”的。一旦你拥有了一个矩形的顶层层次结构,并且成功地测试了它,你就需要确定该矩形轮廓的子(前景)轮廓的子轮廓是否是三角形。一旦测试成功,您就会在一个矩形中嵌套一个三角形。

标签: python python-3.x opencv contour opencv-python


【解决方案1】:

我将向您展示如何找到嵌套的最内部轮廓。
我认为有比您的样本更复杂的结构,您必须对其进行分类。

  • 我建议不要使用cv2.Canny,因为它会创建更多的层次结构。
    看看使用cv2.imshow("edges", edges) 和cv2.waitKey()。
    您可能只是反转极性以获得黑色背景上的白色三角形。

     img = 255 - img
    
  • 有一个小错误(循环内):
    您正在使用:currentHierarchy = hierarchy[1]
    而不是:currentHierarchy = component[1]

寻找嵌套轮廓:

  • 从最内侧的轮廓开始。
    最内部的轮廓是没有“第一个孩子”的轮廓。
    检查是否currentHierarchy[2] &lt; 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()

结果:

【讨论】:

  • 此代码的问题在于,如果三角形位于圆形、正方形或矩形等其他形状内,它甚至会将三角形检测为嵌套三角形。我似乎无法找到解决此问题的方法。用例:如果三角形位于正方形、圆形或矩形等其他形状内,则不应将其检测为嵌套三角形。直到里面有两个三角形。以下是用于测试的图像:[i.stack.imgur.com/Q0Zhr.png](Image1) [i.stack.imgur.com/j0p78.png](Image2)
  • 从祖父母向上遍历轮廓,(从层次中获取父轮廓的索引)。当您拥有索引时,获取与索引匹配的轮廓:contours[index] 为您提供轮廓。检查轮廓是否为三角形len(approx) == 3...继续向上获取父母,直到值为-1。如果其中一个父项是三角形,则您有一个嵌套三角形。
猜你喜欢
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 2013-05-16
  • 2015-04-10
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
相关资源
最近更新 更多